Skip to content

Commit

Permalink
Refactor|UI|Client: Use ui::Context in menu-based widgets
Browse files Browse the repository at this point in the history
ui::Context provides a uniform way to manage a set of items for
menus. It is now used for all menu-based widgets (regular menu, popup
menu, game selection).

Specialized menus tap into the base class's Organizer to gain access
and customize the created widgets.
  • Loading branch information
skyjake committed Aug 16, 2013
1 parent 705dfba commit b6ea8b3
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 30 deletions.
15 changes: 14 additions & 1 deletion doomsday/client/include/ui/widgets/menuwidget.h
Expand Up @@ -21,6 +21,9 @@

#include "scrollareawidget.h"
#include "buttonwidget.h"
#include "context.h"
#include "contextwidgetorganizer.h"
#include "actionitem.h"

/**
* Menu with an N-by-M grid of items (child widgets).
Expand All @@ -36,6 +39,7 @@
class MenuWidget : public ScrollAreaWidget
{
public:
#if 0
class ISortOrder
{
public:
Expand All @@ -51,6 +55,7 @@ class MenuWidget : public ScrollAreaWidget
*/
virtual int compareMenuItemsForSorting(Widget const &a, Widget const &b) const = 0;
};
#endif

public:
MenuWidget(de::String const &name = "");
Expand Down Expand Up @@ -83,8 +88,15 @@ class MenuWidget : public ScrollAreaWidget
*
* @param sorting Sort order object. MenuWidget takes ownership.
*/
void setLayoutSortOrder(ISortOrder *sorting);
//void setLayoutSortOrder(ISortOrder *sorting);

ui::Context &items();

ui::Context const &items() const;

ContextWidgetOrganizer const &organizer() const;

/*
GuiWidget *addItem(GuiWidget *anyWidget);
ButtonWidget *addItem(de::String const &styledText, de::Action *action = 0);
Expand All @@ -94,6 +106,7 @@ class MenuWidget : public ScrollAreaWidget
GuiWidget *addSeparator(de::String const &labelText = "");
void removeItem(GuiWidget *child);
*/

/**
* Returns the number of visible items in the menu. Hidden items are not
Expand Down
4 changes: 3 additions & 1 deletion doomsday/client/include/ui/widgets/popupmenuwidget.h
Expand Up @@ -32,11 +32,13 @@ class PopupMenuWidget : public PopupWidget

MenuWidget &menu() const;

/*
ButtonWidget *addItem(de::String const &styledText, de::Action *action = 0,
bool dismissOnTriggered = true);
LabelWidget *addItem(LabelWidget *anyLabelBasedWidget);
*/

GuiWidget *addSeparator(de::String const &optionalLabel = "");
//GuiWidget *addSeparator(de::String const &optionalLabel = "");

protected:
void glMakeGeometry(DefaultVertexBuf::Builder &verts);
Expand Down
48 changes: 30 additions & 18 deletions doomsday/client/src/ui/widgets/gameselectionwidget.cpp
Expand Up @@ -17,6 +17,7 @@
*/

#include "ui/widgets/gameselectionwidget.h"
#include "ui/widgets/actionitem.h"
#include "ui/commandaction.h"
#include "clientapp.h"
#include "games.h"
Expand All @@ -28,11 +29,13 @@ using namespace de;

DENG2_PIMPL(GameSelectionWidget),
DENG2_OBSERVES(Games, Addition),
DENG2_OBSERVES(App, StartupComplete)
DENG2_OBSERVES(App, StartupComplete),
DENG2_OBSERVES(ContextWidgetOrganizer, WidgetCreation)
{
typedef QMap<Game *, ButtonWidget *> Buttons;
Buttons buttons;

#if 0
/**
* Sorts the game buttons by label text.
*/
Expand All @@ -45,13 +48,15 @@ DENG2_OBSERVES(App, StartupComplete)
return x.text().compareWithoutCase(y.text());
}
};
#endif

Instance(Public *i) : Base(i)
{
App_Games().audienceForAddition += this;
App::app().audienceForStartupComplete += this;

self.setLayoutSortOrder(new Sorting);
//self.setLayoutSortOrder(new Sorting);
self.organizer().audienceForWidgetCreation += this;
}

~Instance()
Expand All @@ -62,22 +67,21 @@ DENG2_OBSERVES(App, StartupComplete)

void gameAdded(Game &game)
{
ButtonWidget *b = addItemForGame(game);
buttons.insert(&game, b);
self.items().append(makeItemForGame(game));
}

ButtonWidget *addItemForGame(Game &game)
ui::Item *makeItemForGame(Game &game)
{
String const idKey = Str_Text(game.identityKey());

CommandAction *loadAction = new CommandAction(String("load ") + idKey);
ButtonWidget *b = self.addItem(
String(_E(b) "%1" _E(.)_E(s)_E(C) " %2\n"
String label = String(_E(b) "%1" _E(.)_E(s)_E(C) " %2\n"
_E(.)_E(.)_E(l)_E(D) "%3")
.arg(Str_Text(game.title()))
.arg(Str_Text(game.author()))
.arg(idKey),
loadAction);
.arg(Str_Text(game.title()))
.arg(Str_Text(game.author()))
.arg(idKey);

ui::ActionItem *item = new ui::ActionItem(label, loadAction);

/// @todo The name of the plugin should be accessible via the plugin loader.
String plugName;
Expand All @@ -95,15 +99,21 @@ DENG2_OBSERVES(App, StartupComplete)
}
if(self.style().images().has("logo.game." + plugName))
{
b->setImage(self.style().images().image("logo.game." + plugName));
item->setImage(self.style().images().image("logo.game." + plugName));
}

b->setBehavior(Widget::ContentClipping);
b->setAlignment(ui::AlignLeft);
b->setTextLineAlignment(ui::AlignLeft);
b->setHeightPolicy(ui::Expand);
b->setOpacity(.3f, .5f);
return b;
return item;
}

void widgetCreatedForItem(GuiWidget &widget, ui::Item const &item)
{
ButtonWidget &b = widget.as<ButtonWidget>();

b.setBehavior(Widget::ContentClipping);
b.setAlignment(ui::AlignLeft);
b.setTextLineAlignment(ui::AlignLeft);
b.setHeightPolicy(ui::Expand);
b.setOpacity(.3f, .5f);
}

void appStartupCompleted()
Expand All @@ -126,6 +136,8 @@ DENG2_OBSERVES(App, StartupComplete)
i.value()->disable();
}
}

self.items().sort();
}
};

Expand Down

0 comments on commit b6ea8b3

Please sign in to comment.