Add tabs to the launcher window

This commit is contained in:
Magnus Norddahl 2024-01-10 13:52:48 +01:00 committed by Christoph Oelckers
parent 762ce6f14c
commit a0f52411d3
13 changed files with 592 additions and 331 deletions

View file

@ -39,6 +39,10 @@ public:
// Widget noncontent area
void SetNoncontentSizes(double left, double top, double right, double bottom);
double GetNoncontentLeft() const { return Noncontent.Left; }
double GetNoncontentTop() const { return Noncontent.Top; }
double GetNoncontentRight() const { return Noncontent.Right; }
double GetNoncontentBottom() const { return Noncontent.Bottom; }
// Widget frame box
Rect GetFrameGeometry() const;

View file

@ -91,6 +91,7 @@ void TabWidget::OnGeometryChanged()
TabBar::TabBar(Widget* parent) : Widget(parent)
{
SetNoncontentSizes(20.0, 0.0, 20.0, 0.0);
}
int TabBar::AddTab(const std::string& label)
@ -151,6 +152,9 @@ int TabBar::GetTabIndex(TabBarTab* tab)
void TabBar::OnPaintFrame(Canvas* canvas)
{
double w = GetFrameGeometry().width;
double h = GetFrameGeometry().height;
canvas->fillRect(Rect::xywh(0.0, 0.0, w, h), Colorf::fromRgba8(38, 38, 38));
}
void TabBar::OnGeometryChanged()
@ -160,7 +164,7 @@ void TabBar::OnGeometryChanged()
double x = 0.0;
for (TabBarTab* tab : Tabs)
{
double tabWidth = tab->GetPreferredWidth();
double tabWidth = tab->GetNoncontentLeft() + tab->GetPreferredWidth() + tab->GetNoncontentRight();
tab->SetFrameGeometry(Rect::xywh(x, 0.0, tabWidth, h));
x += tabWidth;
}
@ -170,6 +174,7 @@ void TabBar::OnGeometryChanged()
TabBarTab::TabBarTab(Widget* parent) : Widget(parent)
{
SetNoncontentSizes(15.0, 0.0, 15.0, 0.0);
}
void TabBarTab::SetText(const std::string& text)
@ -228,6 +233,16 @@ double TabBarTab::GetPreferredWidth() const
void TabBarTab::OnPaintFrame(Canvas* canvas)
{
double w = GetFrameGeometry().width;
double h = GetFrameGeometry().height;
if (IsCurrent)
{
canvas->fillRect(Rect::xywh(0.0, 0.0, w, h), Colorf::fromRgba8(51, 51, 51));
}
else if (hot)
{
canvas->fillRect(Rect::xywh(0.0, 0.0, w, h), Colorf::fromRgba8(45, 45, 45));
}
}
void TabBarTab::OnGeometryChanged()
@ -242,7 +257,7 @@ void TabBarTab::OnGeometryChanged()
}
if (Label)
{
Label->SetFrameGeometry(Rect::xywh(x, 0.0, std::max(w - x, 0.0), h));
Label->SetFrameGeometry(Rect::xywh(x, (h - Label->GetPreferredHeight()) * 0.5, std::max(w - x, 0.0), Label->GetPreferredHeight()));
}
}
@ -283,6 +298,7 @@ void TabBarTab::OnMouseLeave()
TabWidgetStack::TabWidgetStack(Widget* parent) : Widget(parent)
{
SetNoncontentSizes(20.0, 5.0, 20.0, 5.0);
}
void TabWidgetStack::SetCurrentWidget(Widget* widget)

View file

@ -978,6 +978,10 @@ set (PCH_SOURCES
rendering/swrenderer/textures/swcanvastexture.cpp
events.cpp
launcher/launcherwindow.cpp
launcher/launcherbanner.cpp
launcher/launcherbuttonbar.cpp
launcher/playgamepage.cpp
launcher/settingspage.cpp
common/audio/sound/i_sound.cpp
common/audio/sound/oalsound.cpp

View file

@ -0,0 +1,34 @@
#include "launcherbanner.h"
#include "gstrings.h"
#include "version.h"
#include <zwidget/widgets/imagebox/imagebox.h>
#include <zwidget/widgets/textlabel/textlabel.h>
#include <zwidget/core/image.h>
LauncherBanner::LauncherBanner(Widget* parent) : Widget(parent)
{
Logo = new ImageBox(this);
VersionLabel = new TextLabel(this);
VersionLabel->SetTextAlignment(TextLabelAlignment::Right);
Logo->SetImage(Image::LoadResource("widgets/banner.png"));
}
void LauncherBanner::UpdateLanguage()
{
FString versionText = GStrings("PICKER_VERSION");
versionText.Substitute("%s", GetVersionString());
VersionLabel->SetText(versionText.GetChars());
}
double LauncherBanner::GetPreferredHeight() const
{
return Logo->GetPreferredHeight();
}
void LauncherBanner::OnGeometryChanged()
{
Logo->SetFrameGeometry(0.0, 0.0, GetWidth(), Logo->GetPreferredHeight());
VersionLabel->SetFrameGeometry(20.0, GetHeight() - 10.0 - VersionLabel->GetPreferredHeight(), GetWidth() - 40.0, VersionLabel->GetPreferredHeight());
}

View file

@ -0,0 +1,21 @@
#pragma once
#include <zwidget/core/widget.h>
class ImageBox;
class TextLabel;
class LauncherBanner : public Widget
{
public:
LauncherBanner(Widget* parent);
void UpdateLanguage();
double GetPreferredHeight() const;
private:
void OnGeometryChanged() override;
ImageBox* Logo = nullptr;
TextLabel* VersionLabel = nullptr;
};

View file

@ -0,0 +1,46 @@
#include "launcherbuttonbar.h"
#include "launcherwindow.h"
#include "gstrings.h"
#include <zwidget/widgets/pushbutton/pushbutton.h>
LauncherButtonbar::LauncherButtonbar(LauncherWindow* parent) : Widget(parent)
{
PlayButton = new PushButton(this);
ExitButton = new PushButton(this);
PlayButton->OnClick = [=]() { OnPlayButtonClicked(); };
ExitButton->OnClick = [=]() { OnExitButtonClicked(); };
}
void LauncherButtonbar::UpdateLanguage()
{
PlayButton->SetText(GStrings("PICKER_PLAY"));
ExitButton->SetText(GStrings("PICKER_EXIT"));
}
double LauncherButtonbar::GetPreferredHeight() const
{
return 20.0 + std::max(PlayButton->GetPreferredHeight(), ExitButton->GetPreferredHeight());
}
void LauncherButtonbar::OnGeometryChanged()
{
PlayButton->SetFrameGeometry(20.0, 10.0, 120.0, PlayButton->GetPreferredHeight());
ExitButton->SetFrameGeometry(GetWidth() - 20.0 - 120.0, 10.0, 120.0, PlayButton->GetPreferredHeight());
}
void LauncherButtonbar::OnPlayButtonClicked()
{
GetLauncher()->Start();
}
void LauncherButtonbar::OnExitButtonClicked()
{
GetLauncher()->Exit();
}
LauncherWindow* LauncherButtonbar::GetLauncher() const
{
return static_cast<LauncherWindow*>(Parent());
}

View file

@ -0,0 +1,25 @@
#pragma once
#include <zwidget/core/widget.h>
class LauncherWindow;
class PushButton;
class LauncherButtonbar : public Widget
{
public:
LauncherButtonbar(LauncherWindow* parent);
void UpdateLanguage();
double GetPreferredHeight() const;
private:
void OnGeometryChanged() override;
void OnPlayButtonClicked();
void OnExitButtonClicked();
LauncherWindow* GetLauncher() const;
PushButton* PlayButton = nullptr;
PushButton* ExitButton = nullptr;
};

View file

@ -1,25 +1,15 @@
#include "launcherwindow.h"
#include "launcherbanner.h"
#include "launcherbuttonbar.h"
#include "playgamepage.h"
#include "settingspage.h"
#include "v_video.h"
#include "version.h"
#include "i_interface.h"
#include "gstrings.h"
#include <zwidget/core/resourcedata.h>
#include <zwidget/core/image.h>
#include <zwidget/window/window.h>
#include <zwidget/widgets/textedit/textedit.h>
#include <zwidget/widgets/listview/listview.h>
#include <zwidget/widgets/imagebox/imagebox.h>
#include <zwidget/widgets/textlabel/textlabel.h>
#include <zwidget/widgets/pushbutton/pushbutton.h>
#include <zwidget/widgets/checkboxlabel/checkboxlabel.h>
#include <zwidget/widgets/lineedit/lineedit.h>
#ifdef RENDER_BACKENDS
EXTERN_CVAR(Int, vid_preferbackend);
#endif
EXTERN_CVAR(String, language)
EXTERN_CVAR(Bool, queryiwad);
#include <zwidget/widgets/tabwidget/tabwidget.h>
int LauncherWindow::ExecModal(WadStuff* wads, int numwads, int defaultiwad, int* autoloadflags)
{
@ -36,39 +26,7 @@ int LauncherWindow::ExecModal(WadStuff* wads, int numwads, int defaultiwad, int*
return launcher->ExecResult;
}
void LauncherWindow::UpdateLanguage()
{
LangLabel->SetText(GStrings("OPTMNU_LANGUAGE"));
SelectLabel->SetText(GStrings("PICKER_SELECT"));
PlayButton->SetText(GStrings("PICKER_PLAY"));
ExitButton->SetText(GStrings("PICKER_EXIT"));
GeneralLabel->SetText(GStrings("PICKER_GENERAL"));
ExtrasLabel->SetText(GStrings("PICKER_EXTRA"));
FullscreenCheckbox->SetText(GStrings("PICKER_FULLSCREEN"));
DisableAutoloadCheckbox->SetText(GStrings("PICKER_NOAUTOLOAD"));
DontAskAgainCheckbox->SetText(GStrings("PICKER_DONTASK"));
LightsCheckbox->SetText(GStrings("PICKER_LIGHTS"));
BrightmapsCheckbox->SetText(GStrings("PICKER_BRIGHTMAPS"));
WidescreenCheckbox->SetText(GStrings("PICKER_WIDESCREEN"));
ParametersLabel->SetText(GStrings("PICKER_ADDPARM"));
#ifdef RENDER_BACKENDS
BackendLabel->SetText(GStrings("PICKER_PREFERBACKEND"));
VulkanCheckbox->SetText(GStrings("OPTVAL_VULKAN"));
OpenGLCheckbox->SetText(GStrings("OPTVAL_OPENGL"));
GLESCheckbox->SetText(GStrings("OPTVAL_OPENGLES"));
#endif
FString welcomeText = GStrings("PICKER_WELCOME");
welcomeText.Substitute("%s", GAMENAME);
FString versionText = GStrings("PICKER_VERSION");
versionText.Substitute("%s", GetVersionString());
WelcomeLabel->SetText(welcomeText.GetChars());
VersionLabel->SetText(versionText.GetChars());
}
LauncherWindow::LauncherWindow(WadStuff* wads, int numwads, int defaultiwad, int* autoloadflags) : Widget(nullptr, WidgetType::Window), AutoloadFlags(autoloadflags)
LauncherWindow::LauncherWindow(WadStuff* wads, int numwads, int defaultiwad, int* autoloadflags) : Widget(nullptr, WidgetType::Window)
{
SetWindowBackground(Colorf::fromRgba8(51, 51, 51));
SetWindowBorderColor(Colorf::fromRgba8(51, 51, 51));
@ -76,270 +34,65 @@ LauncherWindow::LauncherWindow(WadStuff* wads, int numwads, int defaultiwad, int
SetWindowCaptionTextColor(Colorf::fromRgba8(226, 223, 219));
SetWindowTitle(GAMENAME);
Logo = new ImageBox(this);
WelcomeLabel = new TextLabel(this);
VersionLabel = new TextLabel(this);
LangLabel = new TextLabel(this);
SelectLabel = new TextLabel(this);
GeneralLabel = new TextLabel(this);
ExtrasLabel = new TextLabel(this);
ParametersLabel = new TextLabel(this);
FullscreenCheckbox = new CheckboxLabel(this);
DisableAutoloadCheckbox = new CheckboxLabel(this);
DontAskAgainCheckbox = new CheckboxLabel(this);
LightsCheckbox = new CheckboxLabel(this);
BrightmapsCheckbox = new CheckboxLabel(this);
WidescreenCheckbox = new CheckboxLabel(this);
PlayButton = new PushButton(this);
ExitButton = new PushButton(this);
LangList = new ListView(this);
GamesList = new ListView(this);
ParametersEdit = new LineEdit(this);
Banner = new LauncherBanner(this);
Pages = new TabWidget(this);
Buttonbar = new LauncherButtonbar(this);
#ifdef RENDER_BACKENDS
BackendLabel = new TextLabel(this);
VulkanCheckbox = new CheckboxLabel(this);
OpenGLCheckbox = new CheckboxLabel(this);
GLESCheckbox = new CheckboxLabel(this);
#endif
PlayGame = new PlayGamePage(this, wads, numwads, defaultiwad);
Settings = new SettingsPage(this, autoloadflags);
PlayButton->OnClick = [=]() { OnPlayButtonClicked(); };
ExitButton->OnClick = [=]() { OnExitButtonClicked(); };
GamesList->OnActivated = [=]() { OnGamesListActivated(); };
Pages->AddTab(PlayGame, "Play");
Pages->AddTab(Settings, "Settings");
UpdateLanguage();
FullscreenCheckbox->SetChecked(vid_fullscreen);
DontAskAgainCheckbox->SetChecked(!queryiwad);
int flags = *autoloadflags;
DisableAutoloadCheckbox->SetChecked(flags & 1);
LightsCheckbox->SetChecked(flags & 2);
BrightmapsCheckbox->SetChecked(flags & 4);
WidescreenCheckbox->SetChecked(flags & 8);
#ifdef RENDER_BACKENDS
OpenGLCheckbox->SetRadioStyle(true);
VulkanCheckbox->SetRadioStyle(true);
GLESCheckbox->SetRadioStyle(true);
OpenGLCheckbox->FuncChanged = [this](bool on) { if (on) { VulkanCheckbox->SetChecked(false); GLESCheckbox->SetChecked(false); }};
VulkanCheckbox->FuncChanged = [this](bool on) { if (on) { OpenGLCheckbox->SetChecked(false); GLESCheckbox->SetChecked(false); }};
GLESCheckbox->FuncChanged = [this](bool on) { if (on) { VulkanCheckbox->SetChecked(false); OpenGLCheckbox->SetChecked(false); }};
switch (vid_preferbackend)
{
case 0:
OpenGLCheckbox->SetChecked(true);
break;
case 1:
VulkanCheckbox->SetChecked(true);
break;
case 2:
GLESCheckbox->SetChecked(true);
break;
}
#endif
try
{
auto data = LoadWidgetData("menudef.txt");
FScanner sc;
sc.OpenMem("menudef.txt", data);
while (sc.GetString())
{
if (sc.Compare("OptionString"))
{
sc.MustGetString();
if (sc.Compare("LanguageOptions"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
FString iso = sc.String;
sc.MustGetStringName(",");
sc.MustGetString();
if(iso.CompareNoCase("auto"))
languages.push_back(std::make_pair(iso, FString(sc.String)));
}
}
}
}
}
catch (const std::exception& ex)
{
hideLanguage = true;
}
int i = 0;
for (auto& l : languages)
{
LangList->AddItem(l.second.GetChars());
if (!l.first.CompareNoCase(::language))
LangList->SetSelectedItem(i);
i++;
}
for (int i = 0; i < numwads; i++)
{
const char* filepart = strrchr(wads[i].Path.GetChars(), '/');
if (filepart == NULL)
filepart = wads[i].Path.GetChars();
else
filepart++;
FString work;
if (*filepart) work.Format("%s (%s)", wads[i].Name.GetChars(), filepart);
else work = wads[i].Name.GetChars();
GamesList->AddItem(work.GetChars());
}
if (defaultiwad >= 0 && defaultiwad < numwads)
{
GamesList->SetSelectedItem(defaultiwad);
GamesList->ScrollToItem(defaultiwad);
}
Logo->SetImage(Image::LoadResource("widgets/banner.png"));
GamesList->SetFocus();
LangList->OnChanged = [this](int i)
{
::language = languages[i].first.GetChars();
GStrings.UpdateLanguage(::language); // CVAR callbacks are not active yet.
UpdateLanguage();
Update();
};
Pages->SetCurrentWidget(PlayGame);
PlayGame->SetFocus();
}
void LauncherWindow::OnClose()
void LauncherWindow::Start()
{
OnExitButtonClicked();
}
Settings->Save();
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;
#ifdef RENDER_BACKENDS
int v = 1;
if (OpenGLCheckbox->GetChecked()) v = 0;
else if (VulkanCheckbox->GetChecked()) v = 1;
else if (GLESCheckbox->GetChecked()) v = 2;
if (v != vid_preferbackend) vid_preferbackend = v;
#endif
std::string extraargs = ParametersEdit->GetText();
std::string extraargs = PlayGame->GetExtraArgs();
if (!extraargs.empty())
{
// To do: restart the process like the cocoa backend is doing?
}
ExecResult = GamesList->GetSelectedItem();
ExecResult = PlayGame->GetSelectedGame();
DisplayWindow::ExitLoop();
}
void LauncherWindow::OnExitButtonClicked()
void LauncherWindow::Exit()
{
ExecResult = -1;
DisplayWindow::ExitLoop();
}
void LauncherWindow::OnGamesListActivated()
void LauncherWindow::UpdateLanguage()
{
OnPlayButtonClicked();
Banner->UpdateLanguage();
PlayGame->UpdateLanguage();
Settings->UpdateLanguage();
Buttonbar->UpdateLanguage();
}
void LauncherWindow::OnClose()
{
Exit();
}
void LauncherWindow::OnGeometryChanged()
{
double y = 0.0;
double top = 0.0;
double bottom = GetHeight();
Logo->SetFrameGeometry(0.0, y, GetWidth(), Logo->GetPreferredHeight());
y += Logo->GetPreferredHeight();
Banner->SetFrameGeometry(0.0, top, GetWidth(), Banner->GetPreferredHeight());
top += Banner->GetPreferredHeight();
y += 10.0;
bottom -= Buttonbar->GetPreferredHeight();
Buttonbar->SetFrameGeometry(0.0, bottom, GetWidth(), Buttonbar->GetPreferredHeight());
WelcomeLabel->SetFrameGeometry(20.0, y, GetWidth() - 40.0, WelcomeLabel->GetPreferredHeight());
y += WelcomeLabel->GetPreferredHeight();
VersionLabel->SetFrameGeometry(20.0, y, GetWidth() - 40.0, VersionLabel->GetPreferredHeight());
y += VersionLabel->GetPreferredHeight();
y += 10.0;
if (!hideLanguage)
{
LangLabel->SetFrameGeometry(20.0, y, GetWidth() - 40.0, SelectLabel->GetPreferredHeight());
y += LangLabel->GetPreferredHeight();
LangList->SetFrameGeometry(20.0, y, GetWidth() - 40.0, 61);
y += 64.0;
}
SelectLabel->SetFrameGeometry(20.0, y, GetWidth() - 40.0, SelectLabel->GetPreferredHeight());
y += SelectLabel->GetPreferredHeight();
double listViewTop = y;
y = GetHeight() - 15.0 - PlayButton->GetPreferredHeight();
PlayButton->SetFrameGeometry(20.0, y, 120.0, PlayButton->GetPreferredHeight());
ExitButton->SetFrameGeometry(GetWidth() - 20.0 - 120.0, y, 120.0, PlayButton->GetPreferredHeight());
y -= 20.0;
double editHeight = 24.0;
y -= editHeight;
ParametersEdit->SetFrameGeometry(20.0, y, GetWidth() - 40.0, editHeight);
y -= 5.0;
double labelHeight = ParametersLabel->GetPreferredHeight();
y -= labelHeight;
ParametersLabel->SetFrameGeometry(20.0, y, GetWidth() - 40.0, labelHeight);
y -= 10.0;
double panelWidth = 150.0;
#ifdef RENDER_BACKENDS
auto yy = y;
y -= GLESCheckbox->GetPreferredHeight();
double x = GetWidth() / 2 - panelWidth / 2;
GLESCheckbox->SetFrameGeometry(x, y, 190.0, GLESCheckbox->GetPreferredHeight());
y -= OpenGLCheckbox->GetPreferredHeight();
OpenGLCheckbox->SetFrameGeometry(x, y, 190.0, OpenGLCheckbox->GetPreferredHeight());
y -= VulkanCheckbox->GetPreferredHeight();
VulkanCheckbox->SetFrameGeometry(x, y, 190.0, VulkanCheckbox->GetPreferredHeight());
y -= BackendLabel->GetPreferredHeight();
BackendLabel->SetFrameGeometry(x, y, 190.0, BackendLabel->GetPreferredHeight());
y = yy;
#endif
y -= DontAskAgainCheckbox->GetPreferredHeight();
DontAskAgainCheckbox->SetFrameGeometry(20.0, y, 190.0, DontAskAgainCheckbox->GetPreferredHeight());
WidescreenCheckbox->SetFrameGeometry(GetWidth() - 20.0 - panelWidth, y, panelWidth, WidescreenCheckbox->GetPreferredHeight());
y -= DisableAutoloadCheckbox->GetPreferredHeight();
DisableAutoloadCheckbox->SetFrameGeometry(20.0, y, 190.0, DisableAutoloadCheckbox->GetPreferredHeight());
BrightmapsCheckbox->SetFrameGeometry(GetWidth() - 20.0 - panelWidth, y, panelWidth, BrightmapsCheckbox->GetPreferredHeight());
y -= FullscreenCheckbox->GetPreferredHeight();
FullscreenCheckbox->SetFrameGeometry(20.0, y, 190.0, FullscreenCheckbox->GetPreferredHeight());
LightsCheckbox->SetFrameGeometry(GetWidth() - 20.0 - panelWidth, y, panelWidth, LightsCheckbox->GetPreferredHeight());
y -= GeneralLabel->GetPreferredHeight();
GeneralLabel->SetFrameGeometry(20.0, y, 190.0, GeneralLabel->GetPreferredHeight());
ExtrasLabel->SetFrameGeometry(GetWidth() - 20.0 - panelWidth, y, panelWidth, ExtrasLabel->GetPreferredHeight());
double listViewBottom = y - 10.0;
GamesList->SetFrameGeometry(20.0, listViewTop, GetWidth() - 40.0, std::max(listViewBottom - listViewTop, 0.0));
Pages->SetFrameGeometry(0.0, top, GetWidth(), std::max(bottom - top, 0.0));
}

View file

@ -4,15 +4,11 @@
#include "tarray.h"
#include "zstring.h"
#define RENDER_BACKENDS
class ImageBox;
class TextLabel;
class CheckboxLabel;
class PushButton;
class ListView;
class LineEdit;
class TabWidget;
class LauncherBanner;
class LauncherButtonbar;
class PlayGamePage;
class SettingsPage;
struct WadStuff;
class LauncherWindow : public Widget
@ -21,44 +17,21 @@ public:
static int ExecModal(WadStuff* wads, int numwads, int defaultiwad, int* autoloadflags);
LauncherWindow(WadStuff* wads, int numwads, int defaultiwad, int* autoloadflags);
private:
void OnPlayButtonClicked();
void OnExitButtonClicked();
void OnGamesListActivated();
void OnClose() override;
void OnGeometryChanged() override;
void UpdateLanguage();
ImageBox* Logo = nullptr;
TextLabel* WelcomeLabel = nullptr;
TextLabel* VersionLabel = nullptr;
TextLabel* LangLabel = nullptr;
TextLabel* SelectLabel = nullptr;
TextLabel* GeneralLabel = nullptr;
TextLabel* ExtrasLabel = nullptr;
TextLabel* ParametersLabel = nullptr;
CheckboxLabel* FullscreenCheckbox = nullptr;
CheckboxLabel* DisableAutoloadCheckbox = nullptr;
CheckboxLabel* DontAskAgainCheckbox = nullptr;
CheckboxLabel* LightsCheckbox = nullptr;
CheckboxLabel* BrightmapsCheckbox = nullptr;
CheckboxLabel* WidescreenCheckbox = nullptr;
#ifdef RENDER_BACKENDS
TextLabel* BackendLabel = nullptr;
CheckboxLabel* VulkanCheckbox = nullptr;
CheckboxLabel* OpenGLCheckbox = nullptr;
CheckboxLabel* GLESCheckbox = nullptr;
#endif
PushButton* PlayButton = nullptr;
PushButton* ExitButton = nullptr;
ListView* GamesList = nullptr;
ListView* LangList = nullptr;
LineEdit* ParametersEdit = nullptr;
void Start();
void Exit();
private:
void OnClose() override;
void OnGeometryChanged() override;
LauncherBanner* Banner = nullptr;
TabWidget* Pages = nullptr;
LauncherButtonbar* Buttonbar = nullptr;
PlayGamePage* PlayGame = nullptr;
SettingsPage* Settings = nullptr;
int* AutoloadFlags = nullptr;
int ExecResult = -1;
bool hideLanguage = false;
TArray<std::pair<FString, FString>> languages;
};

View file

@ -0,0 +1,100 @@
#include "playgamepage.h"
#include "launcherwindow.h"
#include "i_interface.h"
#include "gstrings.h"
#include "version.h"
#include <zwidget/widgets/textlabel/textlabel.h>
#include <zwidget/widgets/listview/listview.h>
#include <zwidget/widgets/lineedit/lineedit.h>
PlayGamePage::PlayGamePage(LauncherWindow* launcher, WadStuff* wads, int numwads, int defaultiwad) : Widget(nullptr), Launcher(launcher)
{
WelcomeLabel = new TextLabel(this);
SelectLabel = new TextLabel(this);
ParametersLabel = new TextLabel(this);
GamesList = new ListView(this);
ParametersEdit = new LineEdit(this);
for (int i = 0; i < numwads; i++)
{
const char* filepart = strrchr(wads[i].Path.GetChars(), '/');
if (filepart == NULL)
filepart = wads[i].Path.GetChars();
else
filepart++;
FString work;
if (*filepart) work.Format("%s (%s)", wads[i].Name.GetChars(), filepart);
else work = wads[i].Name.GetChars();
GamesList->AddItem(work.GetChars());
}
if (defaultiwad >= 0 && defaultiwad < numwads)
{
GamesList->SetSelectedItem(defaultiwad);
GamesList->ScrollToItem(defaultiwad);
}
GamesList->OnActivated = [=]() { OnGamesListActivated(); };
}
std::string PlayGamePage::GetExtraArgs()
{
return ParametersEdit->GetText();
}
int PlayGamePage::GetSelectedGame()
{
return GamesList->GetSelectedItem();
}
void PlayGamePage::UpdateLanguage()
{
SelectLabel->SetText(GStrings("PICKER_SELECT"));
ParametersLabel->SetText(GStrings("PICKER_ADDPARM"));
FString welcomeText = GStrings("PICKER_WELCOME");
welcomeText.Substitute("%s", GAMENAME);
WelcomeLabel->SetText(welcomeText.GetChars());
}
void PlayGamePage::OnGamesListActivated()
{
Launcher->Start();
}
void PlayGamePage::OnSetFocus()
{
GamesList->SetFocus();
}
void PlayGamePage::OnGeometryChanged()
{
double y = 10.0;
WelcomeLabel->SetFrameGeometry(0.0, y, GetWidth(), WelcomeLabel->GetPreferredHeight());
y += WelcomeLabel->GetPreferredHeight();
y += 10.0;
SelectLabel->SetFrameGeometry(0.0, y, GetWidth(), SelectLabel->GetPreferredHeight());
y += SelectLabel->GetPreferredHeight();
double listViewTop = y;
y = GetHeight() - 10.0;
double editHeight = 24.0;
y -= editHeight;
ParametersEdit->SetFrameGeometry(0.0, y, GetWidth(), editHeight);
y -= 5.0;
double labelHeight = ParametersLabel->GetPreferredHeight();
y -= labelHeight;
ParametersLabel->SetFrameGeometry(0.0, y, GetWidth(), labelHeight);
y -= 10.0;
double listViewBottom = y - 10.0;
GamesList->SetFrameGeometry(0.0, listViewTop, GetWidth(), std::max(listViewBottom - listViewTop, 0.0));
}

View file

@ -0,0 +1,32 @@
#pragma once
#include <zwidget/core/widget.h>
class LauncherWindow;
class TextLabel;
class ListView;
class LineEdit;
struct WadStuff;
class PlayGamePage : public Widget
{
public:
PlayGamePage(LauncherWindow* launcher, WadStuff* wads, int numwads, int defaultiwad);
void UpdateLanguage();
std::string GetExtraArgs();
int GetSelectedGame();
private:
void OnGeometryChanged() override;
void OnSetFocus() override;
void OnGamesListActivated();
LauncherWindow* Launcher = nullptr;
TextLabel* WelcomeLabel = nullptr;
TextLabel* SelectLabel = nullptr;
TextLabel* ParametersLabel = nullptr;
ListView* GamesList = nullptr;
LineEdit* ParametersEdit = nullptr;
};

View file

@ -0,0 +1,206 @@
#include "settingspage.h"
#include "launcherwindow.h"
#include "gstrings.h"
#include "i_interface.h"
#include "v_video.h"
#include <zwidget/core/resourcedata.h>
#include <zwidget/widgets/listview/listview.h>
#include <zwidget/widgets/textlabel/textlabel.h>
#include <zwidget/widgets/checkboxlabel/checkboxlabel.h>
#ifdef RENDER_BACKENDS
EXTERN_CVAR(Int, vid_preferbackend);
#endif
EXTERN_CVAR(String, language)
EXTERN_CVAR(Bool, queryiwad);
SettingsPage::SettingsPage(LauncherWindow* launcher, int* autoloadflags) : Widget(nullptr), Launcher(launcher), AutoloadFlags(autoloadflags)
{
LangLabel = new TextLabel(this);
GeneralLabel = new TextLabel(this);
ExtrasLabel = new TextLabel(this);
FullscreenCheckbox = new CheckboxLabel(this);
DisableAutoloadCheckbox = new CheckboxLabel(this);
DontAskAgainCheckbox = new CheckboxLabel(this);
LightsCheckbox = new CheckboxLabel(this);
BrightmapsCheckbox = new CheckboxLabel(this);
WidescreenCheckbox = new CheckboxLabel(this);
#ifdef RENDER_BACKENDS
BackendLabel = new TextLabel(this);
VulkanCheckbox = new CheckboxLabel(this);
OpenGLCheckbox = new CheckboxLabel(this);
GLESCheckbox = new CheckboxLabel(this);
#endif
FullscreenCheckbox->SetChecked(vid_fullscreen);
DontAskAgainCheckbox->SetChecked(!queryiwad);
int flags = *autoloadflags;
DisableAutoloadCheckbox->SetChecked(flags & 1);
LightsCheckbox->SetChecked(flags & 2);
BrightmapsCheckbox->SetChecked(flags & 4);
WidescreenCheckbox->SetChecked(flags & 8);
#ifdef RENDER_BACKENDS
OpenGLCheckbox->SetRadioStyle(true);
VulkanCheckbox->SetRadioStyle(true);
GLESCheckbox->SetRadioStyle(true);
OpenGLCheckbox->FuncChanged = [this](bool on) { if (on) { VulkanCheckbox->SetChecked(false); GLESCheckbox->SetChecked(false); }};
VulkanCheckbox->FuncChanged = [this](bool on) { if (on) { OpenGLCheckbox->SetChecked(false); GLESCheckbox->SetChecked(false); }};
GLESCheckbox->FuncChanged = [this](bool on) { if (on) { VulkanCheckbox->SetChecked(false); OpenGLCheckbox->SetChecked(false); }};
switch (vid_preferbackend)
{
case 0:
OpenGLCheckbox->SetChecked(true);
break;
case 1:
VulkanCheckbox->SetChecked(true);
break;
case 2:
GLESCheckbox->SetChecked(true);
break;
}
#endif
LangList = new ListView(this);
try
{
auto data = LoadWidgetData("menudef.txt");
FScanner sc;
sc.OpenMem("menudef.txt", data);
while (sc.GetString())
{
if (sc.Compare("OptionString"))
{
sc.MustGetString();
if (sc.Compare("LanguageOptions"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
FString iso = sc.String;
sc.MustGetStringName(",");
sc.MustGetString();
if(iso.CompareNoCase("auto"))
languages.push_back(std::make_pair(iso, FString(sc.String)));
}
}
}
}
}
catch (const std::exception& ex)
{
hideLanguage = true;
}
int i = 0;
for (auto& l : languages)
{
LangList->AddItem(l.second.GetChars());
if (!l.first.CompareNoCase(::language))
LangList->SetSelectedItem(i);
i++;
}
LangList->OnChanged = [=](int i) { OnLanguageChanged(i); };
}
void SettingsPage::Save()
{
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;
#ifdef RENDER_BACKENDS
int v = 1;
if (OpenGLCheckbox->GetChecked()) v = 0;
else if (VulkanCheckbox->GetChecked()) v = 1;
else if (GLESCheckbox->GetChecked()) v = 2;
if (v != vid_preferbackend) vid_preferbackend = v;
#endif
}
void SettingsPage::UpdateLanguage()
{
LangLabel->SetText(GStrings("OPTMNU_LANGUAGE"));
GeneralLabel->SetText(GStrings("PICKER_GENERAL"));
ExtrasLabel->SetText(GStrings("PICKER_EXTRA"));
FullscreenCheckbox->SetText(GStrings("PICKER_FULLSCREEN"));
DisableAutoloadCheckbox->SetText(GStrings("PICKER_NOAUTOLOAD"));
DontAskAgainCheckbox->SetText(GStrings("PICKER_DONTASK"));
LightsCheckbox->SetText(GStrings("PICKER_LIGHTS"));
BrightmapsCheckbox->SetText(GStrings("PICKER_BRIGHTMAPS"));
WidescreenCheckbox->SetText(GStrings("PICKER_WIDESCREEN"));
#ifdef RENDER_BACKENDS
BackendLabel->SetText(GStrings("PICKER_PREFERBACKEND"));
VulkanCheckbox->SetText(GStrings("OPTVAL_VULKAN"));
OpenGLCheckbox->SetText(GStrings("OPTVAL_OPENGL"));
GLESCheckbox->SetText(GStrings("OPTVAL_OPENGLES"));
#endif
}
void SettingsPage::OnLanguageChanged(int i)
{
::language = languages[i].first.GetChars();
GStrings.UpdateLanguage(::language); // CVAR callbacks are not active yet.
UpdateLanguage();
Update();
Launcher->UpdateLanguage();
}
void SettingsPage::OnGeometryChanged()
{
double panelWidth = 200.0;
double y = 0.0;
double w = GetWidth();
double h = GetHeight();
GeneralLabel->SetFrameGeometry(0.0, y, 190.0, GeneralLabel->GetPreferredHeight());
ExtrasLabel->SetFrameGeometry(w - panelWidth, y, panelWidth, ExtrasLabel->GetPreferredHeight());
y += GeneralLabel->GetPreferredHeight();
FullscreenCheckbox->SetFrameGeometry(0.0, y, 190.0, FullscreenCheckbox->GetPreferredHeight());
LightsCheckbox->SetFrameGeometry(w - panelWidth, y, panelWidth, LightsCheckbox->GetPreferredHeight());
y += FullscreenCheckbox->GetPreferredHeight();
DisableAutoloadCheckbox->SetFrameGeometry(0.0, y, 190.0, DisableAutoloadCheckbox->GetPreferredHeight());
BrightmapsCheckbox->SetFrameGeometry(w - panelWidth, y, panelWidth, BrightmapsCheckbox->GetPreferredHeight());
y += DisableAutoloadCheckbox->GetPreferredHeight();
DontAskAgainCheckbox->SetFrameGeometry(0.0, y, 190.0, DontAskAgainCheckbox->GetPreferredHeight());
WidescreenCheckbox->SetFrameGeometry(w - panelWidth, y, panelWidth, WidescreenCheckbox->GetPreferredHeight());
y += DontAskAgainCheckbox->GetPreferredHeight();
#ifdef RENDER_BACKENDS
BackendLabel->SetFrameGeometry(x, y, 190.0, BackendLabel->GetPreferredHeight());
y += BackendLabel->GetPreferredHeight();
VulkanCheckbox->SetFrameGeometry(x, y, 190.0, VulkanCheckbox->GetPreferredHeight());
y += VulkanCheckbox->GetPreferredHeight();
OpenGLCheckbox->SetFrameGeometry(x, y, 190.0, OpenGLCheckbox->GetPreferredHeight());
y += OpenGLCheckbox->GetPreferredHeight();
double x = w / 2 - panelWidth / 2;
GLESCheckbox->SetFrameGeometry(x, y, 190.0, GLESCheckbox->GetPreferredHeight());
y += GLESCheckbox->GetPreferredHeight();
#endif
if (!hideLanguage)
{
LangLabel->SetFrameGeometry(0.0, y, w, LangLabel->GetPreferredHeight());
y += LangLabel->GetPreferredHeight();
LangList->SetFrameGeometry(0.0, y, w, std::max(h - y, 0.0));
}
}

View file

@ -0,0 +1,47 @@
#pragma once
#include <zwidget/core/widget.h>
// #define RENDER_BACKENDS
class LauncherWindow;
class TextLabel;
class CheckboxLabel;
class ListView;
class SettingsPage : public Widget
{
public:
SettingsPage(LauncherWindow* launcher, int* autoloadflags);
void UpdateLanguage();
void Save();
private:
void OnLanguageChanged(int i);
void OnGeometryChanged() override;
LauncherWindow* Launcher = nullptr;
TextLabel* LangLabel = nullptr;
TextLabel* GeneralLabel = nullptr;
TextLabel* ExtrasLabel = nullptr;
CheckboxLabel* FullscreenCheckbox = nullptr;
CheckboxLabel* DisableAutoloadCheckbox = nullptr;
CheckboxLabel* DontAskAgainCheckbox = nullptr;
CheckboxLabel* LightsCheckbox = nullptr;
CheckboxLabel* BrightmapsCheckbox = nullptr;
CheckboxLabel* WidescreenCheckbox = nullptr;
#ifdef RENDER_BACKENDS
TextLabel* BackendLabel = nullptr;
CheckboxLabel* VulkanCheckbox = nullptr;
CheckboxLabel* OpenGLCheckbox = nullptr;
CheckboxLabel* GLESCheckbox = nullptr;
#endif
ListView* LangList = nullptr;
int* AutoloadFlags = nullptr;
TArray<std::pair<FString, FString>> languages;
bool hideLanguage = false;
};