mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-18 02:01:18 +00:00
Add launcher window
This commit is contained in:
parent
113fdc5fcc
commit
787d18e12b
4 changed files with 285 additions and 0 deletions
|
@ -324,6 +324,8 @@ if (HAVE_VULKAN)
|
||||||
list( APPEND PROJECT_LIBRARIES "zvulkan" )
|
list( APPEND PROJECT_LIBRARIES "zvulkan" )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
list( APPEND PROJECT_LIBRARIES "zwidget" )
|
||||||
|
|
||||||
# ZMUSIC
|
# ZMUSIC
|
||||||
|
|
||||||
if( MSVC )
|
if( MSVC )
|
||||||
|
@ -589,6 +591,7 @@ file( GLOB HEADER_FILES
|
||||||
common/models/*.h
|
common/models/*.h
|
||||||
common/textures/*.h
|
common/textures/*.h
|
||||||
common/startscreen/*.h
|
common/startscreen/*.h
|
||||||
|
common/widgets/*.h
|
||||||
common/textures/hires/hqnx/*.h
|
common/textures/hires/hqnx/*.h
|
||||||
common/textures/hires/hqnx_asm/*.h
|
common/textures/hires/hqnx_asm/*.h
|
||||||
common/textures/hires/xbr/*.h
|
common/textures/hires/xbr/*.h
|
||||||
|
@ -996,6 +999,7 @@ set (PCH_SOURCES
|
||||||
common/startscreen/startscreen_strife.cpp
|
common/startscreen/startscreen_strife.cpp
|
||||||
common/startscreen/startscreen_generic.cpp
|
common/startscreen/startscreen_generic.cpp
|
||||||
common/startscreen/endoom.cpp
|
common/startscreen/endoom.cpp
|
||||||
|
common/widgets/launcherwindow.cpp
|
||||||
common/fonts/singlelumpfont.cpp
|
common/fonts/singlelumpfont.cpp
|
||||||
common/fonts/singlepicfont.cpp
|
common/fonts/singlepicfont.cpp
|
||||||
common/fonts/specialfont.cpp
|
common/fonts/specialfont.cpp
|
||||||
|
@ -1287,6 +1291,7 @@ include_directories(
|
||||||
common/fonts
|
common/fonts
|
||||||
common/objects
|
common/objects
|
||||||
common/startscreen
|
common/startscreen
|
||||||
|
common/widgets
|
||||||
common/rendering
|
common/rendering
|
||||||
common/rendering/hwrenderer/data
|
common/rendering/hwrenderer/data
|
||||||
common/rendering/gl_load
|
common/rendering/gl_load
|
||||||
|
@ -1322,6 +1327,7 @@ include_directories(
|
||||||
scripting/zscript
|
scripting/zscript
|
||||||
rendering
|
rendering
|
||||||
../libraries/ZVulkan/include
|
../libraries/ZVulkan/include
|
||||||
|
../libraries/ZWidget/include
|
||||||
${SYSTEM_SOURCES_DIR}
|
${SYSTEM_SOURCES_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1481,6 +1487,8 @@ source_group("Common\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/co
|
||||||
source_group("Common\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/.+")
|
source_group("Common\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/.+")
|
||||||
source_group("Common\\File System\\Include" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/include/.+")
|
source_group("Common\\File System\\Include" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/include/.+")
|
||||||
source_group("Common\\File System\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/source/.+")
|
source_group("Common\\File System\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/source/.+")
|
||||||
|
source_group("Common\\Startscreen" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/startscreen/.+")
|
||||||
|
source_group("Common\\Widgets" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/widgets/.+")
|
||||||
source_group("Common\\Scripting" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/.+")
|
source_group("Common\\Scripting" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/.+")
|
||||||
source_group("Common\\Scripting\\Interface" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/interface/.+")
|
source_group("Common\\Scripting\\Interface" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/interface/.+")
|
||||||
source_group("Common\\Scripting\\Frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/frontend/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h)
|
source_group("Common\\Scripting\\Frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/frontend/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h)
|
||||||
|
|
|
@ -87,6 +87,8 @@
|
||||||
#include "i_interface.h"
|
#include "i_interface.h"
|
||||||
#include "i_mainwindow.h"
|
#include "i_mainwindow.h"
|
||||||
|
|
||||||
|
#include "common/widgets/launcherwindow.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -493,12 +495,15 @@ int I_PickIWad(WadStuff *wads, int numwads, bool showwin, int defaultiwad, int&
|
||||||
}
|
}
|
||||||
if (showwin || (vkey != 0 && GetAsyncKeyState(vkey)))
|
if (showwin || (vkey != 0 && GetAsyncKeyState(vkey)))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
WadList = wads;
|
WadList = wads;
|
||||||
NumWads = numwads;
|
NumWads = numwads;
|
||||||
DefaultWad = defaultiwad;
|
DefaultWad = defaultiwad;
|
||||||
|
|
||||||
return (int)DialogBox(g_hInst, MAKEINTRESOURCE(IDD_IWADDIALOG),
|
return (int)DialogBox(g_hInst, MAKEINTRESOURCE(IDD_IWADDIALOG),
|
||||||
(HWND)mainwindow.GetHandle(), (DLGPROC)IWADBoxCallback);
|
(HWND)mainwindow.GetHandle(), (DLGPROC)IWADBoxCallback);
|
||||||
|
*/
|
||||||
|
return LauncherWindow::ExecModal(wads, numwads, defaultiwad, &autoloadflags);
|
||||||
}
|
}
|
||||||
return defaultiwad;
|
return defaultiwad;
|
||||||
}
|
}
|
||||||
|
|
233
src/common/widgets/launcherwindow.cpp
Normal file
233
src/common/widgets/launcherwindow.cpp
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
|
||||||
|
#include "launcherwindow.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "version.h"
|
||||||
|
#include "i_interface.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>
|
||||||
|
|
||||||
|
EXTERN_CVAR(Bool, queryiwad);
|
||||||
|
|
||||||
|
int LauncherWindow::ExecModal(WadStuff* wads, int numwads, int defaultiwad, int* autoloadflags)
|
||||||
|
{
|
||||||
|
Size screenSize = GetScreenSize();
|
||||||
|
double windowWidth = 615.0;
|
||||||
|
double windowHeight = 668.0;
|
||||||
|
|
||||||
|
auto launcher = new LauncherWindow(wads, numwads, defaultiwad, autoloadflags);
|
||||||
|
launcher->SetFrameGeometry((screenSize.width - windowWidth) * 0.5, (screenSize.height - windowHeight) * 0.5, windowWidth, windowHeight);
|
||||||
|
launcher->Show();
|
||||||
|
|
||||||
|
DisplayWindow::RunLoop();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
SetWindowCaptionColor(Colorf::fromRgba8(33, 33, 33));
|
||||||
|
SetWindowCaptionTextColor(Colorf::fromRgba8(226, 223, 219));
|
||||||
|
SetWindowTitle(GAMENAME);
|
||||||
|
|
||||||
|
Logo = new ImageBox(this);
|
||||||
|
WelcomeLabel = new TextLabel(this);
|
||||||
|
VersionLabel = new TextLabel(this);
|
||||||
|
SelectLabel = 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);
|
||||||
|
PlayButton = new PushButton(this);
|
||||||
|
ExitButton = new PushButton(this);
|
||||||
|
GamesList = new ListView(this);
|
||||||
|
|
||||||
|
SelectLabel->SetText("Select which game file (IWAD) to run.");
|
||||||
|
PlayButton->SetText("Play Game");
|
||||||
|
ExitButton->SetText("Exit");
|
||||||
|
|
||||||
|
GeneralLabel->SetText("General");
|
||||||
|
ExtrasLabel->SetText("Extra Graphics");
|
||||||
|
FullscreenCheckbox->SetText("Fullscreen");
|
||||||
|
DisableAutoloadCheckbox->SetText("Disable autoload");
|
||||||
|
DontAskAgainCheckbox->SetText("Don't ask me again");
|
||||||
|
LightsCheckbox->SetText("Lights");
|
||||||
|
BrightmapsCheckbox->SetText("Brightmaps");
|
||||||
|
WidescreenCheckbox->SetText("Widescreen");
|
||||||
|
|
||||||
|
FString welcomeText, versionText;
|
||||||
|
welcomeText.Format("Welcome to %s!", GAMENAME);
|
||||||
|
versionText.Format("Version %s.", GetVersionString());
|
||||||
|
WelcomeLabel->SetText(welcomeText.GetChars());
|
||||||
|
VersionLabel->SetText(versionText.GetChars());
|
||||||
|
|
||||||
|
int flags = *autoloadflags;
|
||||||
|
FullscreenCheckbox->SetChecked(vid_fullscreen);
|
||||||
|
DisableAutoloadCheckbox->SetChecked(flags & 1);
|
||||||
|
DontAskAgainCheckbox->SetChecked(!queryiwad);
|
||||||
|
LightsCheckbox->SetChecked(flags & 2);
|
||||||
|
BrightmapsCheckbox->SetChecked(flags & 4);
|
||||||
|
WidescreenCheckbox->SetChecked(flags & 8);
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*try
|
||||||
|
{
|
||||||
|
auto filedata = ReadAllBytes("C:/Development/ZWidget/example/banner.png");
|
||||||
|
std::vector<unsigned char> pixels;
|
||||||
|
unsigned long width = 0, height = 0;
|
||||||
|
int result = decodePNG(pixels, width, height, (const unsigned char*)filedata.data(), filedata.size(), true);
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
Logo->SetImage(Image::Create(width, height, ImageFormat::R8G8B8A8, pixels.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherWindow::OnGeometryChanged()
|
||||||
|
{
|
||||||
|
double y = 0.0;
|
||||||
|
|
||||||
|
Logo->SetFrameGeometry(0.0, y, GetWidth(), Logo->GetPreferredHeight());
|
||||||
|
y += Logo->GetPreferredHeight();
|
||||||
|
|
||||||
|
y += 10.0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
SelectLabel->SetFrameGeometry(20.0, y, GetWidth() - 40.0, SelectLabel->GetPreferredHeight());
|
||||||
|
y += SelectLabel->GetPreferredHeight();
|
||||||
|
|
||||||
|
double listViewTop = y + 10.0;
|
||||||
|
|
||||||
|
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 panelWidth = 150.0;
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// To do: clean this up
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
static std::wstring to_utf16(const std::string& str)
|
||||||
|
{
|
||||||
|
if (str.empty()) return {};
|
||||||
|
int needed = MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), nullptr, 0);
|
||||||
|
if (needed == 0)
|
||||||
|
throw std::runtime_error("MultiByteToWideChar failed");
|
||||||
|
std::wstring result;
|
||||||
|
result.resize(needed);
|
||||||
|
needed = MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &result[0], (int)result.size());
|
||||||
|
if (needed == 0)
|
||||||
|
throw std::runtime_error("MultiByteToWideChar failed");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<uint8_t> ReadAllBytes(const std::string& filename)
|
||||||
|
{
|
||||||
|
HANDLE handle = CreateFile(to_utf16(filename).c_str(), 0x0001/*FILE_READ_ACCESS*/, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
throw std::runtime_error("Could not open " + filename);
|
||||||
|
|
||||||
|
LARGE_INTEGER fileSize;
|
||||||
|
BOOL result = GetFileSizeEx(handle, &fileSize);
|
||||||
|
if (result == FALSE)
|
||||||
|
{
|
||||||
|
CloseHandle(handle);
|
||||||
|
throw std::runtime_error("GetFileSizeEx failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> buffer(fileSize.QuadPart);
|
||||||
|
|
||||||
|
DWORD bytesRead = 0;
|
||||||
|
result = ReadFile(handle, buffer.data(), (DWORD)buffer.size(), &bytesRead, nullptr);
|
||||||
|
if (result == FALSE || bytesRead != buffer.size())
|
||||||
|
{
|
||||||
|
CloseHandle(handle);
|
||||||
|
throw std::runtime_error("ReadFile failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(handle);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> LoadWidgetFontData(const std::string& name)
|
||||||
|
{
|
||||||
|
return ReadAllBytes("C:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
|
}
|
||||||
|
|
||||||
|
Size LauncherWindow::GetScreenSize()
|
||||||
|
{
|
||||||
|
HDC screenDC = GetDC(0);
|
||||||
|
int screenWidth = GetDeviceCaps(screenDC, HORZRES);
|
||||||
|
int screenHeight = GetDeviceCaps(screenDC, VERTRES);
|
||||||
|
double dpiScale = GetDeviceCaps(screenDC, LOGPIXELSX) / 96.0;
|
||||||
|
ReleaseDC(0, screenDC);
|
||||||
|
|
||||||
|
return Size(screenWidth / dpiScale, screenHeight / dpiScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
std::vector<uint8_t> LoadWidgetFontData(const std::string& name)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
#endif
|
39
src/common/widgets/launcherwindow.h
Normal file
39
src/common/widgets/launcherwindow.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <zwidget/core/widget.h>
|
||||||
|
|
||||||
|
class ImageBox;
|
||||||
|
class TextLabel;
|
||||||
|
class CheckboxLabel;
|
||||||
|
class PushButton;
|
||||||
|
class ListView;
|
||||||
|
struct WadStuff;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
void OnGeometryChanged() override;
|
||||||
|
|
||||||
|
ImageBox* Logo = nullptr;
|
||||||
|
TextLabel* WelcomeLabel = nullptr;
|
||||||
|
TextLabel* VersionLabel = nullptr;
|
||||||
|
TextLabel* SelectLabel = 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;
|
||||||
|
PushButton* PlayButton = nullptr;
|
||||||
|
PushButton* ExitButton = nullptr;
|
||||||
|
ListView* GamesList = nullptr;
|
||||||
|
|
||||||
|
static Size GetScreenSize();
|
||||||
|
};
|
Loading…
Reference in a new issue