Skip to content

Commit

Permalink
UI|Client|Home: Added a background for the game filter area
Browse files Browse the repository at this point in the history
The sort order and filter tabs conflict with the menu contents when
the menu is scrolled up. Now there's a white blurred background
that appears behind the top part of the view when the menu is
scrolled.
  • Loading branch information
skyjake committed Nov 30, 2014
1 parent 442812d commit 13af965
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 5 deletions.
12 changes: 12 additions & 0 deletions doomsday/client/include/ui/widgets/gamefilterwidget.h
Expand Up @@ -61,9 +61,21 @@ class GameFilterWidget : public de::GuiWidget, public de::IPersistent
void useInvertedStyle();
void setFilter(Filter flt, FilterMode mode = UserChangeable);

/**
* Enables a background for the filter. Opacity of the background is controlled
* by the provided scroll position rule, so that the background is visible only
* when the scroll position is greater than zero.
*
* @param scrollPositionRule Rule.
*/
void enableBackground(de::Rule const &scrollPositionRule);

Filter filter() const;
SortOrder sortOrder() const;

// Events.
void update();

// Implements IPersistent.
void operator >> (de::PersistentState &toState) const;
void operator << (de::PersistentState const &fromState);
Expand Down
1 change: 1 addition & 0 deletions doomsday/client/src/ui/clientwindow.cpp
Expand Up @@ -236,6 +236,7 @@ DENG2_PIMPL(ClientWindow)
.setInput(Rule::Width, gameSelMenu->rule().width() - gameSelMenu->margins().width())
.setInput(Rule::Top, root.viewTop() + style.rules().rule("gap"));
container().add(gameSelMenu);
gameSelMenu->filter().enableBackground(gameSelMenu->scrollPositionY());

// Common notification area.
notifications = new NotificationAreaWidget;
Expand Down
74 changes: 69 additions & 5 deletions doomsday/client/src/ui/widgets/gamefilterwidget.cpp
Expand Up @@ -27,20 +27,34 @@

using namespace de;

DENG2_PIMPL(GameFilterWidget)
static TimeDelta const BACKGROUND_FADE_SPAN = 0.25;
static float const BACKGROUND_FILL_OPACITY = 0.8f;

DENG_GUI_PIMPL(GameFilterWidget)
{
LabelWidget *background = nullptr;
Rule const *bgOpacityRule = nullptr;
Animation bgOpacity { 0, Animation::Linear };
bool animatingOpacity = false;

TabWidget *tabs;
LabelWidget *sortLabel;
ChoiceWidget *sortBy;
DialogContentStylist stylist;
FilterMode filterMode;
FilterMode filterMode = UserChangeable;

Instance(Public *i)
: Base(i)
, filterMode(UserChangeable)
Instance(Public *i) : Base(i)
{
stylist.setContainer(self);

// Optional background.
self.add(background = new LabelWidget);
background->set(Background(Vector4f(style().colors().colorf("text"), 0),
Background::BlurredWithSolidFill));
background->setOpacity(0);
background->setAttribute(IndependentOpacity);
background->hide(); // hidden by default

// Create widgets.
self.add(tabs = new TabWidget);
sortLabel = LabelWidget::newWithText(tr("Sort By:"), &self);
Expand Down Expand Up @@ -68,10 +82,35 @@ DENG2_PIMPL(GameFilterWidget)
.setInput(Rule::Top, self.rule().top());
}

~Instance()
{
releaseRef(bgOpacityRule);
}

String persistId(String const &name) const
{
return self.name() + "." + name;
}

void updateBackgroundOpacity()
{
float opacity = (bgOpacityRule->value() > 1? 1 : 0);
if(!fequal(bgOpacity.target(), opacity))
{
bgOpacity.setValue(opacity, BACKGROUND_FADE_SPAN);
background->setOpacity(opacity, BACKGROUND_FADE_SPAN);
animatingOpacity = true;
}

if(animatingOpacity)
{
Background bg = background->background();
bg.solidFill.w = bgOpacity * BACKGROUND_FILL_OPACITY;
background->set(bg);

if(bgOpacity.done()) animatingOpacity = false;
}
}
};

GameFilterWidget::GameFilterWidget(String const &name)
Expand Down Expand Up @@ -105,6 +144,21 @@ void GameFilterWidget::setFilter(Filter flt, FilterMode mode)
}
}

void GameFilterWidget::enableBackground(Rule const &scrollPositionRule)
{
DENG2_ASSERT(hasRoot());

d->bgOpacityRule = holdRef(scrollPositionRule);

d->background->rule()
.setInput(Rule::Left, root().viewLeft())
.setInput(Rule::Right, root().viewRight())
.setInput(Rule::Top, d->tabs->rule().top() - style().rules().rule("gap"))
.setInput(Rule::Bottom, d->tabs->rule().bottom() + style().rules().rule("gap"));

d->background->show();
}

GameFilterWidget::Filter GameFilterWidget::filter() const
{
return Filter(d->tabs->currentItem().data().toUInt());
Expand All @@ -115,6 +169,16 @@ GameFilterWidget::SortOrder GameFilterWidget::sortOrder() const
return SortOrder(d->sortBy->selectedItem().data().toInt());
}

void GameFilterWidget::update()
{
GuiWidget::update();

if(d->background->isVisible())
{
d->updateBackgroundOpacity();
}
}

void GameFilterWidget::operator >> (PersistentState &toState) const
{
Record &st = toState.names();
Expand Down

0 comments on commit 13af965

Please sign in to comment.