Skip to content

Commit

Permalink
Widgets|UI|libappfw: Colored popup outlines
Browse files Browse the repository at this point in the history
Contextual dialogs and popup menus now have colored outlines and
a dark appearance.
  • Loading branch information
skyjake committed Jun 26, 2017
1 parent a05130e commit 56d3745
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 20 deletions.
Expand Up @@ -40,6 +40,7 @@ focus {
}

popup {
color outline { rgb <1.0, 1.0, 1.0, 0.5> }
info {
color background { rgb <0.933, 0.933, 0.933> }
color glow { rgb $= inverted.glow.rgb }
Expand Down
21 changes: 16 additions & 5 deletions doomsday/apps/client/src/ui/dialogs/packageinfodialog.cpp
Expand Up @@ -38,6 +38,7 @@
#include <de/NativeFile>
#include <de/PackageLoader>
#include <de/PopupMenuWidget>
#include <de/ProgressWidget>
#include <de/SequentialLayout>
#include <de/SignalAction>

Expand Down Expand Up @@ -70,7 +71,7 @@ DENG_GUI_PIMPL(PackageInfoDialog)
descriptionWidth = new IndirectRule;
minContentHeight = new IndirectRule;

self().useInfoStyle();
//self().useInfoStyle();

// The Close button is always available. Other actions are shown depending
// on what kind of package is being displayed.
Expand All @@ -95,20 +96,30 @@ DENG_GUI_PIMPL(PackageInfoDialog)
title = LabelWidget::newWithText("", &area);
title->setFont("title");
title->setSizePolicy(ui::Filled, ui::Expand);
title->setTextColor("inverted.accent");
title->setTextColor("accent");
title->setTextLineAlignment(ui::AlignLeft);
title->margins().setBottom("");

path = LabelWidget::newWithText("", &area);
path->setSizePolicy(ui::Filled, ui::Expand);
path->setTextColor("inverted.text");
path->setTextColor("text");
path->setTextLineAlignment(ui::AlignLeft);
path->margins().setTop("unit");

AutoRef<Rule> contentHeight(OperatorRule::maximum(*minContentHeight, *targetHeight));

description = new DocumentWidget;
description->setFont("small");

// Light-on-dark document.
description->setStyleColor(Font::RichFormat::NormalColor, "label.dimmed");
description->setStyleColor(Font::RichFormat::HighlightColor, "label.highlight");
description->setStyleColor(Font::RichFormat::DimmedColor, "label.dimmed");
description->setStyleColor(Font::RichFormat::AccentColor, "label.accent");
description->setStyleColor(Font::RichFormat::DimAccentColor, "label.dimaccent");
description->progress().setColor ("progress.light.wheel");
description->progress().setShadowColor("progress.light.shadow");

description->setWidthPolicy(ui::Fixed);
description->rule().setInput(Rule::Height, contentHeight - title->rule().height()
- path->rule().height());
Expand All @@ -134,7 +145,7 @@ DENG_GUI_PIMPL(PackageInfoDialog)
metaInfo->setSizePolicy(ui::Filled, ui::Expand);
metaInfo->setTextLineAlignment(ui::AlignLeft);
metaInfo->setFont("small");
metaInfo->setTextColor("inverted.altaccent");
metaInfo->setTextColor("altaccent");

SequentialLayout rightLayout(title->rule().right(), title->rule().top(), ui::Down);
rightLayout.setOverrideWidth(rule("dialog.packageinfo.metadata.width"));
Expand Down Expand Up @@ -181,7 +192,7 @@ DENG_GUI_PIMPL(PackageInfoDialog)
void useDefaultIcon()
{
icon->setStyleImage("package.large");
icon->setImageColor(style().colors().colorf("inverted.altaccent"));
icon->setImageColor(style().colors().colorf("altaccent"));
icon->setImageFit(ui::FitToSize | ui::OriginalAspectRatio);
//icon->setImageScale(.75f);
icon->setOpacity(.5f);
Expand Down
1 change: 1 addition & 0 deletions doomsday/apps/client/src/ui/widgets/consolewidget.cpp
Expand Up @@ -280,6 +280,7 @@ DENG_GUI_PIMPL(ConsoleWidget)
static PopupWidget *consoleShortcutPopup()
{
auto *pop = new PopupWidget;
pop->setOutlineColor("popup.outline");
// The 'padding' widget will provide empty margins around the content.
// Popups normally do not provide any margins.
auto *padding = new GuiWidget;
Expand Down
Expand Up @@ -343,6 +343,7 @@ PopupWidget *PackageContentOptionsWidget::makePopup(String const &packageId,
Rule const &maxHeight)
{
PopupWidget *pop = new PopupWidget;
pop->setOutlineColor("popup.outline");
pop->setDeleteAfterDismissed(true);
//pop->setAnchorAndOpeningDirection(rule(), ui::Left);
/*pop->closeButton().setActionFn([this] ()
Expand Down
7 changes: 7 additions & 0 deletions doomsday/sdk/libappfw/include/de/widgets/popupwidget.h
Expand Up @@ -103,6 +103,13 @@ class LIBAPPFW_PUBLIC PopupWidget : public PanelWidget

ColorTheme colorTheme() const;

/**
* Sets the color of the popup outline. By default, popups do not have an outline.
*
* @param outlineColor Outline color.
*/
void setOutlineColor(DotPath const &outlineColor);

void setCloseButtonVisible(bool enable);

/**
Expand Down
1 change: 1 addition & 0 deletions doomsday/sdk/libappfw/src/widgets/dialogwidget.cpp
Expand Up @@ -465,6 +465,7 @@ DialogWidget::DialogWidget(String const &name, Flags const &flags)
{
d->stylist.setContainer(area());
setOpeningDirection(ui::NoDirection);
setOutlineColor("accent");
d->updateBackground();
}

Expand Down
1 change: 1 addition & 0 deletions doomsday/sdk/libappfw/src/widgets/gridpopupwidget.cpp
Expand Up @@ -33,6 +33,7 @@ GridPopupWidget::GridPopupWidget(String const &name)
: PopupWidget(name), d(new Impl)
{
setOpeningDirection(ui::Up);
setOutlineColor("accent");

d->container = new GuiWidget;
setContent(d->container);
Expand Down
12 changes: 8 additions & 4 deletions doomsday/sdk/libappfw/src/widgets/popupmenuwidget.cpp
Expand Up @@ -223,6 +223,7 @@ DENG_GUI_PIMPL(PopupMenuWidget)
void updateItemHitRules()
{
GridLayout const &layout = self().menu().layout();
AutoRef<Rule const> halfUnit = self().rule("halfunit");

foreach (GuiWidget *widget, self().menu().childWidgets())
{
Expand All @@ -234,10 +235,12 @@ DENG_GUI_PIMPL(PopupMenuWidget)
// We want items to be hittable throughout the width of the menu, however
// restrict this to the item's column if there are multiple columns.
widget->hitRule()
.setInput(Rule::Left, (!cell.x? self().rule().left() :
layout.columnLeft(cell.x)))
.setInput(Rule::Right, (cell.x == layout.gridSize().x - 1? self().rule().right() :
layout.columnRight(cell.x)));
.setInput(Rule::Left, (!cell.x?
self().rule().left()
: layout.columnLeft(cell.x)) + halfUnit)
.setInput(Rule::Right, ((cell.x == layout.gridSize().x - 1)?
self().rule().right()
: layout.columnRight(cell.x)) - halfUnit);
}
}
}
Expand Down Expand Up @@ -414,6 +417,7 @@ PopupMenuWidget::PopupMenuWidget(String const &name)
: PopupWidget(name), d(new Impl(this))
{
setContent(new MenuWidget(name.isEmpty()? "" : name + "-content"));
setOutlineColor("popup.outline");

menu().setGridSize(1, ui::Expand, 0, ui::Expand);

Expand Down
127 changes: 116 additions & 11 deletions doomsday/sdk/libappfw/src/widgets/popupwidget.cpp
Expand Up @@ -33,11 +33,13 @@ namespace de {

DENG_GUI_PIMPL(PopupWidget)
{
bool flexibleDir = true;
ColorTheme colorTheme = Normal;
bool flexibleDir = true;
bool deleteAfterDismiss = false;
bool clickToClose = true;
bool outsideClickOngoing = false;
DotPath outlineColorId;
ColorBank::Colorf outlineColor;
SafeWidgetPtr<Widget> realParent;
RuleRectangle anchor;
Rule const *marker;
Expand Down Expand Up @@ -194,6 +196,8 @@ DENG_GUI_PIMPL(PopupWidget)
Style const &st = style();
bool const opaqueBackground = (self().levelOfNesting() > 0);

outlineColor = st.colors().colorf(outlineColorId);

if (colorTheme == Inverted)
{
self().set(self().infoStyleBackground());
Expand Down Expand Up @@ -329,6 +333,12 @@ GuiWidget::ColorTheme PopupWidget::colorTheme() const
return d->colorTheme;
}

void PopupWidget::setOutlineColor(const DotPath &outlineColor)
{
d->outlineColorId = outlineColor;
d->updateStyle();
}

void PopupWidget::setCloseButtonVisible(bool enable)
{
if (enable && !d->close)
Expand Down Expand Up @@ -431,17 +441,22 @@ void PopupWidget::glMakeGeometry(GuiVertexBuilder &verts)
v.rgba = background().solidFill;
v.texCoord = root().atlas().imageRectf(root().solidWhitePixel()).middle();

int marker = d->marker->valuei();
int const marker = d->marker->valuei();
Vector2i anchorPos = d->anchorPos();
bool markerVisible = false;

if (dir == ui::Up)
{
// Can't put the anchor too close to the edges.
anchorPos.x = clamp(2 * marker, anchorPos.x, int(root().viewSize().x) - 2*marker);

v.pos = anchorPos; tri << v;
v.pos = anchorPos + Vector2i(-marker, -marker); tri << v;
v.pos = anchorPos + Vector2i(marker, -marker); tri << v;
if (anchorPos.y > rule().bottom().valuei())
{
v.pos = anchorPos; tri << v;
v.pos = anchorPos + Vector2i(-marker, -marker); tri << v;
v.pos = anchorPos + Vector2i(marker, -marker); tri << v;
markerVisible = true;
}
}
else if (dir == ui::Left)
{
Expand All @@ -451,19 +466,109 @@ void PopupWidget::glMakeGeometry(GuiVertexBuilder &verts)
v.pos = anchorPos; tri << v;
v.pos = anchorPos + Vector2i(-marker, marker); tri << v;
v.pos = anchorPos + Vector2i(-marker, -marker); tri << v;
markerVisible = true;
}
}
else if (dir == ui::Right)
{
v.pos = anchorPos; tri << v;
v.pos = anchorPos + Vector2i(marker, -marker); tri << v;
v.pos = anchorPos + Vector2i(marker, marker); tri << v;
if (anchorPos.x < rule().left().valuei())
{
v.pos = anchorPos; tri << v;
v.pos = anchorPos + Vector2i(marker, -marker); tri << v;
v.pos = anchorPos + Vector2i(marker, marker); tri << v;
markerVisible = true;
}
}
else
{
v.pos = anchorPos; tri << v;
v.pos = anchorPos + Vector2i(marker, marker); tri << v;
v.pos = anchorPos + Vector2i(-marker, marker); tri << v;
if (anchorPos.y < rule().top().valuei())
{
v.pos = anchorPos; tri << v;
v.pos = anchorPos + Vector2i(marker, marker); tri << v;
v.pos = anchorPos + Vector2i(-marker, marker); tri << v;
markerVisible = true;
}
}

// Outline.
if (d->outlineColor.w > 0.f)
{
tri << v; // discontinued

Rectanglei const rect = rule().recti();
int const ow = GuiWidget::toDevicePixels(1);
int const halfOw = ow/2;
int const midOw = ow + halfOw;

v.rgba = d->outlineColor;

// Top edge.
v.pos = rect.topLeft + Vector2i(-ow, -ow); tri << v << v;
v.pos = rect.topLeft; tri << v;

if (markerVisible && dir == ui::Down)
{
v.pos = Vector2i(anchorPos.x - marker - halfOw, rect.top() - ow); tri << v;
v.pos += Vector2i(halfOw, ow); tri << v;

v.pos = anchorPos + Vector2i(0, -midOw); tri << v;
v.pos.y += midOw; tri << v;

v.pos = Vector2i(anchorPos.x + marker + halfOw, rect.top() - ow); tri << v;
v.pos += Vector2i(-halfOw, ow); tri << v;
}

// Right edge.
v.pos = rect.topRight() + Vector2i(ow, -ow); tri << v;
v.pos = rect.topRight(); tri << v;

if (markerVisible && dir == ui::Left)
{
v.pos = Vector2i(rect.right() + ow, anchorPos.y - marker - halfOw); tri << v;
v.pos += Vector2i(-ow, halfOw); tri << v;

v.pos = anchorPos + Vector2i(midOw, 0); tri << v;
v.pos.x += -midOw; tri << v;

v.pos = Vector2i(rect.right() + ow, anchorPos.y + marker + halfOw); tri << v;
v.pos += Vector2i(-ow, -halfOw); tri << v;
}

// Bottom edge.
v.pos = rect.bottomRight + Vector2i(ow, ow); tri << v;
v.pos = rect.bottomRight; tri << v;

if (markerVisible && dir == ui::Up)
{
v.pos = Vector2i(anchorPos.x + marker + halfOw, rect.bottom() + ow); tri << v;
v.pos += Vector2i(-halfOw, -ow); tri << v;

v.pos = anchorPos + Vector2i(0, midOw); tri << v;
v.pos.y += -midOw; tri << v;

v.pos = Vector2i(anchorPos.x - marker - halfOw, rect.bottom() + ow); tri << v;
v.pos += Vector2i(halfOw, -ow); tri << v;
}

// Left edge.
v.pos = rect.bottomLeft() + Vector2i(-ow, ow); tri << v;
v.pos = rect.bottomLeft(); tri << v;

if (markerVisible && dir == ui::Right)
{
v.pos = Vector2i(rect.left() - ow, anchorPos.y + marker + halfOw); tri << v;
v.pos += Vector2i(ow, -halfOw); tri << v;

v.pos = anchorPos + Vector2i(-midOw, 0); tri << v;
v.pos.x += midOw; tri << v;

v.pos = Vector2i(rect.left() - ow, anchorPos.y - marker - halfOw); tri << v;
v.pos += Vector2i(ow, halfOw); tri << v;
}

// Back to top.
v.pos = rect.topLeft + Vector2i(-ow, -ow); tri << v;
v.pos = rect.topLeft; tri << v;
}

verts += tri;
Expand Down

0 comments on commit 56d3745

Please sign in to comment.