Skip to content

Commit

Permalink
Refactor|UI|Client: Added a popup widget with a grid
Browse files Browse the repository at this point in the history
GridPopupWidget makes it easier to create popups whose content is
laid out in a grid.
  • Loading branch information
skyjake committed Sep 20, 2013
1 parent 666dc88 commit df614d6
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 71 deletions.
2 changes: 2 additions & 0 deletions doomsday/client/client.pro
Expand Up @@ -423,6 +423,7 @@ DENG_HEADERS += \
include/ui/widgets/documentwidget.h \
include/ui/widgets/foldpanelwidget.h \
include/ui/widgets/gameselectionwidget.h \
include/ui/widgets/gridpopupwidget.h \
include/ui/widgets/icvarwidget.h \
include/ui/widgets/labelwidget.h \
include/ui/widgets/legacywidget.h \
Expand Down Expand Up @@ -763,6 +764,7 @@ SOURCES += \
src/ui/widgets/documentwidget.cpp \
src/ui/widgets/foldpanelwidget.cpp \
src/ui/widgets/gameselectionwidget.cpp \
src/ui/widgets/gridpopupwidget.cpp \
src/ui/widgets/labelwidget.cpp \
src/ui/widgets/legacywidget.cpp \
src/ui/widgets/lineeditwidget.cpp \
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/include/ui/widgets/cvartogglewidget.h
Expand Up @@ -30,7 +30,7 @@ class CVarToggleWidget : public ToggleWidget, public ICVarWidget
Q_OBJECT

public:
CVarToggleWidget(char const *cvarPath);
CVarToggleWidget(char const *cvarPath, de::String const &labelText = "");

char const *cvarPath() const;

Expand Down
73 changes: 73 additions & 0 deletions doomsday/client/include/ui/widgets/gridpopupwidget.h
@@ -0,0 +1,73 @@
/** @file
*
* @authors Copyright (c) 2013 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#ifndef DENG_CLIENT_GRIDPOPUPWIDGET_H
#define DENG_CLIENT_GRIDPOPUPWIDGET_H

#include "popupwidget.h"

class GridLayout;

/**
* Popup with a grid layout for children.
*
* The default layout is 2 columns with unlimited rows, with the leftmost
* column aligned to the right.
*
* Used for instance in the settings dialogs.
*/
class GridPopupWidget : public PopupWidget
{
public:
GridPopupWidget(de::String const &name = "");

/**
* Returns the layout used by the popup's contents.
*/
GridLayout &layout();

/**
* Adds a widget to the popup grid. The widget becomes a child of the
* popup's container and is added to the grid layout as the next item.
*
* @param widget Widget to add.
*
* @return Reference to this widget (fluent interface).
*/
GridPopupWidget &operator << (GuiWidget *widget);

/**
* Adds an empty cell to the popup grid.
*
* @param rule Amount of space to add in the cell.
*
* @return Reference to this widget (fluent interface).
*/
GridPopupWidget &operator << (de::Rule const &rule);

/**
* Finalizes the layout of the popup. Call this after all the layout items
* have been added to the widget.
*/
void commit();

private:
DENG2_PRIVATE(d)
};

#endif // DENG_CLIENT_GRIDPOPUPWIDGET_H
102 changes: 35 additions & 67 deletions doomsday/client/src/ui/dialogs/renderersettingsdialog.cpp
Expand Up @@ -23,6 +23,7 @@
#include "ui/widgets/taskbarwidget.h"
#include "ui/editors/rendererappearanceeditor.h"
#include "ui/widgets/profilepickerwidget.h"
#include "ui/widgets/gridpopupwidget.h"
#include "ui/dialogs/inputdialog.h"
#include "GridLayout"
#include "SignalAction"
Expand All @@ -44,16 +45,7 @@ DENG_GUI_PIMPL(RendererSettingsDialog)
CVarToggleWidget *multiDetail;

// Developer settings.
PopupWidget *devPopup;
QScopedPointer<DialogContentStylist> stylist;
CVarChoiceWidget *rendTex;
CVarChoiceWidget *wireframe;
CVarToggleWidget *bboxMobj;
CVarToggleWidget *bboxPoly;
CVarToggleWidget *thinkerIds;
CVarToggleWidget *secIdx;
CVarToggleWidget *vertIdx;
CVarToggleWidget *genIdx;
GridPopupWidget *devPopup;

Instance(Public *i) : Base(i)
{
Expand All @@ -74,44 +66,38 @@ DENG_GUI_PIMPL(RendererSettingsDialog)
area.add(multiDetail = new CVarToggleWidget("rend-tex-detail-multitex"));

// Set up a separate popup for developer settings.
self.add(devPopup = new PopupWidget);

GuiWidget *container = new GuiWidget;
devPopup->setContent(container);
stylist.reset(new DialogContentStylist(*container));

LabelWidget *boundLabel = LabelWidget::newWithText(tr("Bounds:"), container);
LabelWidget *idLabel = LabelWidget::newWithText(tr("Identifiers:"), container);
LabelWidget *texLabel = LabelWidget::newWithText(tr("Surface Texturing:"), container);
LabelWidget *wireLabel = LabelWidget::newWithText(tr("Draw as Wireframe:"), container);

container->add(bboxMobj = new CVarToggleWidget("rend-dev-mobj-bbox"));
container->add(bboxPoly = new CVarToggleWidget("rend-dev-polyobj-bbox"));
container->add(thinkerIds = new CVarToggleWidget("rend-dev-thinker-ids"));
container->add(secIdx = new CVarToggleWidget("rend-dev-sector-show-indices"));
container->add(vertIdx = new CVarToggleWidget("rend-dev-vertex-show-indices"));
container->add(genIdx = new CVarToggleWidget("rend-dev-generator-show-indices"));
container->add(rendTex = new CVarChoiceWidget("rend-tex"));
container->add(wireframe = new CVarChoiceWidget("rend-dev-wireframe"));

// Layout for the developer settings.
Rule const &gap = self.style().rules().rule("gap");
GridLayout layout(container->rule().left() + gap,
container->rule().top() + gap);
layout.setGridSize(2, 0);
layout.setColumnAlignment(0, ui::AlignRight);

layout << *texLabel << *rendTex
<< *wireLabel << *wireframe
<< *boundLabel << *bboxMobj
<< Const(0) << *bboxPoly
<< *idLabel << *thinkerIds
<< Const(0) << *secIdx
<< Const(0) << *vertIdx
<< Const(0) << *genIdx;

container->rule().setSize(layout.width() + gap * 2,
layout.height() + gap * 2);
self.add(devPopup = new GridPopupWidget);

CVarChoiceWidget *rendTex = new CVarChoiceWidget("rend-tex");
rendTex->items()
<< new ChoiceItem(tr("Materials"), 1)
<< new ChoiceItem(tr("Plain white"), 0)
<< new ChoiceItem(tr("Plain gray"), 2);

CVarChoiceWidget *wireframe = new CVarChoiceWidget("rend-dev-wireframe");
wireframe->items()
<< new ChoiceItem(tr("Nothing"), 0)
<< new ChoiceItem(tr("Game world"), 1)
<< new ChoiceItem(tr("Game world and UI"), 2);

*devPopup << LabelWidget::newWithText(tr("Surface Texturing:"))
<< rendTex
<< LabelWidget::newWithText(tr("Draw as Wireframe:"))
<< wireframe
<< LabelWidget::newWithText(tr("Bounds:"))
<< new CVarToggleWidget("rend-dev-mobj-bbox", tr("Mobj Bounding Boxes"))
<< Const(0)
<< new CVarToggleWidget("rend-dev-polyobj-bbox", tr("Polyobj Bounding Boxes"))
<< LabelWidget::newWithText(tr("Identifiers:"))
<< new CVarToggleWidget("rend-dev-thinker-ids", tr("Thinker IDs"))
<< Const(0)
<< new CVarToggleWidget("rend-dev-sector-show-indices", tr("Sector Indices"))
<< Const(0)
<< new CVarToggleWidget("rend-dev-vertex-show-indices", tr("Vertex Indices"))
<< Const(0)
<< new CVarToggleWidget("rend-dev-generator-show-indices", tr("Particle Generator Indices"));

devPopup->commit();
}

void fetch()
Expand Down Expand Up @@ -146,24 +132,6 @@ RendererSettingsDialog::RendererSettingsDialog(String const &name)
d->multiShiny->setText(tr("3D Model Shiny Surfaces"));
d->multiDetail->setText(tr("Surface Details"));

d->rendTex->items()
<< new ChoiceItem(tr("Materials"), 1)
<< new ChoiceItem(tr("Plain white"), 0)
<< new ChoiceItem(tr("Plain gray"), 2);

d->wireframe->items()
<< new ChoiceItem(tr("Nothing"), 0)
<< new ChoiceItem(tr("Game world"), 1)
<< new ChoiceItem(tr("Game world and UI"), 2);

// Developer labels.
d->bboxMobj->setText(tr("Mobj Bounding Boxes"));
d->bboxPoly->setText(tr("Polyobj Bounding Boxes"));
d->thinkerIds->setText(tr("Thinker IDs"));
d->secIdx->setText(tr("Sector Indices"));
d->vertIdx->setText(tr("Vertex Indices"));
d->genIdx->setText(tr("Particle Generator Indices"));

LabelWidget *capLabel = LabelWidget::newWithText(_E(1)_E(D) + tr("Behavior"), &area());
capLabel->margins().setTop("gap");

Expand All @@ -179,7 +147,7 @@ RendererSettingsDialog::RendererSettingsDialog(String const &name)
layout << *fovLabel << *d->fov;

// Label for the tech caps.
layout.setCellAlignment(Vector2i(0, 2), ui::AlignTopLeft);
layout.setCellAlignment(Vector2i(0, 2), ui::AlignLeft);
layout.append(*capLabel, 2);

layout
Expand Down
3 changes: 1 addition & 2 deletions doomsday/client/src/ui/editors/rendererappearanceeditor.cpp
Expand Up @@ -122,8 +122,7 @@ DENG2_OBSERVES(App, GameChange)

CVarToggleWidget *addToggle(char const *cvar, String const &label)
{
CVarToggleWidget *w = new CVarToggleWidget(cvar);
w->setText(label);
CVarToggleWidget *w = new CVarToggleWidget(cvar, label);
_group->add(w);
_layout << *w;
return w;
Expand Down
5 changes: 4 additions & 1 deletion doomsday/client/src/ui/widgets/cvartogglewidget.cpp
Expand Up @@ -34,8 +34,11 @@ DENG2_PIMPL_NOREF(CVarToggleWidget)
}
};

CVarToggleWidget::CVarToggleWidget(char const *cvarPath) : d(new Instance)
CVarToggleWidget::CVarToggleWidget(char const *cvarPath, String const &labelText)
: d(new Instance)
{
setText(labelText);

d->cvar = cvarPath;
updateFromCVar();

Expand Down
74 changes: 74 additions & 0 deletions doomsday/client/src/ui/widgets/gridpopupwidget.cpp
@@ -0,0 +1,74 @@
/** @file gridpopupwidget.cpp
*
* @authors Copyright (c) 2013 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#include "ui/widgets/gridpopupwidget.h"

#include "GridLayout"
#include "DialogContentStylist"

using namespace de;

DENG2_PIMPL_NOREF(GridPopupWidget)
{
DialogContentStylist stylist;
GuiWidget *container;
GridLayout layout;
};

GridPopupWidget::GridPopupWidget(String const &name)
: PopupWidget(name), d(new Instance)
{
setOpeningDirection(ui::Up);

d->container = new GuiWidget;
setContent(d->container);

d->stylist.setContainer(*d->container);

// Initialize the layout.
Rule const &gap = style().rules().rule("gap");
d->layout.setLeftTop(d->container->rule().left() + gap,
d->container->rule().top() + gap);
d->layout.setGridSize(2, 0);
d->layout.setColumnAlignment(0, ui::AlignRight);
}

GridLayout &GridPopupWidget::layout()
{
return d->layout;
}

GridPopupWidget &GridPopupWidget::operator << (GuiWidget *widget)
{
d->container->add(widget);
d->layout << *widget;
return *this;
}

GridPopupWidget &GridPopupWidget::operator << (Rule const &rule)
{
d->layout << rule;
return *this;
}

void GridPopupWidget::commit()
{
Rule const &gap = style().rules().rule("gap");
d->container->rule().setSize(d->layout.width() + gap * 2,
d->layout.height() + gap * 2);
}

0 comments on commit df614d6

Please sign in to comment.