diff --git a/doomsday/client/include/ui/dialogs/gamesdialog.h b/doomsday/client/include/ui/dialogs/gamesdialog.h index 05891cae5f..0e00cf566c 100644 --- a/doomsday/client/include/ui/dialogs/gamesdialog.h +++ b/doomsday/client/include/ui/dialogs/gamesdialog.h @@ -29,10 +29,17 @@ class GamesDialog : public de::DialogWidget Q_OBJECT public: - GamesDialog(de::String const &name = "games"); + enum Mode { + ShowAll, + ShowSingleplayerOnly, + ShowMultiplayerOnly + }; + + GamesDialog(Mode mode = ShowAll, de::String const &name = "games"); public slots: void showSettings(); + void connectManually(); protected: void preparePanelForOpening(); diff --git a/doomsday/client/include/ui/dialogs/manualconnectiondialog.h b/doomsday/client/include/ui/dialogs/manualconnectiondialog.h index 8d809c68a0..d39e49d657 100644 --- a/doomsday/client/include/ui/dialogs/manualconnectiondialog.h +++ b/doomsday/client/include/ui/dialogs/manualconnectiondialog.h @@ -43,7 +43,6 @@ public slots: void queryOrConnect(); void contentChanged(); void validate(); - void disconnected(); protected: void finish(int result); diff --git a/doomsday/client/include/ui/widgets/gamefilterwidget.h b/doomsday/client/include/ui/widgets/gamefilterwidget.h index fba3bf7cdf..7dd4e9dec0 100644 --- a/doomsday/client/include/ui/widgets/gamefilterwidget.h +++ b/doomsday/client/include/ui/widgets/gamefilterwidget.h @@ -53,9 +53,9 @@ class GameFilterWidget : public de::GuiWidget, public de::IPersistent GameFilterWidget(de::String const &name = "gamefilter"); void useInvertedStyle(); + void setFilter(Filter flt); Filter filter() const; - SortOrder sortOrder() const; // Implements IPersistent. diff --git a/doomsday/client/include/ui/widgets/gameselectionwidget.h b/doomsday/client/include/ui/widgets/gameselectionwidget.h index 7a80b676a9..582edc7465 100644 --- a/doomsday/client/include/ui/widgets/gameselectionwidget.h +++ b/doomsday/client/include/ui/widgets/gameselectionwidget.h @@ -20,6 +20,7 @@ #define DENG_CLIENT_GAMESELECTIONWIDGET_H #include +#include #include #include @@ -46,6 +47,8 @@ class GameSelectionWidget : public de::ScrollAreaWidget, public de::IPersistent */ GameFilterWidget &filter(); + de::FoldPanelWidget *subsetFold(de::String const &name); + // Events. void update(); diff --git a/doomsday/client/src/ui/dialogs/gamesdialog.cpp b/doomsday/client/src/ui/dialogs/gamesdialog.cpp index a9b59c5ec0..3e5780387e 100644 --- a/doomsday/client/src/ui/dialogs/gamesdialog.cpp +++ b/doomsday/client/src/ui/dialogs/gamesdialog.cpp @@ -19,7 +19,7 @@ #include "ui/dialogs/gamesdialog.h" #include "ui/widgets/gameselectionwidget.h" #include "ui/dialogs/networksettingsdialog.h" - +#include "ui/dialogs/manualconnectiondialog.h" #include "CommandAction" #include @@ -28,9 +28,12 @@ using namespace de; DENG_GUI_PIMPL(GamesDialog) { + Mode mode; GameSelectionWidget *gameSel; //MenuWidget *list; - Instance(Public *i) : Base(i) + Instance(Public *i, Mode m) + : Base(i) + , mode(m) { self.area().add(gameSel = new GameSelectionWidget("games")); @@ -41,25 +44,62 @@ DENG_GUI_PIMPL(GamesDialog) } }; -GamesDialog::GamesDialog(String const &name) - : DialogWidget(name/*, WithHeading*/), d(new Instance(this)) +GamesDialog::GamesDialog(Mode mode, String const &name) + : DialogWidget(name/*, WithHeading*/) + , d(new Instance(this, mode)) { connect(d->gameSel, SIGNAL(gameSessionSelected()), this, SLOT(accept())); GridLayout layout(area().contentRule().left(), area().contentRule().top()); layout.setGridSize(1, 0); - d->gameSel->filter().rule().setInput(Rule::Width, d->gameSel->rule().width()); + if(d->mode == ShowAll) + { + // Include the filter in the layout. + d->gameSel->filter().rule().setInput(Rule::Width, d->gameSel->rule().width()); + layout << d->gameSel->filter(); - layout << d->gameSel->filter() << *d->gameSel; + d->gameSel->filter().setFilter(GameFilterWidget::AllGames); + } + else + { + // Select a suitable view as the user can't change the filter. + d->gameSel->filter().hide(); + d->gameSel->filter().enableStateSerialization(false); + d->gameSel->filter().setFilter(d->mode == ShowSingleplayerOnly? + GameFilterWidget::Singleplayer : + GameFilterWidget::Multiplayer); + + switch(d->mode) + { + case ShowSingleplayerOnly: + d->gameSel->subsetFold("available")->open(); + d->gameSel->subsetFold("incomplete")->close(); + break; + + case ShowMultiplayerOnly: + d->gameSel->subsetFold("multi")->open(); + break; + + default: + break; + } + } + layout << *d->gameSel; area().setContentSize(layout.width(), layout.height()); - buttons() - << new DialogButtonItem(Default | Accept, tr("Close")) - << new DialogButtonItem(Action | Id1, - style().images().image("gear"), - new SignalAction(this, SLOT(showSettings()))); + // Buttons appropriate for the mode: + buttons() << new DialogButtonItem(Default | Accept, tr("Close")); + + if(d->mode != ShowSingleplayerOnly) + { + buttons() << new DialogButtonItem(Action | Id2, tr("Connect Manually..."), + new SignalAction(this, SLOT(connectManually()))); + } + + buttons() << new DialogButtonItem(Action | Id1, style().images().image("gear"), + new SignalAction(this, SLOT(showSettings()))); } void GamesDialog::showSettings() @@ -70,6 +110,14 @@ void GamesDialog::showSettings() dlg->exec(root()); } +void GamesDialog::connectManually() +{ + ManualConnectionDialog *dlg = new ManualConnectionDialog; + dlg->setAnchorAndOpeningDirection(buttonWidget(Id2)->rule(), ui::Up); + dlg->setDeleteAfterDismissed(true); + dlg->exec(root()); +} + void GamesDialog::preparePanelForOpening() { DialogWidget::preparePanelForOpening(); diff --git a/doomsday/client/src/ui/dialogs/manualconnectiondialog.cpp b/doomsday/client/src/ui/dialogs/manualconnectiondialog.cpp index 3873c85aea..f6a97be393 100644 --- a/doomsday/client/src/ui/dialogs/manualconnectiondialog.cpp +++ b/doomsday/client/src/ui/dialogs/manualconnectiondialog.cpp @@ -132,7 +132,6 @@ ManualConnectionDialog::ManualConnectionDialog(String const &name) connect(&editor(), SIGNAL(enterPressed(QString)), this, SLOT(queryOrConnect())); connect(&editor(), SIGNAL(editorContentChanged()), this, SLOT(validate())); connect(&editor(), SIGNAL(editorContentChanged()), this, SLOT(contentChanged())); - connect(&ClientApp::serverLink(), SIGNAL(disconnected()), this, SLOT(disconnected())); updateLayout(); } @@ -202,11 +201,6 @@ void ManualConnectionDialog::validate() d->connectButton().enable(valid); } -void ManualConnectionDialog::disconnected() -{ - d->linkDiscoveryUpdate(ClientApp::serverLink()); -} - void ManualConnectionDialog::finish(int result) { if(result) diff --git a/doomsday/client/src/ui/widgets/gamefilterwidget.cpp b/doomsday/client/src/ui/widgets/gamefilterwidget.cpp index c22a6c0010..3899949e57 100644 --- a/doomsday/client/src/ui/widgets/gamefilterwidget.cpp +++ b/doomsday/client/src/ui/widgets/gamefilterwidget.cpp @@ -84,6 +84,15 @@ void GameFilterWidget::useInvertedStyle() d->sortLabel->setTextColor("inverted.text"); } +void GameFilterWidget::setFilter(Filter flt) +{ + ui::DataPos pos = d->tabs->items().findData(duint(flt)); + if(pos != ui::Data::InvalidPos) + { + d->tabs->setCurrent(pos); + } +} + GameFilterWidget::Filter GameFilterWidget::filter() const { return Filter(d->tabs->currentItem().data().toUInt()); diff --git a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp index 7f91583ab8..c4c85f8f47 100644 --- a/doomsday/client/src/ui/widgets/gameselectionwidget.cpp +++ b/doomsday/client/src/ui/widgets/gameselectionwidget.cpp @@ -557,6 +557,11 @@ GameFilterWidget &GameSelectionWidget::filter() return *d->filter; } +FoldPanelWidget *GameSelectionWidget::subsetFold(String const &name) +{ + return find(name)->maybeAs(); +} + void GameSelectionWidget::update() { d->addPendingGames();