diff --git a/doomsday/apps/client/include/ui/widgets/homeitemwidget.h b/doomsday/apps/client/include/ui/widgets/homeitemwidget.h index 7b04659bd2..745079bd58 100644 --- a/doomsday/apps/client/include/ui/widgets/homeitemwidget.h +++ b/doomsday/apps/client/include/ui/widgets/homeitemwidget.h @@ -40,8 +40,10 @@ class HomeItemWidget : public de::GuiWidget virtual void setSelected(bool selected); bool isSelected() const; - void useInvertedStyle(); void useNormalStyle(); + void useInvertedStyle(); + void useColorTheme(ColorTheme style); + void useColorTheme(ColorTheme unselected, ColorTheme selected); signals: void mouseActivity(); diff --git a/doomsday/apps/client/include/ui/widgets/packageswidget.h b/doomsday/apps/client/include/ui/widgets/packageswidget.h index bf1d31e620..b9cdf9d8f2 100644 --- a/doomsday/apps/client/include/ui/widgets/packageswidget.h +++ b/doomsday/apps/client/include/ui/widgets/packageswidget.h @@ -32,6 +32,9 @@ class PackagesWidget : public de::GuiWidget, public de::IPersistent public: PackagesWidget(de::String const &name = ""); + void setColorTheme(ColorTheme unselectedItem, ColorTheme selectedItem, + ColorTheme loadedUnselectedItem, ColorTheme loadedSelectedItem); + // Implements IPersistent. void operator >> (de::PersistentState &toState) const; void operator << (de::PersistentState const &fromState); diff --git a/doomsday/apps/client/src/ui/dialogs/packagesdialog.cpp b/doomsday/apps/client/src/ui/dialogs/packagesdialog.cpp index a1cbfe823d..b2bf8d4994 100644 --- a/doomsday/apps/client/src/ui/dialogs/packagesdialog.cpp +++ b/doomsday/apps/client/src/ui/dialogs/packagesdialog.cpp @@ -18,6 +18,8 @@ #include "ui/dialogs/packagesdialog.h" #include "ui/widgets/packageswidget.h" +#include "ui/widgets/homeitemwidget.h" +#include "ui/widgets/homemenuwidget.h" #include "clientapp.h" #include @@ -26,18 +28,21 @@ #include #include #include +#include +#include #include +#include using namespace de; DENG_GUI_PIMPL(PackagesDialog) , public ChildWidgetOrganizer::IWidgetFactory { - MenuWidget *menu; + HomeMenuWidget *menu; PackagesWidget *browser; /** - * Information about an available package. + * Information about a selected package. */ struct PackageItem : public ui::Item { @@ -51,6 +56,11 @@ DENG_GUI_PIMPL(PackagesDialog) setData(QString(info->gets("ID"))); } + String packageId() const + { + return data().toString(); + } + void setFile(File const &packFile) { file = &packFile; @@ -60,47 +70,34 @@ DENG_GUI_PIMPL(PackagesDialog) }; /** - * Widget showing information about a package and containing buttons for manipulating - * the package. + * Widget showing information about a selected package, with a button for dragging + * the item up and down. */ - class Widget : public GuiWidget + class Widget : public HomeItemWidget { - private: - /// Action to load or unload a package. - struct LoadAction : public Action + public: + Widget(PackageItem const &item) + : _item(&item) { - Widget &owner; - - LoadAction(Widget &widget) : owner(widget) {} + useColorTheme(Normal, Inverted); - void trigger() + _infoButton = new PopupButtonWidget; + _infoButton->setText(tr("...")); + _infoButton->setFont("small"); + _infoButton->margins().setTopBottom("unit"); + _infoButton->setPopup([this] (PopupButtonWidget const &) { - Action::trigger(); - auto &loader = App::packageLoader(); - if(loader.isLoaded(owner.packageId())) - { - loader.unload(owner.packageId()); - } - else - { - try - { - loader.load(owner.packageId()); - } - catch(Error const &er) - { - LOG_RES_ERROR("Package \"" + owner.packageId() + - "\" could not be loaded: " + er.asText()); - } - } - owner.updateContents(); + auto *pop = new PopupMenuWidget; + pop->useInfoStyle(); + pop->items() << new ui::SubwidgetItem( + tr("Info"), ui::Down, + [this] () -> PopupWidget * { return makeInfoPopup(); }); + return pop; } - }; + , ui::Down); + addButton(_infoButton); - public: - Widget(PackageItem const &item) - : _item(&item) - { + /* add(_title = new LabelWidget); _title->setSizePolicy(ui::Fixed, ui::Expand); _title->setAlignment(ui::AlignLeft); @@ -152,8 +149,9 @@ DENG_GUI_PIMPL(PackagesDialog) rule().setInput(Rule::Width, rule("dialog.packages.width")) .setInput(Rule::Height, _title->rule().height() + _subtitle->rule().height() + _tags.at(0)->rule().height()); + */ } - +/* void createTagButtons() { SequentialLayout layout(_subtitle->rule().left(), @@ -180,11 +178,13 @@ DENG_GUI_PIMPL(PackagesDialog) tag->setFont("small"); tag->setTextColor(color); tag->set(Background(Background::Rounded, style().colors().colorf(color), 6)); - } + }*/ void updateContents() { - _title->setText(_item->info->gets("title")); + label().setText(_item->info->gets("title")); + + /* _subtitle->setText(packageId()); String auxColor = "accent"; @@ -209,17 +209,12 @@ DENG_GUI_PIMPL(PackagesDialog) for(ButtonWidget *b : _tags) { updateTagButtonStyle(b, auxColor); - } - } - - bool isLoaded() const - { - return App::packageLoader().isLoaded(packageId()); + }*/ } String packageId() const { - return _item->info->gets("ID"); + return _item->packageId(); } PopupWidget *makeInfoPopup() const @@ -239,65 +234,46 @@ DENG_GUI_PIMPL(PackagesDialog) private: PackageItem const *_item; - LabelWidget *_title; - LabelWidget *_subtitle; - QList _tags; - ButtonWidget *_loadButton; + //LabelWidget *_title; + //LabelWidget *_subtitle; + //QList _tags; PopupButtonWidget *_infoButton; + //ButtonWidget *_loadButton; + //PopupButtonWidget *_infoButton; }; Instance(Public *i) : Base(i) { // Currently selected packages. - self.leftArea().add(menu = new MenuWidget); - menu->enableScrolling(false); // dialog content already scrolls - menu->enablePageKeys(false); - menu->setGridSize(1, ui::Expand, 0, ui::Expand); + self.leftArea().add(menu = new HomeMenuWidget); + menu->layout().setRowPadding(Const(0)); menu->rule() - .setInput(Rule::Left, self.leftArea().contentRule().left()) - .setInput(Rule::Top, self.leftArea().contentRule().top()); + .setInput(Rule::Left, self.leftArea().contentRule().left()) + .setInput(Rule::Top, self.leftArea().contentRule().top()) + .setInput(Rule::Width, rule("dialog.packages.width")); menu->organizer().setWidgetFactory(*this); + self.leftArea().enableIndicatorDraw(true); // Package browser. self.rightArea().add(browser = new PackagesWidget); + browser->setColorTheme(Normal, Inverted, Normal, Inverted); browser->rule() .setInput(Rule::Left, self.rightArea().contentRule().left()) .setInput(Rule::Top, self.rightArea().contentRule().top()) .setInput(Rule::Width, menu->rule().width()); + self.rightArea().enableIndicatorDraw(true); } void populate() { - StringList packages = App::packageLoader().findAllPackages(); - qSort(packages); + menu->items().clear(); - // Remove from the list those packages that are no longer listed. - for(ui::DataPos i = 0; i < menu->items().size(); ++i) - { - if(!packages.contains(menu->items().at(i).data().toString())) - { - menu->items().remove(i--); - } - } + auto loaded = App::packageLoader().loadedPackagesAsFilesInPackageOrder(); - // Add/update the listed packages. - for(String const &path : packages) + // Remove from the list those packages that are no longer listed. + for(File const *packFile : loaded) { - File const &pack = App::rootFolder().locate(path); - - // Core packages are mandatory and thus omitted. - if(Package::tags(pack).contains("core")) continue; - - // Is this already in the list? - ui::DataPos pos = menu->items().findData(pack.objectNamespace().gets("package.ID")); - if(pos != ui::Data::InvalidPos) - { - menu->items().at(pos).as().setFile(pack); - } - else - { - menu->items() << new PackageItem(pack); - } + menu->items() << new PackageItem(*packFile); } } diff --git a/doomsday/apps/client/src/ui/home/multiplayercolumnwidget.cpp b/doomsday/apps/client/src/ui/home/multiplayercolumnwidget.cpp index 9561cab6f9..16d1a9ff37 100644 --- a/doomsday/apps/client/src/ui/home/multiplayercolumnwidget.cpp +++ b/doomsday/apps/client/src/ui/home/multiplayercolumnwidget.cpp @@ -218,6 +218,9 @@ MultiplayerColumnWidget::MultiplayerColumnWidget() : ColumnWidget("multiplayer-column") , d(new Instance(this)) { + d->mode = DiscoverUsingMaster; + d->link().discoverUsingMaster(); + scrollArea().setContentSize(maximumContentWidth(), header().rule().height() + rule("gap") + diff --git a/doomsday/apps/client/src/ui/widgets/homeitemwidget.cpp b/doomsday/apps/client/src/ui/widgets/homeitemwidget.cpp index 7edeac1471..88f615eff9 100644 --- a/doomsday/apps/client/src/ui/widgets/homeitemwidget.cpp +++ b/doomsday/apps/client/src/ui/widgets/homeitemwidget.cpp @@ -205,21 +205,45 @@ bool HomeItemWidget::isSelected() const return d->selected; } +void HomeItemWidget::useNormalStyle() +{ + useColorTheme(Normal); +} + void HomeItemWidget::useInvertedStyle() { - d->bgColor = "accent"; - d->textColor = "inverted.accent"; - d->selectedBgColor = "accent"; - d->selectedTextColor = "inverted.text"; - d->updateColors(); + useColorTheme(Inverted); } -void HomeItemWidget::useNormalStyle() +void HomeItemWidget::useColorTheme(ColorTheme style) { - d->bgColor = "transparent"; - d->textColor = "text"; - d->selectedBgColor = "background"; - d->selectedTextColor = "text"; + useColorTheme(style, style); +} + +void HomeItemWidget::useColorTheme(ColorTheme unselected, ColorTheme selected) +{ + if(unselected == Inverted) + { + d->bgColor = "accent"; + d->textColor = "inverted.accent"; + } + else + { + d->bgColor = "transparent"; + d->textColor = "text"; + } + + if(selected == Inverted) + { + d->selectedBgColor = "accent"; + d->selectedTextColor = "inverted.text"; + } + else + { + d->selectedBgColor = "background"; + d->selectedTextColor = "text"; + } + d->updateColors(); } diff --git a/doomsday/apps/client/src/ui/widgets/packageswidget.cpp b/doomsday/apps/client/src/ui/widgets/packageswidget.cpp index c67970efa7..7d62656b04 100644 --- a/doomsday/apps/client/src/ui/widgets/packageswidget.cpp +++ b/doomsday/apps/client/src/ui/widgets/packageswidget.cpp @@ -45,6 +45,10 @@ DENG_GUI_PIMPL(PackagesWidget) ButtonWidget *clearSearch; HomeMenuWidget *menu; QStringList filterTerms; + GuiWidget::ColorTheme unselectedItem = GuiWidget::Normal; + GuiWidget::ColorTheme selectedItem = GuiWidget::Normal; + GuiWidget::ColorTheme loadedUnselectedItem = GuiWidget::Inverted; + GuiWidget::ColorTheme loadedSelectedItem = GuiWidget::Inverted; /** * Information about an available package. @@ -228,7 +232,8 @@ DENG_GUI_PIMPL(PackagesWidget) _loadButton->setText(tr("Unload")); _loadButton->useNormalStyle(); icon().setImageColor(style().colors().colorf("accent")); - useInvertedStyle(); + //useInvertedStyle(); + useColorTheme(_owner.d->loadedUnselectedItem, _owner.d->loadedSelectedItem); //_loadButton->setTextColor("altaccent"); //_loadButton->setBorderColor("altaccent"); //_title->setFont("choice.selected"); @@ -239,7 +244,8 @@ DENG_GUI_PIMPL(PackagesWidget) _loadButton->setText(tr("Load")); _loadButton->useInfoStyle(); icon().setImageColor(style().colors().colorf("text")); - useNormalStyle(); + //useNormalStyle(); + useColorTheme(_owner.d->unselectedItem, _owner.d->selectedItem); //_loadButton->setTextColor("text"); //_loadButton->setBorderColor("text"); //_title->setFont("default"); @@ -446,6 +452,17 @@ PackagesWidget::PackagesWidget(String const &name) refreshPackages(); } +void PackagesWidget::setColorTheme(ColorTheme unselectedItem, ColorTheme selectedItem, + ColorTheme loadedUnselectedItem, ColorTheme loadedSelectedItem) +{ + d->unselectedItem = unselectedItem; + d->selectedItem = selectedItem; + d->loadedUnselectedItem = loadedUnselectedItem; + d->loadedSelectedItem = loadedSelectedItem; + + d->populate(); +} + void PackagesWidget::operator >> (PersistentState &toState) const { if(name().isEmpty()) return;