Project

General

Profile

Bug #2645 » test_WStackedWidget_animation_stutter.C

Bruce Toll, 02/07/2014 05:38 PM

 
#include <Wt/WServer>
#include <Wt/WStackedWidget>
#include <Wt/WAnimation>
#include <Wt/WTimer>
#include <Wt/WText>
#include <Wt/WBreak>
#include <Wt/WTable>
#include <Wt/WPushButton>
#include <Wt/WBootstrapTheme>

using namespace Wt;

class TestApplication : public WApplication
{
public:
TestApplication(const WEnvironment& env);

private:
void step();
void start_stepping(int anim_time);
WColor col_color(int col);

static constexpr int Cell_Width {16};
static constexpr int Cell_Height {16};
static constexpr int Table_Cols {48};
static constexpr int Table_Rows {20};
static constexpr int Table_Width {Table_Cols * Cell_Width};
static constexpr int Table_Height {Table_Rows * Cell_Height};
static constexpr int Column_Group {6};
static constexpr int Step_Time {2000};
static const int Animation_Time[];

WBootstrapTheme bs_theme_;
WStackedWidget* sw_ {nullptr};
WTimer timer_;
int anim_time_ { Animation_Time[0] };
int cnt_ {0};
WText* status_ {nullptr};
};

const int TestApplication::Animation_Time[] {50, 1000, 3000};

TestApplication::TestApplication(const WEnvironment& env) : WApplication(env)
{
setTitle("Stuttering WStackedWidget Animations");
setTheme(&bs_theme_);

WContainerWidget *w = new WContainerWidget(root());
new WText("<b>NOTES:</b><br/>"
"Look for stuttering transitions at 1000ms, particularly with FireFox...<br/>"
"Content stops being displayed when animation time exceeds step time, at 3000ms.<br/><br/>", w);

for (auto anim_time: Animation_Time) {
auto pb = new WPushButton((boost::lexical_cast<std::string>(anim_time) + " ms."), w);
pb->clicked().connect(std::bind(&TestApplication::start_stepping, this, anim_time));
}

new WBreak(w);

status_ = new WText(w);

new WBreak(w);

sw_ = new WStackedWidget(w);
sw_->setMargin(30, Top);
sw_->resize(Table_Width, Table_Height);

for (int i = 0; i < 2; ++i) {
auto t0 = new WTable();
t0->resize(Table_Width, Table_Height);
for (int r = 0; r < Table_Rows; ++r) {
for (int c = 0; c < Table_Cols; ++c) {
auto w0 = t0->elementAt(r, c);
w0->resize(Cell_Width, Cell_Height);
}
}
sw_->addWidget(t0);
}

timer_.timeout().connect(this, &TestApplication::step);
timer_.setInterval(Step_Time);
timer_.start();
start_stepping(Animation_Time[0]);
}

void TestApplication::start_stepping(int anim_time)
{
anim_time_ = anim_time;
static const int step_time {Step_Time};
status_->setText("Step Time: " + boost::lexical_cast<std::string>(step_time) +
"ms, <b>Animation Time: " + boost::lexical_cast<std::string>(anim_time) + "ms</b>");
}

void TestApplication::step() {
int next_index = 1 - sw_->currentIndex();

auto t = dynamic_cast<WTable*>(sw_->widget(next_index));

for (int r = 0; r < Table_Rows; ++r) {
for (int c = 0; c < Table_Cols; ++c) {
t->elementAt(r, c)->decorationStyle().setBackgroundColor(col_color(c));
}
}

sw_->setTransitionAnimation(WAnimation(WAnimation::Fade, WAnimation::Linear, anim_time_));
sw_->setCurrentIndex(next_index);
++cnt_;
}

WColor TestApplication::col_color(int col) {
// sequence active columns through colors: red, blue, green (at 50% alpha)
if ((col % Column_Group) == (cnt_ % Column_Group))
return WColor(!(col % 3) * 256, !((col + 1) % 3) * 256, !((col + 2) % 3) * 256,128);
else
return WColor(white);
}

int main(int argc, char **argv)
{
return WRun(argc, argv, [](const WEnvironment& env) {return new TestApplication(env);});
}
(1-1/2)