From 63c814c8512d6f07248ab3593e4835e3e7f87336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Mon, 2 Sep 2019 09:13:38 +0300 Subject: [PATCH] Shell: Continuing work with the Shell UI --- doomsday/tools/shell/src/aboutdialog.cpp | 2 + doomsday/tools/shell/src/guishellapp.cpp | 5 +- doomsday/tools/shell/src/linkwindow.cpp | 78 +++++----- doomsday/tools/shell/src/linkwindow.h | 2 +- doomsday/tools/shell/src/preferences.cpp | 181 ++++++++--------------- 5 files changed, 109 insertions(+), 159 deletions(-) diff --git a/doomsday/tools/shell/src/aboutdialog.cpp b/doomsday/tools/shell/src/aboutdialog.cpp index ce29d7d448..c3c91e8a0a 100644 --- a/doomsday/tools/shell/src/aboutdialog.cpp +++ b/doomsday/tools/shell/src/aboutdialog.cpp @@ -10,6 +10,8 @@ AboutDialog::AboutDialog() { title().setText("Doomsday Shell"); + buttons() << new ButtonItem(Default | Accept, "OK"); + // QVBoxLayout *box = new QVBoxLayout; // setLayout(box); // box->setSizeConstraint(QLayout::SetFixedSize); diff --git a/doomsday/tools/shell/src/guishellapp.cpp b/doomsday/tools/shell/src/guishellapp.cpp index 44147f2f9c..855292f07d 100644 --- a/doomsday/tools/shell/src/guishellapp.cpp +++ b/doomsday/tools/shell/src/guishellapp.cpp @@ -339,7 +339,10 @@ void GuiShellApp::updateLocalServerMenu() void GuiShellApp::aboutShell() { -// AboutDialog().exec(); + auto *win = d->winSys->focusedWindow(); + auto *about = new AboutDialog; + about->setDeleteAfterDismissed(true); + about->exec(win->root()); } void GuiShellApp::showHelp() diff --git a/doomsday/tools/shell/src/linkwindow.cpp b/doomsday/tools/shell/src/linkwindow.cpp index e0b415068e..6c947758ba 100644 --- a/doomsday/tools/shell/src/linkwindow.cpp +++ b/doomsday/tools/shell/src/linkwindow.cpp @@ -23,19 +23,20 @@ #include "preferences.h" #include "errorlogdialog.h" -#include -#include -#include -#include +#include #include -#include +#include #include -#include +#include #include -#include +#include +#include #include #include #include +#include +#include +#include //#ifndef MACOSX //# define MENU_IN_LINK_WINDOW @@ -68,30 +69,27 @@ DE_PIMPL(LinkWindow) { GuiRootWidget root; LogBuffer logBuffer; - network::Link *link; + network::Link *link = nullptr; duint16 waitingForLocalPort = 0; Time startedWaitingAt; Timer waitTimeout; String linkName; NativePath errorLog; - GuiWidget *tools; -// ButtonWidget *statusButton; -// ButtonWidget *optionsButton; -// ButtonWidget *consoleButton; - TabWidget *pageTabs; - GuiWidget *newLocalServerPage; - GuiWidget *consolePage; + GuiWidget *tools = nullptr; + TabWidget *pageTabs = nullptr; + GuiWidget *newLocalServerPage = nullptr; + GuiWidget *consolePage = nullptr; List pages; - StatusWidget *status; - OptionsPage *options; + StatusWidget *status = nullptr; + OptionsPage *options = nullptr; StyledLogSinkFormatter logFormatter{LogEntry::Styled | LogEntry::OmitLevel}; - LogWidget *logWidget; - ServerCommandWidget *commandWidget; - LabelWidget *statusMessage; - LabelWidget *gameStatus; - LabelWidget *timeCounter; - LabelWidget *currentHost; -// QAction *stopAction; + LogWidget *logWidget = nullptr; + ServerCommandWidget *commandWidget = nullptr; + LabelWidget *statusMessage = nullptr; + LabelWidget *gameStatus = nullptr; + LabelWidget *timeCounter = nullptr; + LabelWidget *currentHost = nullptr; + PopupMenuWidget *menu = nullptr; #ifdef MENU_IN_LINK_WINDOW // QAction *disconnectAction; #endif @@ -99,15 +97,6 @@ DE_PIMPL(LinkWindow) Impl(Public &i) : Base(i) , root(&i) - , link(0) -// tools(0), -// statusButton(0), -// consoleButton(0), -// stack(0), - , status(0) -// gameStatus(0), -// timeCounter(0), -// currentHost(0) { // Configure the log buffer. logBuffer.setMaxEntryCount(50); // buffered here rather than appBuffer @@ -214,6 +203,15 @@ DE_PIMPL(LinkWindow) // Status bar. { + menu = &root.addNew(); + menu->items() + << new ui::ActionItem("About Doomsday Shell", [](){ GuiShellApp::app().aboutShell(); }); + auto *menuButton = &root.addNew(); + menuButton->setSizePolicy(ui::Expand, ui::Expand); + menuButton->setText("Menu"); + menuButton->setPopup(*menu, ui::Up); + // menuButton->setStyleImage("", menuButton->fontId()); + root.add(statusBar); statusMessage = new LabelWidget; @@ -251,6 +249,10 @@ DE_PIMPL(LinkWindow) .setInput(Rule::Right, root.viewRight()) .setInput(Rule::Bottom, root.viewBottom()) .setInput(Rule::Height, statusHeight); + + menuButton->rule() + .setInput(Rule::Right, root.viewRight()) + .setInput(Rule::Bottom, root.viewBottom()); } for (auto *page : pages) @@ -535,6 +537,8 @@ LinkWindow::LinkWindow(const String &id) connect(&d->waitTimeout, SIGNAL(timeout()), this, SLOT(checkFoundServers())); d->waitTimeout.start(); #endif + + setTitle("Disconnected"); } GuiRootWidget &LinkWindow::root() @@ -559,10 +563,10 @@ void LinkWindow::drawWindowContent() d->root.draw(); } -//void LinkWindow::setTitle(const QString &title) -//{ -// setWindowTitle(title + " - " + tr("Doomsday Shell")); -//} +void LinkWindow::setTitle(const String &title) +{ + BaseWindow::setTitle(title + " - Doomsday Shell"); +} bool LinkWindow::isConnected() const { diff --git a/doomsday/tools/shell/src/linkwindow.h b/doomsday/tools/shell/src/linkwindow.h index d54ea2f990..3bf219f4a7 100644 --- a/doomsday/tools/shell/src/linkwindow.h +++ b/doomsday/tools/shell/src/linkwindow.h @@ -38,7 +38,7 @@ class LinkWindow : public de::BaseWindow de::Vec2f windowContentSize() const override; void drawWindowContent() override; - // void setTitle(QString const &title); + void setTitle(const de::String &title); bool isConnected() const; diff --git a/doomsday/tools/shell/src/preferences.cpp b/doomsday/tools/shell/src/preferences.cpp index 35bf6924d5..d55c26bec9 100644 --- a/doomsday/tools/shell/src/preferences.cpp +++ b/doomsday/tools/shell/src/preferences.cpp @@ -3,7 +3,7 @@ #include "guishellapp.h" #include -#include +#include //#ifdef MACOSX //# define PREFS_APPLY_IMMEDIATELY @@ -13,123 +13,68 @@ using namespace de; DE_GUI_PIMPL(Preferences) { - FolderSelection * appFolder; - VariableToggleWidget *useCustomIwad; - FolderSelection * iwadFolder; + FolderSelection *appFolder; + ToggleWidget * useCustomIwad; + FolderSelection *iwadFolder; Impl(Public &i) : Base(i) { auto &cfg = Config::get(); - if (!cfg.has("Preferences.customIwad")) - { - cfg.set("Preferences.customIwad", false); - } - - // QGroupBox *fontGroup = new QGroupBox(tr("Console Font")); - // { - // mainLayout->addWidget(fontGroup); - - // fontDesc = new QLabel; - - // QPushButton *selFont = new QPushButton(tr("Select...")); - // selFont->setAutoDefault(false); - // QObject::connect(selFont, SIGNAL(clicked()), thisPublic, SLOT(selectFont())); - - // QHBoxLayout *fl = new QHBoxLayout; - // fl->addWidget(fontDesc, 1); - // fl->addWidget(selFont, 0); - // fontGroup->setLayout(fl); - // } - // updateFontDesc(); - - // QGroupBox *appGroup = new QGroupBox(tr("Server Location")); - // { - // mainLayout->addWidget(appGroup); - - //#ifdef MACOSX - // appFolder = new FolderSelection(tr("Doomsday.app Folder")); - // QLabel *info = new QLabel("" + tr("Shell needs to know where Doomsday.app is located " - // "to be able to start local servers. The server " - // "executable is located inside the Doomsday.app " - // "bundle.") + - // ""); - //#else - // appFolder = new FolderSelection(tr("Executable Folder")); - // QLabel *info = new QLabel("" + tr("The server executable in this folder " - // "is used for starting local servers.") + - // ""); - //#endif - // info->setWordWrap(true); - - // appFolder->setPath(convert(st.value("Preferences/appFolder").toString())); - - // QVBoxLayout *bl = new QVBoxLayout; - // bl->setSpacing(4); - // bl->addWidget(appFolder); - // bl->addWidget(info); - // appGroup->setLayout(bl); - // } - - // QGroupBox *group = new QGroupBox(tr("Game Data")); - // { - // mainLayout->addWidget(group); - - // useCustomIwad = new QCheckBox(tr("Use a custom IWAD folder")); - // useCustomIwad->setChecked(st.value("Preferences/customIwad", false).toBool()); - // useCustomIwad->setToolTip(tr("Doomsday's default IWAD folder can be configured\n" - // "using configuration files, environment variables,\n" - // "or command line options.")); - // Game Data options. + AutoRef dialogWidth = rule("unit") * 75; + + LabelWidget *appFolderInfo; +#if defined (MACOSX) + appFolder = &self().area().addNew("Doomsday.app Folder"); + appFolderInfo = + LabelWidget::newWithText("Shell needs to know where Doomsday.app is located " + "to be able to start local servers. The server " + "executable is located inside the Doomsday.app " + "bundle.", + &self().area()); +#else + appFolder = &self().area().addNew("Executable Folder"); + appFolderInfo = LabelWidget::newWithText("The server executable in this folder " + "is used for starting local servers.", + &self().area()); +#endif + appFolder->setPath(cfg.gets("Preferences.appFolder", "")); + appFolder->rule().setInput(Rule::Width, dialogWidth); - useCustomIwad = &self().area().addNew("Use a custom IWAD folder", - cfg["Preferences.customIwad"]); + appFolderInfo->setMaximumTextWidth(dialogWidth); + appFolderInfo->setAlignment(ui::AlignLeft); + appFolderInfo->setTextLineAlignment(ui::AlignLeft); + appFolderInfo->setFont("small"); + appFolderInfo->setTextColor("altaccent"); + + // Game Data options. + useCustomIwad = &self().area().addNew(); + useCustomIwad->setText("Use a custom IWAD folder"); + useCustomIwad->setActive(cfg.getb("Preferences.customIwad", false)); iwadFolder = &self().area().addNew("Select IWAD Folder"); - iwadFolder->rule().setInput(Rule::Width, rule("unit") * 75); + iwadFolder->rule().setInput(Rule::Width, dialogWidth); iwadFolder->setPath(cfg.gets("Preferences.iwadFolder", "")); - // QVBoxLayout *bl = new QVBoxLayout; - // bl->setSpacing(4); - // bl->addWidget(useCustomIwad); - // bl->addWidget(iwadFolder); - // QLabel *info = new QLabel("" + - // tr("Doomsday tries to locate game data such as " - // "IWAD files " - // "automatically, but that may fail " - // "if you have the files in a custom location.") + ""); - // QObject::connect(info, SIGNAL(linkActivated(QString)), &GuiShellApp::app(), SLOT(openWebAddress(QString))); - // info->setWordWrap(true); - // bl->addWidget(info); - // group->setLayout(bl); - // } - - // mainLayout->addStretch(1); - - //#ifndef PREFS_APPLY_IMMEDIATELY - - // // On macOS, changes to the preferences are applied immediately. - // // Other platforms use OK/Cancel buttons. - - // // Buttons. - // QDialogButtonBox *bbox = new QDialogButtonBox; - // mainLayout->addWidget(bbox); - // QPushButton *yes = bbox->addButton(tr("&OK"), QDialogButtonBox::YesRole); - // QPushButton *no = bbox->addButton(tr("&Cancel"), QDialogButtonBox::RejectRole); - // QObject::connect(yes, SIGNAL(clicked()), thisPublic, SLOT(accept())); - // QObject::connect(no, SIGNAL(clicked()), thisPublic, SLOT(reject())); - // yes->setDefault(true); - //#endif - - GridLayout layout(self().area().contentRule().left(), self().area().contentRule().top()); - layout.setGridSize(2, 0); - layout.setColumnAlignment(0, ui::AlignRight); - - LabelWidget::appendSeparatorWithText("Game Data", &self().area(), &layout); - layout << Const(0) << *useCustomIwad; - layout.append(*iwadFolder, 2); - - self().area().setContentSize(layout); + // QLabel *info = new QLabel("" + + // tr("Doomsday tries to locate game data such as " + // "IWAD files " + // "automatically, but that may fail " + // "if you have the files in a custom location.") + ""); + + + GridLayout layout(self().area().contentRule().left(), self().area().contentRule().top()); + layout.setGridSize(2, 0); + layout.setColumnAlignment(0, ui::AlignRight); + + LabelWidget::appendSeparatorWithText("Server Location", &self().area(), &layout); + layout.append(*appFolder, 2) + .append(*appFolderInfo, 2); + LabelWidget::appendSeparatorWithText("Game Data", &self().area(), &layout); + layout << Const(0) << *useCustomIwad; + layout.append(*iwadFolder, 2); + + self().area().setContentSize(layout); self().buttons() << new DialogButtonItem(Accept | Default, "Apply") @@ -163,12 +108,8 @@ Preferences::Preferences() , d(new Impl(*this)) { heading().setText("Preferences"); -// connect(d->useCustomIwad, SIGNAL(toggled(bool)), this, SLOT(validate())); -// connect(this, SIGNAL(accepted()), this, SLOT(saveState())); -//#ifdef PREFS_APPLY_IMMEDIATELY -// connect(d->iwadFolder, SIGNAL(selected()), this, SLOT(saveState())); -// connect(d->appFolder, SIGNAL(selected()), this, SLOT(saveState())); -//#endif + d->useCustomIwad->audienceForToggle() += [this]() { validate(); }; + audienceForAccept() += [this]() { saveState(); }; validate(); } @@ -179,7 +120,7 @@ de::NativePath Preferences::iwadFolder() { return cfg.gets("Preferences.iwadFolder", ""); } - return ""; + return {}; } //QFont Preferences::consoleFont() @@ -192,17 +133,17 @@ de::NativePath Preferences::iwadFolder() void Preferences::saveState() { - //auto &cfg = Config::get(); + auto &cfg = Config::get(); // st.setValue("Preferences/appFolder", convert(d->appFolder->path())); -// st.setValue("Preferences/customIwad", d->useCustomIwad->isChecked()); -// st.setValue("Preferences/iwadFolder", convert(d->iwadFolder->path())); -// st.setValue("Preferences/consoleFont", d->consoleFont.toString()); + cfg.set("Preferences.customIwad", d->useCustomIwad->isActive()); + cfg.set("Preferences.iwadFolder", d->iwadFolder->path().toString()); + // st.setValue("Preferences/consoleFont", d->consoleFont.toString()); // emit consoleFontChanged(); } void Preferences::validate() { - //d->iwadFolder->setEnabled(d->useCustomIwad->isChecked()); + d->iwadFolder->setEnabled(d->useCustomIwad->isActive()); }