Implement NetStartWindow

# Conflicts:
#	src/p_setup.cpp
This commit is contained in:
Magnus Norddahl 2023-12-31 04:15:09 +01:00 committed by Christoph Oelckers
parent da83b546ad
commit 16e578a0f8
5 changed files with 182 additions and 6 deletions

View file

@ -3,6 +3,13 @@
#include "../../core/widget.h"
enum TextLabelAlignment
{
Left,
Center,
Right
};
class TextLabel : public Widget
{
public:
@ -11,6 +18,9 @@ public:
void SetText(const std::string& value);
const std::string& GetText() const;
void SetTextAlignment(TextLabelAlignment alignment);
TextLabelAlignment GetTextAlignment() const;
double GetPreferredHeight() const;
protected:
@ -18,4 +28,5 @@ protected:
private:
std::string text;
TextLabelAlignment textAlignment = TextLabelAlignment::Left;
};

View file

@ -19,6 +19,20 @@ const std::string& TextLabel::GetText() const
return text;
}
void TextLabel::SetTextAlignment(TextLabelAlignment alignment)
{
if (textAlignment != alignment)
{
textAlignment = alignment;
Update();
}
}
TextLabelAlignment TextLabel::GetTextAlignment() const
{
return textAlignment;
}
double TextLabel::GetPreferredHeight() const
{
return 20.0;
@ -26,5 +40,15 @@ double TextLabel::GetPreferredHeight() const
void TextLabel::OnPaint(Canvas* canvas)
{
canvas->drawText(Point(0.0, GetHeight() - 5.0), Colorf::fromRgba8(255, 255, 255), text);
double x = 0.0;
if (textAlignment == TextLabelAlignment::Center)
{
x = (GetWidth() - canvas->measureText(text).width) * 0.5;
}
else if (textAlignment == TextLabelAlignment::Right)
{
x = GetWidth() - canvas->measureText(text).width;
}
canvas->drawText(Point(x, GetHeight() - 5.0), Colorf::fromRgba8(255, 255, 255), text);
}

View file

@ -120,21 +120,22 @@ void MainWindow::ShowErrorPane(const char* text)
void MainWindow::ShowNetStartPane(const char* message, int maxpos)
{
NetStartWindow::ShowNetStartPane(message, maxpos);
}
void MainWindow::HideNetStartPane()
{
NetStartWindow::HideNetStartPane();
}
void MainWindow::SetNetStartProgress(int pos)
{
NetStartWindow::SetNetStartProgress(pos);
}
bool MainWindow::RunMessageLoop(bool (*timer_callback)(void*), void* userdata)
{
// To do: pump messages while showing the netstart window and calling timer_callback every 500 ms
// To do: return true if timer_callback returns true and stop pumping.
return false;
return NetStartWindow::RunMessageLoop(timer_callback, userdata);
}
bool MainWindow::CheckForRestart()

View file

@ -1,12 +1,118 @@
#include "netstartwindow.h"
#include "version.h"
#include <zwidget/core/timer.h>
#include <zwidget/widgets/textlabel/textlabel.h>
#include <zwidget/widgets/pushbutton/pushbutton.h>
NetStartWindow::NetStartWindow() : Widget(nullptr, WidgetType::Window)
NetStartWindow* NetStartWindow::Instance = nullptr;
void NetStartWindow::ShowNetStartPane(const char* message, int maxpos)
{
HideNetStartPane();
Size screenSize = GetScreenSize();
double windowWidth = 300.0;
double windowHeight = 150.0;
Instance = new NetStartWindow(message, maxpos);
Instance->SetFrameGeometry((screenSize.width - windowWidth) * 0.5, (screenSize.height - windowHeight) * 0.5, windowWidth, windowHeight);
Instance->Show();
}
void NetStartWindow::HideNetStartPane()
{
delete Instance;
Instance = nullptr;
}
void NetStartWindow::SetNetStartProgress(int pos)
{
if (Instance)
Instance->SetProgress(pos);
}
bool NetStartWindow::RunMessageLoop(bool (*newtimer_callback)(void*), void* newuserdata)
{
if (!Instance)
return false;
Instance->timer_callback = newtimer_callback;
Instance->userdata = newuserdata;
DisplayWindow::RunLoop();
Instance->timer_callback = nullptr;
Instance->userdata = nullptr;
return Instance->exitreason;
}
NetStartWindow::NetStartWindow(const std::string& message, int maxpos) : 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);
MessageLabel = new TextLabel(this);
ProgressLabel = new TextLabel(this);
AbortButton = new PushButton(this);
MessageLabel->SetTextAlignment(TextLabelAlignment::Center);
ProgressLabel->SetTextAlignment(TextLabelAlignment::Center);
AbortButton->OnClick = [=]() { OnClose(); };
AbortButton->SetText("Abort Network Game");
MessageLabel->SetText(message);
CallbackTimer = new Timer(this);
CallbackTimer->FuncExpired = [=]() { OnCallbackTimerExpired(); };
CallbackTimer->Start(500);
}
void NetStartWindow::SetProgress(int newpos)
{
if (pos != newpos)
{
pos = newpos;
FString message;
message.Format("%d/%d", pos, maxpos);
ProgressLabel->SetText(message.GetChars());
}
}
void NetStartWindow::OnClose()
{
exitreason = false;
DisplayWindow::ExitLoop();
}
void NetStartWindow::OnGeometryChanged()
{
double w = GetWidth();
double h = GetHeight();
double y = 15.0;
double labelheight = MessageLabel->GetPreferredHeight();
MessageLabel->SetFrameGeometry(Rect::xywh(5.0, y, w - 10.0, labelheight));
y += labelheight;
labelheight = ProgressLabel->GetPreferredHeight();
ProgressLabel->SetFrameGeometry(Rect::xywh(5.0, y, w - 10.0, labelheight));
y += labelheight;
y = GetHeight() - 15.0 - AbortButton->GetPreferredHeight();
AbortButton->SetFrameGeometry((w - 200.0) * 0.5, y, 200.0, AbortButton->GetPreferredHeight());
}
void NetStartWindow::OnCallbackTimerExpired()
{
if (timer_callback && timer_callback(userdata))
{
exitreason = true;
DisplayWindow::ExitLoop();
}
}

View file

@ -2,8 +2,42 @@
#include <zwidget/core/widget.h>
class TextLabel;
class PushButton;
class Timer;
class NetStartWindow : public Widget
{
public:
NetStartWindow();
static void ShowNetStartPane(const char* message, int maxpos);
static void HideNetStartPane();
static void SetNetStartProgress(int pos);
static bool RunMessageLoop(bool (*timer_callback)(void*), void* userdata);
private:
NetStartWindow(const std::string& message, int maxpos);
void SetProgress(int pos);
protected:
void OnClose() override;
void OnGeometryChanged() override;
private:
void OnCallbackTimerExpired();
TextLabel* MessageLabel = nullptr;
TextLabel* ProgressLabel = nullptr;
PushButton* AbortButton = nullptr;
Timer* CallbackTimer = nullptr;
int pos = 0;
int maxpos = 1;
bool (*timer_callback)(void*) = nullptr;
void* userdata = nullptr;
bool exitreason = false;
static NetStartWindow* Instance;
};