Skip to content

Commit

Permalink
UI|Client|Widgets: Improvements to DialogWidget (and popup, button)
Browse files Browse the repository at this point in the history
Dialogs now define some generic button roles (accept, reject, etc.)
so that it is more convenient to construct dialogs.

Dialogs also don't grow larger than the view height, and will
allow scrolling up/down if the content doesn't fit.

Cleanup: Applied the maybeAs() method
  • Loading branch information
skyjake committed Aug 18, 2013
1 parent eeed31e commit b0dc682
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 37 deletions.
8 changes: 8 additions & 0 deletions doomsday/client/include/ui/uidefs.h
Expand Up @@ -45,6 +45,14 @@ inline Direction opposite(Direction dir) {
}
}

inline bool isHorizontal(Direction dir) {
return dir == ui::Left || dir == ui::Right;
}

inline bool isVertical(Direction dir) {
return dir == ui::Up || dir == ui::Down;
}

/**
* Flags for specifying alignment.
*/
Expand Down
2 changes: 2 additions & 0 deletions doomsday/client/include/ui/widgets/buttonwidget.h
Expand Up @@ -67,6 +67,8 @@ class ButtonWidget : public LabelWidget
*/
void setAction(de::Action *action);

de::Action *action() const;

State state() const;

// Events.
Expand Down
40 changes: 39 additions & 1 deletion doomsday/client/include/ui/widgets/dialogwidget.h
Expand Up @@ -50,14 +50,48 @@ class DialogWidget : public PopupWidget
Nonmodal
};

enum RoleFlag {
None = 0,
Default = 0x1, ///< Pressing Space or Enter will activate this.
Accept = 0x2,
Reject = 0x4,
Yes = 0x8,
No = 0x10,
Action = 0x20
};
Q_DECLARE_FLAGS(RoleFlags, RoleFlag)

class ButtonItem : public ui::ActionItem
{
public:
/**
* Button with the role's default label and action.
* @param flags Role flags for the button.
* @param label Label for the button. If empty, the default label will be used.
*/
ButtonItem(RoleFlags flags, de::String const &label = "");

/**
* Button with custom action.
* @param flags Role flags for the button.
* @param label Label for the button. If empty, the default label will be used.
*/
ButtonItem(RoleFlags flags, de::String const &label, de::Action *action);

RoleFlags role() const { return _role; }

private:
RoleFlags _role;
};

public:
DialogWidget(de::String const &name = "");

void setModality(Modality modality);

Modality modality() const;

ScrollAreaWidget &content();
ScrollAreaWidget &area();

MenuWidget &buttons();

Expand Down Expand Up @@ -105,4 +139,8 @@ public slots:
DENG2_PRIVATE(d)
};

typedef DialogWidget::ButtonItem DialogButtonItem;

Q_DECLARE_OPERATORS_FOR_FLAGS(DialogWidget::RoleFlags)

#endif // DENG_CLIENT_DIALOGWIDGET_H
2 changes: 2 additions & 0 deletions doomsday/client/include/ui/widgets/popupwidget.h
Expand Up @@ -65,6 +65,8 @@ class PopupWidget : public GuiWidget
*/
void setOpeningDirection(ui::Direction dir);

ui::Direction openingDirection() const;

bool isOpen() const;

/**
Expand Down
19 changes: 9 additions & 10 deletions doomsday/client/src/ui/widgets/aboutdialog.cpp
Expand Up @@ -65,13 +65,13 @@ AboutDialog::AboutDialog() : DialogWidget("about")
homepage->setSizePolicy(ui::Expand, ui::Expand);
homepage->setAction(new SignalAction(&ClientApp::app(), SLOT(openHomepageInBrowser())));

content().add(logo);
content().add(title);
content().add(info);
content().add(homepage);
area().add(logo);
area().add(title);
area().add(info);
area().add(homepage);

// Position inside the content.
RuleRectangle const &cont = content().contentRule();
RuleRectangle const &cont = area().contentRule();
logo->rule()
.setLeftTop(cont.left(), cont.top())
.setInput(Rule::Width, width);
Expand All @@ -87,11 +87,10 @@ AboutDialog::AboutDialog() : DialogWidget("about")
.setAnchorPoint(Vector2f(.5f, 0));

// Total size of the dialog's content.
content().setContentWidth(width);
content().setContentHeight(logo->rule().height() + title->rule().height() +
info->rule().height() + homepage->rule().height());
area().setContentWidth(width);
area().setContentHeight(logo->rule().height() + title->rule().height() +
info->rule().height() + homepage->rule().height());

// Just an OK button.
buttons().items()
<< new ui::ActionItem(tr("Close"), new SignalAction(this, SLOT(accept())));
<< new DialogButtonItem(DialogWidget::Accept | DialogWidget::Default, tr("Close"));
}
5 changes: 5 additions & 0 deletions doomsday/client/src/ui/widgets/buttonwidget.cpp
Expand Up @@ -147,6 +147,11 @@ void ButtonWidget::setAction(Action *action)
}
}

Action *ButtonWidget::action() const
{
return d->action.data();
}

ButtonWidget::State ButtonWidget::state() const
{
return d->state;
Expand Down
4 changes: 2 additions & 2 deletions doomsday/client/src/ui/widgets/choicewidget.cpp
Expand Up @@ -63,11 +63,11 @@ DENG2_OBSERVES(ContextWidgetOrganizer, WidgetCreation)

void widgetCreatedForItem(GuiWidget &widget, ui::Item const &item)
{
if(widget.is<ButtonWidget>())
if(ButtonWidget *but = widget.maybeAs<ButtonWidget>())
{
// Make sure the created buttons have an action that updates the
// selected item.
widget.as<ButtonWidget>().setAction(new SelectAction(this, item));
but->setAction(new SelectAction(this, item));
}
}

Expand Down

0 comments on commit b0dc682

Please sign in to comment.