Skip to content

Commit

Permalink
UI|Client: Folding/unfolding all groups in the Renderer Appearance ed…
Browse files Browse the repository at this point in the history
…itor

Right-clicking on one of the group titles now opens a popup menu with
fold/unfold actions.

Added a generic GuiWidget event handler to allow generic event
handling in any widget.
  • Loading branch information
skyjake committed Sep 23, 2013
1 parent 90eff11 commit 053f990
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 3 deletions.
Expand Up @@ -36,7 +36,8 @@ class RendererAppearanceEditor : public PanelWidget
RendererAppearanceEditor();

public slots:
//void showRendererSettings();
void foldAll();
void unfoldAll();

protected:
void preparePanelForOpening();
Expand Down
31 changes: 31 additions & 0 deletions doomsday/client/include/ui/framework/guiwidget.h
Expand Up @@ -136,6 +136,25 @@ class GuiWidget : public QObject, public de::Widget
typedef de::Vertex2TexRgba DefaultVertex;
typedef de::GLBufferT<DefaultVertex> DefaultVertexBuf;

/**
* Handles events.
*/
class IEventHandler
{
public:
virtual ~IEventHandler() {}

/**
* Handle an event.
*
* @param widget Widget that received the event.
* @param event Event.
*
* @return @c true, if the event was eaten. @c false otherwise.
*/
virtual bool handleEvent(GuiWidget &widget, de::Event const &event) = 0;
};

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

Expand Down Expand Up @@ -214,12 +233,24 @@ class GuiWidget : public QObject, public de::Widget
*/
float visibleOpacity() const;

/**
* Sets an object that will be offered events received by this widget. The
* handler may eat the event. Any number of event handlers can be added;
* they are called in the order of addition.
*
* @param handler Event handler. Ownership given to GuiWidget.
*/
void addEventHandler(IEventHandler *handler);

void removeEventHandler(IEventHandler *handler);

// Events.
void initialize();
void deinitialize();
void viewResized();
void update();
void draw() /*final*/;
bool handleEvent(de::Event const &event);

/**
* Determines if the widget occupies on-screen position @a pos.
Expand Down
62 changes: 61 additions & 1 deletion doomsday/client/src/ui/editors/rendererappearanceeditor.cpp
Expand Up @@ -39,6 +39,40 @@ DENG_GUI_PIMPL(RendererAppearanceEditor),
DENG2_OBSERVES(SettingsRegister, ProfileChange),
DENG2_OBSERVES(App, GameChange)
{
/**
* Opens a popup menu for folding/unfolding all settings groups.
*/
struct RightClickHandler : public GuiWidget::IEventHandler
{
Instance *d;

RightClickHandler(Instance *inst) : d(inst) {}

bool handleEvent(GuiWidget &widget, Event const &event)
{
switch(widget.handleMouseClick(event, MouseEvent::Right))
{
case MouseClickFinished: {
MouseEvent const &mouse = event.as<MouseEvent>();
PopupMenuWidget *pop = new PopupMenuWidget;
pop->setDeleteAfterDismissed(true);
d->self.add(pop);
pop->setAnchorAndOpeningDirection(widget.rule(), ui::Left);
pop->items()
<< new ActionItem(tr("Fold All"), new SignalAction(d->thisPublic, SLOT(foldAll())))
<< new ActionItem(tr("Unfold All"), new SignalAction(d->thisPublic, SLOT(unfoldAll())));
pop->open();
return true; }

case MouseClickUnrelated:
return false;

default:
return true;
}
}
};

/**
* Foldable group of settings.
*/
Expand All @@ -60,7 +94,6 @@ DENG2_OBSERVES(App, GameChange)
};

public:

Group(RendererAppearanceEditor::Instance *inst, String const &titleText)
: d(inst), _firstColumnWidth(0)
{
Expand All @@ -69,6 +102,9 @@ DENG2_OBSERVES(App, GameChange)
title().setText(titleText);
title().setTextColor("accent");

// Set up a context menu for right-clicking.
title().addEventHandler(new RightClickHandler(d));

// We want the first column of all groups to be aligned with each other.
_layout.setColumnFixedWidth(0, *d->firstColumnWidth);

Expand Down Expand Up @@ -597,6 +633,20 @@ DENG2_OBSERVES(App, GameChange)
}
}
}

void foldAll(bool fold)
{
foreach(Widget *child, container->childWidgets())
{
if(Group *g = child->maybeAs<Group>())
{
if(fold)
g->close(0);
else
g->open();
}
}
}
};

RendererAppearanceEditor::RendererAppearanceEditor()
Expand Down Expand Up @@ -664,6 +714,16 @@ RendererAppearanceEditor::RendererAppearanceEditor()
d->lightGroup->open();
}

void RendererAppearanceEditor::foldAll()
{
d->foldAll(true);
}

void RendererAppearanceEditor::unfoldAll()
{
d->foldAll(false);
}

/*
void RendererAppearanceEditor::showRendererSettings()
{
Expand Down
27 changes: 27 additions & 0 deletions doomsday/client/src/ui/framework/guiwidget.cpp
Expand Up @@ -26,6 +26,8 @@
#include <de/GLTexture>
#include <de/GLTarget>

#include <QList>

using namespace de;

DENG2_PIMPL(GuiWidget),
Expand All @@ -44,6 +46,7 @@ DENG2_OBSERVES(ui::Margins, Change)
bool styleChanged;
Background background;
Animation opacity;
QList<IEventHandler *> eventHandlers;

// Style.
DotPath fontId;
Expand Down Expand Up @@ -91,6 +94,8 @@ DENG2_OBSERVES(ui::Margins, Change)

~Instance()
{
qDeleteAll(eventHandlers);

// The base class will delete all children, but we need to deinitialize
// them first.
self.notifyTree(&Widget::deinitialize);
Expand Down Expand Up @@ -419,6 +424,16 @@ float GuiWidget::visibleOpacity() const
return opacity;
}

void GuiWidget::addEventHandler(IEventHandler *handler)
{
d->eventHandlers.append(handler);
}

void GuiWidget::removeEventHandler(IEventHandler *handler)
{
d->eventHandlers.removeOne(handler);
}

void GuiWidget::initialize()
{
if(d->inited) return;
Expand Down Expand Up @@ -490,6 +505,18 @@ void GuiWidget::draw()
}
}

bool GuiWidget::handleEvent(Event const &event)
{
foreach(IEventHandler *handler, d->eventHandlers)
{
if(handler->handleEvent(*this, event))
{
return true;
}
}
return Widget::handleEvent(event);
}

bool GuiWidget::hitTest(Vector2i const &pos) const
{
if(behavior().testFlag(Unhittable))
Expand Down
3 changes: 2 additions & 1 deletion doomsday/client/src/ui/widgets/buttonwidget.cpp
Expand Up @@ -223,7 +223,8 @@ bool ButtonWidget::handleEvent(Event const &event)
}
}
}
return false;

return LabelWidget::handleEvent(event);
}

void ButtonWidget::updateModelViewProjection(GLUniform &uMvp)
Expand Down

0 comments on commit 053f990

Please sign in to comment.