Skip to content

Commit

Permalink
UI|libappfw: UI style tweaks
Browse files Browse the repository at this point in the history
Inverted buttons with rounded background, focus flashing colors from
Style, animating panel height.
  • Loading branch information
skyjake committed Jun 19, 2016
1 parent b262956 commit c62dd27
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ label {
color shadow { rgb $= gui.colorAlpha(background.rgb, 0.34) }
}

focus {
color flash.on { rgb $= gui.colorAlpha(accent.rgb, 0.8) }
color flash.off { rgb $= background.rgb }
}

popup {
info {
color background { rgb <1.0, 1.0, 1.0> }
Expand Down Expand Up @@ -68,11 +73,6 @@ dialog {
editor {
color cursor { rgb $= gui.colorAlpha(accent.rgb, 0.7) }
color hint { rgb $= altaccent.rgb }

#completion {
# color background { rgb <1.0, 1.0, 1.0> }
# color glow { rgb $= inverted.glow.rgb }
#}
}

log {
Expand Down
1 change: 1 addition & 0 deletions doomsday/sdk/libappfw/include/de/framework/guirootwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class LIBAPPFW_PUBLIC GuiRootWidget : public RootWidget
AtlasTexture &atlas();
GLUniform &uAtlas();
Id solidWhitePixel() const;
Id solidRoundCorners() const;
Id roundCorners() const;
Id boldRoundCorners() const;
Id borderGlow() const;
Expand Down
5 changes: 3 additions & 2 deletions doomsday/sdk/libappfw/include/de/framework/guiwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ class LIBAPPFW_PUBLIC GuiWidget : public QObject, public Widget
*/
struct Background {
enum Type {
None, ///< No background or solid fill.
GradientFrame, ///< Use the "gradient frame" from the UI atlas.
None, ///< No background, no solid fill.
GradientFrame, ///< Bold round corners, square background.
GradientFrameWithRoundedFill, ///< Bold round corners with solid rounded background.
BorderGlow, ///< Border glow with specified color/thickness.
Blurred, ///< Blurs whatever is showing behind the widget.
BlurredWithBorderGlow,
Expand Down
3 changes: 3 additions & 0 deletions doomsday/sdk/libappfw/include/de/widgets/focuswidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class LIBAPPFW_PUBLIC FocusWidget : public LabelWidget
void startFlashing(GuiWidget const *reference = nullptr);
void stopFlashing();

// Events.
void update() override;

protected slots:
void updateFlash();

Expand Down
38 changes: 29 additions & 9 deletions doomsday/sdk/libappfw/src/guirootwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@
namespace de {

// Identifiers for images generated by GuiRootWidget.
static DotPath const ID_SOLID_WHITE = "GuiRootWidget.solid.white";
static DotPath const ID_THIN_ROUND_CORNERS = "GuiRootWidget.frame.thin";
static DotPath const ID_BOLD_ROUND_CORNERS = "GuiRootWidget.frame.bold";
static DotPath const ID_DOT = "GuiRootWidget.dot";
static DotPath const ID_SOLID_WHITE = "GuiRootWidget.solid.white";
static DotPath const ID_SOLID_ROUND_CORNERS = "GuiRootWidget.solid.roundCorners";
static DotPath const ID_THIN_ROUND_CORNERS = "GuiRootWidget.frame.thin";
static DotPath const ID_BOLD_ROUND_CORNERS = "GuiRootWidget.frame.bold";
static DotPath const ID_DOT = "GuiRootWidget.dot";

#ifdef DENG2_QT_5_0_OR_NEWER
# define DPI_SCALED(x) ((x) * DENG2_BASE_GUI_APP->dpiFactor())
Expand Down Expand Up @@ -77,12 +78,24 @@ DENG2_PIMPL(GuiRootWidget)
img.fill(QColor(255, 255, 255, 0).rgba());
QPainter painter(&img);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(QColor(255, 255, 255, 255), DPI_SCALED(2)));
painter.setPen(QPen(Qt::white, DPI_SCALED(2)));
painter.setBrush(Qt::NoBrush);
painter.drawEllipse(DPI_SCALED(QPointF(6, 6)), DPI_SCALED(4), DPI_SCALED(4));
return img;
}
};
struct SolidRoundedImage : public TextureBank::ImageSource {
Image load() const {
QImage img(QSize(DPI_SCALED(12), DPI_SCALED(12)), QImage::Format_ARGB32);
img.fill(QColor(255, 255, 255, 0).rgba());
QPainter painter(&img);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::white);
painter.drawEllipse(DPI_SCALED(QPointF(6, 6)), DPI_SCALED(6), DPI_SCALED(6));
return img;
}
};
struct TinyDotImage : public TextureBank::ImageSource {
Image load() const {
QImage img(QSize(DPI_SCALED(5), DPI_SCALED(5)), QImage::Format_ARGB32);
Expand Down Expand Up @@ -154,10 +167,11 @@ DENG2_PIMPL(GuiRootWidget)
void initBankContents()
{
// Built-in images.
texBank.add(ID_SOLID_WHITE, new SolidWhiteImage);
texBank.add(ID_THIN_ROUND_CORNERS, new ThinCornersImage);
texBank.add(ID_BOLD_ROUND_CORNERS, new BoldCornersImage);
texBank.add(ID_DOT, new TinyDotImage);
texBank.add(ID_SOLID_WHITE, new SolidWhiteImage);
texBank.add(ID_SOLID_ROUND_CORNERS, new SolidRoundedImage);
texBank.add(ID_THIN_ROUND_CORNERS, new ThinCornersImage);
texBank.add(ID_BOLD_ROUND_CORNERS, new BoldCornersImage);
texBank.add(ID_DOT, new TinyDotImage);

// All style images.
Style const &st = Style::get();
Expand Down Expand Up @@ -247,6 +261,12 @@ Id GuiRootWidget::solidWhitePixel() const
return d->texBank.texture(ID_SOLID_WHITE);
}

Id GuiRootWidget::solidRoundCorners() const
{
d->initAtlas();
return d->texBank.texture(ID_SOLID_ROUND_CORNERS);
}

Id GuiRootWidget::roundCorners() const
{
d->initAtlas();
Expand Down
34 changes: 22 additions & 12 deletions doomsday/sdk/libappfw/src/guiwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,36 +904,46 @@ GuiWidget const *GuiWidget::guiFind(String const &name) const

void GuiWidget::glMakeGeometry(DefaultVertexBuf::Builder &verts)
{
if (d->background.type != Background::Blurred &&
d->background.type != Background::BlurredWithBorderGlow &&
d->background.type != Background::SharedBlur &&
d->background.type != Background::SharedBlurWithBorderGlow)
auto &rootWgt = root();
float const thick = d->toDevicePixels(d->background.thickness);

// Is there a solid fill?
if (d->background.solidFill.w > 0)
{
// Is there a solid fill?
if (d->background.solidFill.w > 0)
if (d->background.type == Background::GradientFrameWithRoundedFill)
{
Rectanglei const recti = rule().recti().shrunk(d->toDevicePixels(2));
verts.makeQuad(recti.shrunk(thick), d->background.solidFill,
rootWgt.atlas().imageRectf(rootWgt.solidRoundCorners()).middle());
verts.makeFlexibleFrame(recti, thick, d->background.solidFill,
rootWgt.atlas().imageRectf(rootWgt.solidRoundCorners()));
}
else if (d->background.type != Background::Blurred &&
d->background.type != Background::BlurredWithBorderGlow &&
d->background.type != Background::SharedBlur &&
d->background.type != Background::SharedBlurWithBorderGlow)
{
verts.makeQuad(rule().recti(),
d->background.solidFill,
root().atlas().imageRectf(root().solidWhitePixel()).middle());
rootWgt.atlas().imageRectf(rootWgt.solidWhitePixel()).middle());
}
}

float const thick = d->toDevicePixels(d->background.thickness);

switch (d->background.type)
{
case Background::GradientFrame:
case Background::GradientFrameWithRoundedFill:
verts.makeFlexibleFrame(rule().recti().shrunk(d->toDevicePixels(1)),
thick,
d->background.color,
root().atlas().imageRectf(root().boldRoundCorners()));
rootWgt.atlas().imageRectf(rootWgt.boldRoundCorners()));
break;

case Background::Rounded:
verts.makeFlexibleFrame(rule().recti().shrunk(d->toDevicePixels(d->background.thickness - 4)),
thick,
d->background.color,
root().atlas().imageRectf(root().roundCorners()));
rootWgt.atlas().imageRectf(rootWgt.roundCorners()));
break;

case Background::BorderGlow:
Expand All @@ -942,7 +952,7 @@ void GuiWidget::glMakeGeometry(DefaultVertexBuf::Builder &verts)
verts.makeFlexibleFrame(rule().recti().expanded(thick),
thick,
d->background.color,
root().atlas().imageRectf(root().borderGlow()));
rootWgt.atlas().imageRectf(rootWgt.borderGlow()));
break;

case Background::Blurred: // blurs drawn separately in GuiWidget::draw()
Expand Down
14 changes: 11 additions & 3 deletions doomsday/sdk/libappfw/src/widgets/buttonwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ DENG2_OBSERVES(Action, Triggered)
DotPath borderColorId { "text" };
HoverColorMode hoverColorMode = ReplaceColor;
ColorTheme colorTheme = Normal;
Background::Type bgType = Background::GradientFrame;
Action *action = nullptr;
Animation scale { 1.f };
Animation frameOpacity { .08f, Animation::Linear };
Expand Down Expand Up @@ -143,14 +144,14 @@ DENG2_OBSERVES(Action, Triggered)
void setDefaultBackground()
{
self.set(Background(style().colors().colorf(bgColorId),
Background::GradientFrame,
borderColor(), 6));
bgType, borderColor(), 6));
}

void updateBackground()
{
Background bg = self.background();
if (bg.type == Background::GradientFrame)
if (bg.type == Background::GradientFrame ||
bg.type == Background::GradientFrameWithRoundedFill)
{
bg.solidFill = style().colors().colorf(bgColorId);
bg.color = borderColor();
Expand Down Expand Up @@ -205,21 +206,28 @@ bool ButtonWidget::isUsingInfoStyle() const

void ButtonWidget::setColorTheme(ColorTheme theme)
{
auto bg = background();

d->colorTheme = theme;
if (theme == Inverted)
{
d->bgType = Background::GradientFrameWithRoundedFill;
if (bg.type == Background::GradientFrame) bg.type = d->bgType;
d->originalTextColor = "inverted.text";
setHoverTextColor("inverted.text", ReplaceColor);
setBorderColor("inverted.text");
setBackgroundColor("inverted.background");
}
else
{
d->bgType = Background::GradientFrame;
if (bg.type == Background::GradientFrameWithRoundedFill) bg.type = d->bgType;
d->originalTextColor = "text";
setHoverTextColor("text", ReplaceColor);
setBorderColor("text");
setBackgroundColor("background");
}
set(bg);
setTextColor(d->originalTextColor);
d->originalTextModColor = Vector4f(1, 1, 1, 1);
setTextModulationColorf(d->originalTextModColor);
Expand Down
38 changes: 29 additions & 9 deletions doomsday/sdk/libappfw/src/widgets/focuswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ DENG2_PIMPL(FocusWidget)
{
QTimer flashing;
SafeWidgetPtr<GuiWidget const> reference;
Animation color { 0.f, Animation::Linear };
Vector4f flashColors[2];

Instance(Public *i) : Base(i)
{
self.set(Background(Background::GradientFrame,
Style::get().colors().colorf("accent"), 6));
flashColors[0] = Style::get().colors().colorf("focus.flash.off");
flashColors[1] = Style::get().colors().colorf("focus.flash.on");

flashing.setInterval(FLASH_SPAN.asMilliSeconds());
flashing.setSingleShot(false);
Expand All @@ -41,25 +43,31 @@ DENG2_PIMPL(FocusWidget)
void flash()
{
// Flashing depends on the reference widget's visibility.
float const maxOpacity = (reference? reference->visibleOpacity() : 1.f);
//float const maxOpacity = (reference? reference->visibleOpacity() : 1.f);
if (reference)
{
self.show(reference->isVisible());
}

if (self.opacity().target() == 0)
/*if (color.target() == 0)
{
self.setOpacity(.8f * maxOpacity, FLASH_SPAN + .1, .1);
color.setValue(.8f * maxOpacity, FLASH_SPAN + .1, .1);
}
else if (self.opacity().target() > .5f)
else*/
if (color.target() > .5f)
{
self.setOpacity(.2f * maxOpacity, FLASH_SPAN);
color.setValue(0, FLASH_SPAN);
}
else
{
self.setOpacity(.8f * maxOpacity, FLASH_SPAN);
color.setValue(1, FLASH_SPAN);
}
}

Vector4f currentColor() const
{
return flashColors[0] * (1.f - color) + flashColors[1] * color;
}
};

FocusWidget::FocusWidget(String const &name)
Expand All @@ -76,8 +84,8 @@ void FocusWidget::startFlashing(GuiWidget const *reference)
show();
if (!d->flashing.isActive())
{
setOpacity(0);
d->flashing.start();
d->color = 1;
}
}

Expand All @@ -87,6 +95,18 @@ void FocusWidget::stopFlashing()
hide();
}

void FocusWidget::update()
{
setOpacity(d->reference? d->reference->visibleOpacity() : 0.f);

if (isVisible())
{
set(Background(Background::GradientFrame, d->currentColor(), 6));
}

LabelWidget::update();
}

void FocusWidget::updateFlash()
{
d->flash();
Expand Down
1 change: 1 addition & 0 deletions doomsday/sdk/libappfw/src/widgets/panelwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ DENG_GUI_PIMPL(PanelWidget)
Instance(Public *i) : Base(i)
{
openingRule = new AnimationRule(0);
openingRule->setBehavior(AnimationRule::RestartWhenTargetChanges);

dismissTimer.setSingleShot(true);
QObject::connect(&dismissTimer, SIGNAL(timeout()), thisPublic, SLOT(dismiss()));
Expand Down

0 comments on commit c62dd27

Please sign in to comment.