From 19c2ea171de810445b924d76f642793fda102185 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 29 Dec 2023 02:16:18 +0100 Subject: [PATCH] Implement launcher window base functionality --- .../zwidget/widgets/listview/listview.h | 6 +++ .../ZWidget/src/widgets/listview/listview.cpp | 24 +++++++++ .../ZWidget/src/window/win32/win32window.cpp | 7 ++- src/common/widgets/launcherwindow.cpp | 49 +++++++++++++++++-- src/common/widgets/launcherwindow.h | 10 +++- 5 files changed, 89 insertions(+), 7 deletions(-) diff --git a/libraries/ZWidget/include/zwidget/widgets/listview/listview.h b/libraries/ZWidget/include/zwidget/widgets/listview/listview.h index 52cd5a7a2c..0d8f632cd9 100644 --- a/libraries/ZWidget/include/zwidget/widgets/listview/listview.h +++ b/libraries/ZWidget/include/zwidget/widgets/listview/listview.h @@ -3,6 +3,7 @@ #include "../../core/widget.h" #include +#include class ListView : public Widget { @@ -10,6 +11,11 @@ public: ListView(Widget* parent = nullptr); void AddItem(const std::string& text); + int GetSelectedItem() const { return selectedItem; } + + void Activate(); + + std::function OnActivated; protected: void OnPaint(Canvas* canvas) override; diff --git a/libraries/ZWidget/src/widgets/listview/listview.cpp b/libraries/ZWidget/src/widgets/listview/listview.cpp index ca3a22e7a4..6093d9d8e5 100644 --- a/libraries/ZWidget/src/widgets/listview/listview.cpp +++ b/libraries/ZWidget/src/widgets/listview/listview.cpp @@ -12,6 +12,12 @@ void ListView::AddItem(const std::string& text) Update(); } +void ListView::Activate() +{ + if (OnActivated) + OnActivated(); +} + void ListView::OnPaint(Canvas* canvas) { double y = 20.0; @@ -47,10 +53,24 @@ void ListView::OnPaintFrame(Canvas* canvas) void ListView::OnMouseDown(const Point& pos, int key) { SetFocus(); + + if (key == IK_LeftMouse) + { + int index = (int)((pos.y - 5.0) / 20.0); + if (index >= 0 && (size_t)index < items.size()) + { + selectedItem = index; + Update(); + } + } } void ListView::OnMouseDoubleclick(const Point& pos, int key) { + if (key == IK_LeftMouse) + { + Activate(); + } } void ListView::OnKeyDown(EInputKey key) @@ -71,4 +91,8 @@ void ListView::OnKeyDown(EInputKey key) Update(); } } + else if (key == IK_Enter) + { + Activate(); + } } diff --git a/libraries/ZWidget/src/window/win32/win32window.cpp b/libraries/ZWidget/src/window/win32/win32window.cpp index 3a9b54c484..e041a1cc8b 100644 --- a/libraries/ZWidget/src/window/win32/win32window.cpp +++ b/libraries/ZWidget/src/window/win32/win32window.cpp @@ -69,7 +69,12 @@ Win32Window::Win32Window(DisplayWindowHost* windowHost) : WindowHost(windowHost) classdesc.lpfnWndProc = &Win32Window::WndProc; RegisterClassEx(&classdesc); - CreateWindowEx(WS_EX_APPWINDOW, L"ZWidgetWindow", L"", WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandle(0), this); + // Microsoft logic at its finest: + // WS_EX_DLGMODALFRAME hides the sysmenu icon + // WS_CAPTION shows the caption (yay! actually a flag that does what it says it does!) + // WS_SYSMENU shows the min/max/close buttons + // WS_THICKFRAME makes the window resizable + CreateWindowEx(WS_EX_APPWINDOW | WS_EX_DLGMODALFRAME, L"ZWidgetWindow", L"", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 0, 0, 100, 100, 0, 0, GetModuleHandle(0), this); /* RAWINPUTDEVICE rid; diff --git a/src/common/widgets/launcherwindow.cpp b/src/common/widgets/launcherwindow.cpp index 655457f1ac..e37edd523f 100644 --- a/src/common/widgets/launcherwindow.cpp +++ b/src/common/widgets/launcherwindow.cpp @@ -20,16 +20,16 @@ int LauncherWindow::ExecModal(WadStuff* wads, int numwads, int defaultiwad, int* double windowWidth = 615.0; double windowHeight = 668.0; - auto launcher = new LauncherWindow(wads, numwads, defaultiwad, autoloadflags); + auto launcher = std::make_unique(wads, numwads, defaultiwad, autoloadflags); launcher->SetFrameGeometry((screenSize.width - windowWidth) * 0.5, (screenSize.height - windowHeight) * 0.5, windowWidth, windowHeight); launcher->Show(); DisplayWindow::RunLoop(); - return 0; + return launcher->ExecResult; } -LauncherWindow::LauncherWindow(WadStuff* wads, int numwads, int defaultiwad, int* autoloadflags) : Widget(nullptr, WidgetType::Window) +LauncherWindow::LauncherWindow(WadStuff* wads, int numwads, int defaultiwad, int* autoloadflags) : Widget(nullptr, WidgetType::Window), AutoloadFlags(autoloadflags) { SetWindowBackground(Colorf::fromRgba8(51, 51, 51)); SetWindowBorderColor(Colorf::fromRgba8(51, 51, 51)); @@ -53,6 +53,10 @@ LauncherWindow::LauncherWindow(WadStuff* wads, int numwads, int defaultiwad, int ExitButton = new PushButton(this); GamesList = new ListView(this); + PlayButton->OnClick = [=]() { OnPlayButtonClicked(); }; + ExitButton->OnClick = [=]() { OnExitButtonClicked(); }; + GamesList->OnActivated = [=]() { OnGamesListActivated(); }; + SelectLabel->SetText("Select which game file (IWAD) to run."); PlayButton->SetText("Play Game"); ExitButton->SetText("Exit"); @@ -72,10 +76,11 @@ LauncherWindow::LauncherWindow(WadStuff* wads, int numwads, int defaultiwad, int WelcomeLabel->SetText(welcomeText.GetChars()); VersionLabel->SetText(versionText.GetChars()); - int flags = *autoloadflags; FullscreenCheckbox->SetChecked(vid_fullscreen); - DisableAutoloadCheckbox->SetChecked(flags & 1); DontAskAgainCheckbox->SetChecked(!queryiwad); + + int flags = *autoloadflags; + DisableAutoloadCheckbox->SetChecked(flags & 1); LightsCheckbox->SetChecked(flags & 2); BrightmapsCheckbox->SetChecked(flags & 4); WidescreenCheckbox->SetChecked(flags & 8); @@ -96,6 +101,40 @@ LauncherWindow::LauncherWindow(WadStuff* wads, int numwads, int defaultiwad, int } Logo->SetImage(Image::LoadResource("widgets/banner.png")); + + GamesList->SetFocus(); +} + +void LauncherWindow::OnClose() +{ + OnExitButtonClicked(); +} + +void LauncherWindow::OnPlayButtonClicked() +{ + vid_fullscreen = FullscreenCheckbox->GetChecked(); + queryiwad = !DontAskAgainCheckbox->GetChecked(); + + int flags = 0; + if (DisableAutoloadCheckbox->GetChecked()) flags |= 1; + if (LightsCheckbox->GetChecked()) flags |= 2; + if (BrightmapsCheckbox->GetChecked()) flags |= 4; + if (WidescreenCheckbox->GetChecked()) flags |= 8; + *AutoloadFlags = flags; + + ExecResult = GamesList->GetSelectedItem(); + DisplayWindow::ExitLoop(); +} + +void LauncherWindow::OnExitButtonClicked() +{ + ExecResult = -1; + DisplayWindow::ExitLoop(); +} + +void LauncherWindow::OnGamesListActivated() +{ + OnPlayButtonClicked(); } void LauncherWindow::OnGeometryChanged() diff --git a/src/common/widgets/launcherwindow.h b/src/common/widgets/launcherwindow.h index 4ca1279029..d367aaafcb 100644 --- a/src/common/widgets/launcherwindow.h +++ b/src/common/widgets/launcherwindow.h @@ -14,9 +14,14 @@ class LauncherWindow : public Widget public: static int ExecModal(WadStuff* wads, int numwads, int defaultiwad, int* autoloadflags); -private: LauncherWindow(WadStuff* wads, int numwads, int defaultiwad, int* autoloadflags); +private: + void OnPlayButtonClicked(); + void OnExitButtonClicked(); + void OnGamesListActivated(); + + void OnClose() override; void OnGeometryChanged() override; ImageBox* Logo = nullptr; @@ -34,4 +39,7 @@ private: PushButton* PlayButton = nullptr; PushButton* ExitButton = nullptr; ListView* GamesList = nullptr; + + int* AutoloadFlags = nullptr; + int ExecResult = -1; };