Project

General

Profile

Bug #11345 » test_WStackedWidget_animation_overflow_20230222a.C

Bruce Toll, 02/23/2023 03:20 AM

 
#include <array>
#include <Wt/WApplication.h>
#include <Wt/WAnimation.h>
#include <Wt/WButtonGroup.h>
#include <Wt/WColor.h>
#include <Wt/WComboBox.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WCssDecorationStyle.h>
#include <Wt/WEnvironment.h>
#include <Wt/WFitLayout.h>
#include <Wt/WRadioButton.h>
#include <Wt/WServer.h>
#include <Wt/WStackedWidget.h>
#include <Wt/WText.h>

using namespace Wt;

class TestApp : public WApplication {

public:
TestApp(const WEnvironment& env) : WApplication(env)
{
setTitle("Test WStackedWidget in layout with animation");

constexpr static std::array animations {
std::make_tuple("No Animation", static_cast<AnimationEffect>(0)),
std::make_tuple("SlideInFromLeft", AnimationEffect::SlideInFromLeft),
std::make_tuple("SlideInFromRight", AnimationEffect::SlideInFromRight),
std::make_tuple("SlideInFromBottom", AnimationEffect::SlideInFromBottom),
std::make_tuple("SlideInFromTop", AnimationEffect::SlideInFromTop),
std::make_tuple("Fade", AnimationEffect::Fade)
};

stackedWidgets_.push_back(addStackedWidgetBare(WLength::Auto, WLength::Auto, root()));
stackedWidgets_.push_back(addStackedWidgetBare(WLength(350), WLength(200), root()));
stackedWidgets_.push_back(addStackedWidgetLayout(WLength(350), WLength(200), LayoutImplementation::Flex, root()));
stackedWidgets_.push_back(addStackedWidgetLayout(WLength(350), WLength(200), LayoutImplementation::JavaScript, root()));

auto animationCB = root()->addNew<WComboBox>();
for (auto x: animations) {
animationCB->addItem(std::get<0>(x));
}

animationCB->activated().connect([this] (int index) {
auto animation_effect = std::get<1>(animations[index]);
auto anim { WAnimation(animation_effect, TimingFunction::Linear, 1000) };
for (auto sw: stackedWidgets_)
sw->setTransitionAnimation(anim, true);
});

animationCB->activated().emit(animationCB->currentIndex());

addLayerButtons(root());
}

private:
void addStackedWidgetLayers(WLength width, WLength height, WStackedWidget* sw)
{
constexpr static std::array test {
std::make_tuple("No scrollbars", Overflow::Hidden, Overflow::Hidden),
std::make_tuple("Vertical scrollbar", Overflow::Hidden, Overflow::Scroll),
std::make_tuple("Horizontal scrollbar", Overflow::Scroll, Overflow::Hidden),
std::make_tuple("Both scrollbars", Overflow::Scroll, Overflow::Scroll)
};

std::string longString = "<ol>";
for (int i=1; i <= 10; ++i)
longString += "<li>test_test_test_test_test_test_test_test_test_test_test_test</li>";
longString += "</ol>";

auto grayBackground = WCssDecorationStyle();
grayBackground.setBackgroundColor(StandardColor::LightGray);
for (auto t: test) {
auto container = std::make_unique<WContainerWidget>();
container->addNew<WText>("<h1>" + std::string(std::get<0>(t)) + "</h1>" + longString);
container->setOverflow(std::get<1>(t), Orientation::Horizontal);
container->setOverflow(std::get<2>(t), Orientation::Vertical);
container->resize(width, height);

// container needs a background for SlideInFromTop and SlideInFromBottom to hide lower layer during transition....
container->setDecorationStyle(grayBackground);
sw->addWidget(std::move(container));
sw->setDecorationStyle(grayBackground);
}
}

WStackedWidget* addStackedWidgetBare(WLength width, WLength height, WContainerWidget* parent)
{
auto stackedWidget = std::make_unique<WStackedWidget>();
auto sw = stackedWidget.get();
sw->resize(width, height);

addStackedWidgetLayers(width, height, sw);

parent->addNew<WText>("Bare Implementation: width: " + width.cssText() + ", height: " + height.cssText());
parent->addWidget(std::move(stackedWidget));

return sw;
}

WStackedWidget* addStackedWidgetLayout(WLength width, WLength height, LayoutImplementation layout_impl, WContainerWidget* parent)
{
auto stackedWidget = std::make_unique<WStackedWidget>();
auto sw = stackedWidget.get();

auto smallLayout = std::make_unique<WFitLayout>();
smallLayout->setContentsMargins(0, 0, 0, 0);
smallLayout->setPreferredImplementation(layout_impl);
smallLayout->addWidget(std::move(stackedWidget));

auto smallContainer = std::make_unique<WContainerWidget>();
smallContainer->resize(width, height);
smallContainer->setLayout(std::move(smallLayout));

addStackedWidgetLayers(WLength::Auto, WLength::Auto, sw);

parent->addNew<WText>(layout_impl == LayoutImplementation::Flex ? "Flex Implementation" : "JavaScript Implementation");
parent->addWidget(std::move(smallContainer));

return sw;
}

void addLayerButtons(WContainerWidget* parent)
{
// assume same number of layers in all stackedWidgets_
for (int i = 0; i < stackedWidgets_[0]->count(); ++i) {
auto button = parent->addNew<WRadioButton>(std::to_string(i));
indexGroup_->addButton(button, i);
}
indexGroup_->setCheckedButton(indexGroup_->button(stackedWidgets_[0]->currentIndex()));
indexGroup_->checkedChanged().connect([=] {
auto index = indexGroup_->checkedId();
for (auto sw: stackedWidgets_)
sw->setCurrentIndex(index);
});
}

std::vector<WStackedWidget *> stackedWidgets_;
std::shared_ptr<WButtonGroup> indexGroup_ = std::make_shared<WButtonGroup>();
};


int main(int argc, char **argv)
{
return WRun(argc, argv, [](const WEnvironment& env) {return std::make_unique<TestApp>(env);});
}
(4-4/5)