From 527321c44b24c0136ed598a8d28e318836e90307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Wed, 16 Mar 2016 22:19:42 +0200 Subject: [PATCH] UI|Home: Working on selected packages in the Packages dialog --- .../include/ui/widgets/packageswidget.h | 11 ++ .../client/src/ui/dialogs/packagesdialog.cpp | 111 +++++++++++++----- .../client/src/ui/widgets/packageswidget.cpp | 31 +++-- 3 files changed, 109 insertions(+), 44 deletions(-) diff --git a/doomsday/apps/client/include/ui/widgets/packageswidget.h b/doomsday/apps/client/include/ui/widgets/packageswidget.h index b9cdf9d8f2..43131e98bc 100644 --- a/doomsday/apps/client/include/ui/widgets/packageswidget.h +++ b/doomsday/apps/client/include/ui/widgets/packageswidget.h @@ -29,9 +29,20 @@ */ class PackagesWidget : public de::GuiWidget, public de::IPersistent { +public: + /// Determines whether an item should be shown as highlighted or not. + class IPackageStatus + { + public: + virtual ~IPackageStatus() {} + virtual bool isPackageHighlighted(de::String const &packageId) const = 0; + }; + public: PackagesWidget(de::String const &name = ""); + void setPackageStatus(IPackageStatus const &packageStatus); + void setColorTheme(ColorTheme unselectedItem, ColorTheme selectedItem, ColorTheme loadedUnselectedItem, ColorTheme loadedSelectedItem); diff --git a/doomsday/apps/client/src/ui/dialogs/packagesdialog.cpp b/doomsday/apps/client/src/ui/dialogs/packagesdialog.cpp index b2bf8d4994..7e7df841fd 100644 --- a/doomsday/apps/client/src/ui/dialogs/packagesdialog.cpp +++ b/doomsday/apps/client/src/ui/dialogs/packagesdialog.cpp @@ -37,23 +37,29 @@ using namespace de; DENG_GUI_PIMPL(PackagesDialog) , public ChildWidgetOrganizer::IWidgetFactory +, public PackagesWidget::IPackageStatus { + StringList selectedPackages; + LabelWidget *nothingSelected; HomeMenuWidget *menu; PackagesWidget *browser; /** - * Information about a selected package. + * Information about a selected package. If the package file is not found, only + * the ID is known. */ - struct PackageItem : public ui::Item + class SelectedPackageItem : public ui::Item { - File const *file; - Record const *info; - - PackageItem(File const &packFile) - : file(&packFile) - , info(&file->objectNamespace().subrecord(Package::VAR_PACKAGE)) + public: + SelectedPackageItem(String const &packageId) { - setData(QString(info->gets("ID"))); + setData(packageId); + + _file = App::packageLoader().select(packageId); + if(_file) + { + _info = &_file->objectNamespace().subrecord(Package::VAR_PACKAGE); + } } String packageId() const @@ -61,22 +67,36 @@ DENG_GUI_PIMPL(PackagesDialog) return data().toString(); } - void setFile(File const &packFile) + Record const *info() const + { + return _info; + } + + File const *packageFile() const + { + return _file; + } + + /*void setFile(File const &packFile) { file = &packFile; info = &file->objectNamespace().subrecord(Package::VAR_PACKAGE); notifyChange(); - } + }*/ + + private: + File const *_file = nullptr; + Record const *_info = nullptr; }; /** * Widget showing information about a selected package, with a button for dragging * the item up and down. */ - class Widget : public HomeItemWidget + class SelectedPackageWidget : public HomeItemWidget { public: - Widget(PackageItem const &item) + SelectedPackageWidget(SelectedPackageItem const &item) : _item(&item) { useColorTheme(Normal, Inverted); @@ -88,7 +108,7 @@ DENG_GUI_PIMPL(PackagesDialog) _infoButton->setPopup([this] (PopupButtonWidget const &) { auto *pop = new PopupMenuWidget; - pop->useInfoStyle(); + pop->setColorTheme(Inverted); pop->items() << new ui::SubwidgetItem( tr("Info"), ui::Down, [this] () -> PopupWidget * { return makeInfoPopup(); }); @@ -182,7 +202,14 @@ DENG_GUI_PIMPL(PackagesDialog) void updateContents() { - label().setText(_item->info->gets("title")); + if(_item->info()) + { + label().setText(_item->info()->gets("title")); + } + else + { + label().setText(_item->packageId()); + } /* _subtitle->setText(packageId()); @@ -220,20 +247,27 @@ DENG_GUI_PIMPL(PackagesDialog) PopupWidget *makeInfoPopup() const { auto *pop = new DocumentPopupWidget; - pop->document().setText(QString(_E(1) "%1" _E(.) "\n%2\n" - _E(l) "Version: " _E(.) "%3\n" - _E(l) "License: " _E(.)_E(>) "%4" _E(<) - _E(l) "\nFile: " _E(.)_E(>)_E(C) "%5") - .arg(_item->info->gets("title")) - .arg(packageId()) - .arg(_item->info->gets("version")) - .arg(_item->info->gets("license")) - .arg(_item->file->description())); + if(auto const *info = _item->info()) + { + pop->document().setText(QString(_E(1) "%1" _E(.) "\n%2\n" + _E(l) "Version: " _E(.) "%3\n" + _E(l) "License: " _E(.)_E(>) "%4" _E(<) + _E(l) "\nFile: " _E(.)_E(>)_E(C) "%5") + .arg(info->gets("title")) + .arg(packageId()) + .arg(info->gets("version")) + .arg(info->gets("license")) + .arg(_item->packageFile()->description())); + } + else + { + pop->document().setText(packageId()); + } return pop; } private: - PackageItem const *_item; + SelectedPackageItem const *_item; //LabelWidget *_title; //LabelWidget *_subtitle; //QList _tags; @@ -244,6 +278,13 @@ DENG_GUI_PIMPL(PackagesDialog) Instance(Public *i) : Base(i) { + nothingSelected = new LabelWidget; + nothingSelected->setText(_E(b) + tr("Nothing Selected")); + nothingSelected->setFont("heading"); + nothingSelected->setOpacity(0.5f); + nothingSelected->rule().setRect(self.leftArea().rule()); + self.leftArea().add(nothingSelected); + // Currently selected packages. self.leftArea().add(menu = new HomeMenuWidget); menu->layout().setRowPadding(Const(0)); @@ -256,7 +297,8 @@ DENG_GUI_PIMPL(PackagesDialog) // Package browser. self.rightArea().add(browser = new PackagesWidget); - browser->setColorTheme(Normal, Inverted, Normal, Inverted); + browser->setPackageStatus(*this); + browser->setColorTheme(Normal, Normal, Normal, Normal); browser->rule() .setInput(Rule::Left, self.rightArea().contentRule().left()) .setInput(Rule::Top, self.rightArea().contentRule().top()) @@ -268,23 +310,28 @@ DENG_GUI_PIMPL(PackagesDialog) { menu->items().clear(); - auto loaded = App::packageLoader().loadedPackagesAsFilesInPackageOrder(); - // Remove from the list those packages that are no longer listed. - for(File const *packFile : loaded) + for(String packageId : selectedPackages) { - menu->items() << new PackageItem(*packFile); + menu->items() << new SelectedPackageItem(packageId); } + + nothingSelected->setOpacity(menu->items().isEmpty()? .5f : 0.f, 0.4); } GuiWidget *makeItemWidget(ui::Item const &item, GuiWidget const *) { - return new Widget(item.as()); + return new SelectedPackageWidget(item.as()); } void updateItemWidget(GuiWidget &widget, ui::Item const &) { - widget.as().updateContents(); + widget.as().updateContents(); + } + + bool isPackageHighlighted(String const &packageId) const + { + return selectedPackages.contains(packageId); } }; diff --git a/doomsday/apps/client/src/ui/widgets/packageswidget.cpp b/doomsday/apps/client/src/ui/widgets/packageswidget.cpp index 7d62656b04..b311c3eff9 100644 --- a/doomsday/apps/client/src/ui/widgets/packageswidget.cpp +++ b/doomsday/apps/client/src/ui/widgets/packageswidget.cpp @@ -37,6 +37,16 @@ using namespace de; static String const VAR_TITLE("title"); static String const VAR_TAGS ("tags"); +struct PackageLoadStatus : public PackagesWidget::IPackageStatus +{ + bool isPackageHighlighted(String const &packageId) const + { + return App::packageLoader().isLoaded(packageId); + } +}; + +static PackageLoadStatus isPackageLoaded; + DENG_GUI_PIMPL(PackagesWidget) , public ChildWidgetOrganizer::IFilter , public ChildWidgetOrganizer::IWidgetFactory @@ -45,6 +55,7 @@ DENG_GUI_PIMPL(PackagesWidget) ButtonWidget *clearSearch; HomeMenuWidget *menu; QStringList filterTerms; + IPackageStatus const *packageStatus = &isPackageLoaded; GuiWidget::ColorTheme unselectedItem = GuiWidget::Normal; GuiWidget::ColorTheme selectedItem = GuiWidget::Normal; GuiWidget::ColorTheme loadedUnselectedItem = GuiWidget::Inverted; @@ -227,31 +238,22 @@ DENG_GUI_PIMPL(PackagesWidget) String auxColor = "accent"; - if(isLoaded()) + if(_owner.d->packageStatus->isPackageHighlighted(packageId())) { _loadButton->setText(tr("Unload")); - _loadButton->useNormalStyle(); + _loadButton->setColorTheme(invertColorTheme(_owner.d->loadedSelectedItem)); icon().setImageColor(style().colors().colorf("accent")); - //useInvertedStyle(); useColorTheme(_owner.d->loadedUnselectedItem, _owner.d->loadedSelectedItem); - //_loadButton->setTextColor("altaccent"); - //_loadButton->setBorderColor("altaccent"); - //_title->setFont("choice.selected"); auxColor = "background"; } else { _loadButton->setText(tr("Load")); - _loadButton->useInfoStyle(); + _loadButton->setColorTheme(invertColorTheme(_owner.d->selectedItem)); icon().setImageColor(style().colors().colorf("text")); - //useNormalStyle(); useColorTheme(_owner.d->unselectedItem, _owner.d->selectedItem); - //_loadButton->setTextColor("text"); - //_loadButton->setBorderColor("text"); - //_title->setFont("default"); } - //_subtitle->setTextColor(auxColor); for(ButtonWidget *b : _tags) { updateTagButtonStyle(b, auxColor); @@ -452,6 +454,11 @@ PackagesWidget::PackagesWidget(String const &name) refreshPackages(); } +void PackagesWidget::setPackageStatus(IPackageStatus const &packageStatus) +{ + d->packageStatus = &packageStatus; +} + void PackagesWidget::setColorTheme(ColorTheme unselectedItem, ColorTheme selectedItem, ColorTheme loadedUnselectedItem, ColorTheme loadedSelectedItem) {