1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-21 23:03:04 +01:00

Add Some Items to the OpenRCT2::Ui namespace (#22423)

* Put widget in the Ui namespace

* Put theme in the Ui namespace

* Put objective in Ui namespace
This commit is contained in:
Duncan
2024-07-31 05:26:53 +01:00
committed by GitHub
parent bd0dd44c10
commit 681b54dc87
11 changed files with 2043 additions and 2018 deletions

View File

@@ -36,6 +36,7 @@
#include <optional>
using namespace OpenRCT2;
using namespace OpenRCT2::Ui;
using namespace OpenRCT2::Ui::Windows;
struct RCTMouseData

View File

@@ -14,8 +14,6 @@
#include <openrct2/drawing/ImageId.hpp>
#include <openrct2/util/Util.h>
using namespace OpenRCT2;
namespace OpenRCT2::Dropdown
{
struct Item;

View File

@@ -16,7 +16,9 @@
#include <openrct2/ride/RideData.h>
#include <openrct2/scenario/Scenario.h>
const StringId kObjectiveNames[] = {
namespace OpenRCT2::Ui
{
const StringId kObjectiveNames[] = {
STR_OBJECTIVE_NONE,
STR_OBJECTIVE_GUESTS_BY,
STR_OBJECTIVE_PARK_VALUE_BY,
@@ -29,10 +31,10 @@ const StringId kObjectiveNames[] = {
STR_OBJECTIVE_FINISH_5_ROLLERCOASTERS,
STR_OBJECTIVE_REPLAY_LOAN_AND_PARK_VALUE,
STR_OBJECTIVE_MONTHLY_FOOD_INCOME,
};
};
void formatObjective(Formatter& ft, Objective objective)
{
void formatObjective(Formatter& ft, Objective objective)
{
if (objective.Type == OBJECTIVE_BUILD_THE_BEST)
{
StringId rideTypeString = STR_NONE;
@@ -65,4 +67,5 @@ void formatObjective(Formatter& ft, Objective objective)
else
ft.Add<money64>(objective.Currency);
}
}
}
} // namespace OpenRCT2::Ui

View File

@@ -15,6 +15,9 @@
class Formatter;
struct Objective;
void formatObjective(Formatter& ft, Objective objective);
namespace OpenRCT2::Ui
{
void formatObjective(Formatter& ft, Objective objective);
extern const StringId kObjectiveNames[12];
extern const StringId kObjectiveNames[12];
} // namespace OpenRCT2::Ui

View File

@@ -32,25 +32,25 @@
#include <stdexcept>
#include <vector>
using namespace OpenRCT2;
namespace OpenRCT2::Ui
{
static constexpr uint8_t kCurrentThemeVersion = 1;
static constexpr uint8_t kCurrentThemeVersion = 1;
struct WindowThemeDesc;
struct WindowThemeDesc;
/**
/**
* Represents a window theming style such as the colour scheme.
*/
struct WindowTheme
{
struct WindowTheme
{
ColourWithFlags Colours[6];
};
};
/**
/**
* Represents the style for a particular type of window.
*/
struct UIThemeWindowEntry
{
struct UIThemeWindowEntry
{
WindowClass Class;
WindowTheme Theme;
@@ -59,14 +59,14 @@ struct UIThemeWindowEntry
* @note json is deliberately left non-const: json_t behaviour changes when const
*/
static UIThemeWindowEntry FromJson(const WindowThemeDesc* wtDesc, json_t& json, uint8_t version);
};
};
/**
/**
* Represents a user interface theme. Contains window colour schemes and appearance features.
*/
class UITheme
{
public:
class UITheme
{
public:
std::string Name;
std::vector<UIThemeWindowEntry> Entries;
uint8_t Flags = 0;
@@ -89,23 +89,23 @@ public:
static UITheme* FromJson(json_t& json);
static UITheme* FromFile(const std::string& path);
static UITheme CreatePredefined(const std::string& name, const UIThemeWindowEntry* entries, uint8_t flags);
};
};
/**
/**
* Represents the theme descriptor for a specific window type including the default colour scheme.
*/
struct WindowThemeDesc
{
struct WindowThemeDesc
{
::WindowClass WindowClass;
const utf8* WindowClassSZ;
StringId WindowName;
uint8_t NumColours;
WindowTheme DefaultTheme;
};
};
#pragma region Window Theme Descriptors
// clang-format off
// clang-format off
#define COLOURS_1(c0) 1, { { (c0), 0, 0, 0, 0, 0 } }
#define COLOURS_2(c0, c1) 2, { { (c0), (c1), 0, 0, 0, 0 } }
#define COLOURS_3(c0, c1, c2) 3, { { (c0), (c1), (c2), 0, 0, 0 } }
@@ -230,34 +230,34 @@ static constexpr UIThemeWindowEntry PredefinedThemeRCT1_Entries[] =
{ WindowClass::Changelog, COLOURS_RCT1(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_WHITE), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) },
THEME_DEF_END,
};
// clang-format on
// clang-format on
static constexpr UIThemeWindowEntry PredefinedThemeRCT2_Entries[] = {
static constexpr UIThemeWindowEntry PredefinedThemeRCT2_Entries[] = {
THEME_DEF_END,
};
};
const UITheme PredefinedThemeRCT1 = UITheme::CreatePredefined(
const UITheme PredefinedThemeRCT1 = UITheme::CreatePredefined(
"*RCT1", PredefinedThemeRCT1_Entries,
UITHEME_FLAG_USE_LIGHTS_RIDE | UITHEME_FLAG_USE_LIGHTS_PARK | UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT
| UITHEME_FLAG_USE_FULL_BOTTOM_TOOLBAR);
const UITheme PredefinedThemeRCT2 = UITheme::CreatePredefined("*RCT2", PredefinedThemeRCT2_Entries, 0);
const UITheme PredefinedThemeRCT2 = UITheme::CreatePredefined("*RCT2", PredefinedThemeRCT2_Entries, 0);
struct PredefinedTheme
{
struct PredefinedTheme
{
const UITheme* Theme;
StringId Name;
};
};
static constexpr PredefinedTheme PredefinedThemes[] = {
static constexpr PredefinedTheme PredefinedThemes[] = {
{ &PredefinedThemeRCT1, STR_TITLE_SEQUENCE_RCT1 },
{ &PredefinedThemeRCT2, STR_TITLE_SEQUENCE_RCT2 },
};
};
#pragma endregion
static const WindowThemeDesc* GetWindowThemeDescriptor(WindowClass windowClass)
{
static const WindowThemeDesc* GetWindowThemeDescriptor(WindowClass windowClass)
{
for (const auto& desc : WindowThemeDescriptors)
{
if (desc.WindowClass == windowClass)
@@ -266,10 +266,10 @@ static const WindowThemeDesc* GetWindowThemeDescriptor(WindowClass windowClass)
}
}
return nullptr;
}
}
static const WindowThemeDesc* GetWindowThemeDescriptor(const utf8* windowClassSZ)
{
static const WindowThemeDesc* GetWindowThemeDescriptor(const utf8* windowClassSZ)
{
for (const auto& desc : WindowThemeDescriptors)
{
if (String::Equals(desc.WindowClassSZ, windowClassSZ))
@@ -278,17 +278,17 @@ static const WindowThemeDesc* GetWindowThemeDescriptor(const utf8* windowClassSZ
}
}
return nullptr;
}
}
static void ThrowThemeLoadException()
{
static void ThrowThemeLoadException()
{
throw std::runtime_error("Invalid JSON UI theme entry.");
}
}
#pragma region UIThemeEntry
json_t UIThemeWindowEntry::ToJson() const
{
json_t UIThemeWindowEntry::ToJson() const
{
const WindowThemeDesc* wtDesc = GetWindowThemeDescriptor(Class);
if (wtDesc == nullptr)
{
@@ -309,10 +309,10 @@ json_t UIThemeWindowEntry::ToJson() const
};
return colourSettingsEntry;
}
}
UIThemeWindowEntry UIThemeWindowEntry::FromJson(const WindowThemeDesc* wtDesc, json_t& jsonData, uint8_t version)
{
UIThemeWindowEntry UIThemeWindowEntry::FromJson(const WindowThemeDesc* wtDesc, json_t& jsonData, uint8_t version)
{
Guard::Assert(jsonData.is_object(), "UIThemeWindowEntry::FromJson expects parameter jsonData to be object");
auto jsonColours = Json::AsArray(jsonData["colours"]);
@@ -348,14 +348,14 @@ UIThemeWindowEntry UIThemeWindowEntry::FromJson(const WindowThemeDesc* wtDesc, j
}
return result;
}
}
#pragma endregion
#pragma region UITheme
const UIThemeWindowEntry* UITheme::GetEntry(WindowClass windowClass) const
{
const UIThemeWindowEntry* UITheme::GetEntry(WindowClass windowClass) const
{
for (const auto& entry : Entries)
{
if (entry.Class == windowClass)
@@ -364,10 +364,10 @@ const UIThemeWindowEntry* UITheme::GetEntry(WindowClass windowClass) const
}
}
return nullptr;
}
}
void UITheme::SetEntry(const UIThemeWindowEntry* newEntry)
{
void UITheme::SetEntry(const UIThemeWindowEntry* newEntry)
{
// Try to replace existing entry
for (auto& entry : Entries)
{
@@ -379,10 +379,10 @@ void UITheme::SetEntry(const UIThemeWindowEntry* newEntry)
}
Entries.push_back(*newEntry);
}
}
void UITheme::RemoveEntry(WindowClass windowClass)
{
void UITheme::RemoveEntry(WindowClass windowClass)
{
// Remove existing entry
for (size_t i = 0; i < Entries.size(); i++)
{
@@ -393,10 +393,10 @@ void UITheme::RemoveEntry(WindowClass windowClass)
break;
}
}
}
}
json_t UITheme::ToJson() const
{
json_t UITheme::ToJson() const
{
// Create entries
json_t jsonEntries;
for (const UIThemeWindowEntry& entry : Entries)
@@ -421,10 +421,10 @@ json_t UITheme::ToJson() const
};
return jsonTheme;
}
}
bool UITheme::WriteToFile(const std::string& path) const
{
bool UITheme::WriteToFile(const std::string& path) const
{
auto jsonTheme = ToJson();
bool result;
try
@@ -439,10 +439,10 @@ bool UITheme::WriteToFile(const std::string& path) const
}
return result;
}
}
UITheme* UITheme::FromJson(json_t& jsonObj)
{
UITheme* UITheme::FromJson(json_t& jsonObj)
{
Guard::Assert(jsonObj.is_object(), "UITheme::FromJson expects parameter jsonObj to be object");
const std::string themeName = Json::GetString(jsonObj["name"]);
@@ -493,10 +493,10 @@ UITheme* UITheme::FromJson(json_t& jsonObj)
delete result;
throw;
}
}
}
UITheme* UITheme::FromFile(const std::string& path)
{
UITheme* UITheme::FromFile(const std::string& path)
{
UITheme* result = nullptr;
json_t json;
try
@@ -510,10 +510,10 @@ UITheme* UITheme::FromFile(const std::string& path)
result = nullptr;
}
return result;
}
}
UITheme UITheme::CreatePredefined(const std::string& name, const UIThemeWindowEntry* entries, uint8_t flags)
{
UITheme UITheme::CreatePredefined(const std::string& name, const UIThemeWindowEntry* entries, uint8_t flags)
{
auto theme = UITheme(name);
theme.Flags = flags | UITHEME_FLAG_PREDEFINED;
@@ -525,12 +525,12 @@ UITheme UITheme::CreatePredefined(const std::string& name, const UIThemeWindowEn
theme.Entries = std::vector<UIThemeWindowEntry>(entries, entries + numEntries);
return theme;
}
}
#pragma endregion
namespace OpenRCT2::ThemeManager
{
namespace ThemeManager
{
struct AvailableTheme
{
std::string Path;
@@ -689,41 +689,41 @@ namespace OpenRCT2::ThemeManager
auto env = context->GetPlatformEnvironment();
return env->GetDirectoryPath(DIRBASE::USER, DIRID::THEME);
}
} // namespace OpenRCT2::ThemeManager
} // namespace ThemeManager
void ThemeManagerLoadAvailableThemes()
{
void ThemeManagerLoadAvailableThemes()
{
ThemeManager::GetAvailableThemes(&ThemeManager::AvailableThemes);
}
}
size_t ThemeManagerGetNumAvailableThemes()
{
size_t ThemeManagerGetNumAvailableThemes()
{
return ThemeManager::AvailableThemes.size();
}
}
const utf8* ThemeManagerGetAvailableThemePath(size_t index)
{
const utf8* ThemeManagerGetAvailableThemePath(size_t index)
{
return ThemeManager::AvailableThemes[index].Path.c_str();
}
}
const utf8* ThemeManagerGetAvailableThemeConfigName(size_t index)
{
const utf8* ThemeManagerGetAvailableThemeConfigName(size_t index)
{
return ThemeManager::AvailableThemes[index].Name.c_str();
}
const utf8* ThemeManagerGetAvailableThemeName(size_t index)
{
}
const utf8* ThemeManagerGetAvailableThemeName(size_t index)
{
if (index < ThemeManager::NumPredefinedThemes)
return LanguageGetString(PredefinedThemes[index].Name);
return ThemeManager::AvailableThemes[index].Name.c_str();
}
}
size_t ThemeManagerGetAvailableThemeIndex()
{
size_t ThemeManagerGetAvailableThemeIndex()
{
return ThemeManager::ActiveAvailableThemeIndex;
}
}
void ThemeManagerSetActiveAvailableTheme(size_t index)
{
void ThemeManagerSetActiveAvailableTheme(size_t index)
{
if (index < ThemeManager::NumPredefinedThemes)
{
ThemeManager::LoadTheme(const_cast<UITheme*>(PredefinedThemes[index].Theme));
@@ -743,10 +743,10 @@ void ThemeManagerSetActiveAvailableTheme(size_t index)
Config::Get().interface.CurrentThemePreset = ThemeManagerGetAvailableThemeConfigName(index);
ColourSchemeUpdateAll();
}
}
size_t ThemeGetIndexForName(const utf8* name)
{
size_t ThemeGetIndexForName(const utf8* name)
{
size_t count = ThemeManager::AvailableThemes.size();
for (size_t i = 0; i < count; i++)
{
@@ -757,10 +757,10 @@ size_t ThemeGetIndexForName(const utf8* name)
}
}
return SIZE_MAX;
}
}
ColourWithFlags ThemeGetColour(WindowClass wc, uint8_t index)
{
ColourWithFlags ThemeGetColour(WindowClass wc, uint8_t index)
{
const UIThemeWindowEntry* entry = ThemeManager::CurrentTheme->GetEntry(wc);
if (entry == nullptr)
{
@@ -773,10 +773,10 @@ ColourWithFlags ThemeGetColour(WindowClass wc, uint8_t index)
}
return entry->Theme.Colours[index];
}
}
void ThemeSetColour(WindowClass wc, uint8_t index, ColourWithFlags colour)
{
void ThemeSetColour(WindowClass wc, uint8_t index, ColourWithFlags colour)
{
UIThemeWindowEntry entry{};
entry.Class = wc;
@@ -799,27 +799,27 @@ void ThemeSetColour(WindowClass wc, uint8_t index, ColourWithFlags colour)
ThemeManager::CurrentTheme->SetEntry(&entry);
ThemeSave();
}
}
uint8_t ThemeGetFlags()
{
uint8_t ThemeGetFlags()
{
return ThemeManager::CurrentTheme->Flags;
}
}
void ThemeSetFlags(uint8_t flags)
{
void ThemeSetFlags(uint8_t flags)
{
ThemeManager::CurrentTheme->Flags = flags;
ThemeSave();
}
}
void ThemeSave()
{
void ThemeSave()
{
ThemeManager::EnsureThemeDirectoryExists();
ThemeManager::CurrentTheme->WriteToFile(ThemeManager::CurrentThemePath);
}
}
void ThemeRename(const utf8* name)
{
void ThemeRename(const utf8* name)
{
const auto oldPath = ThemeManager::CurrentThemePath;
ThemeManager::EnsureThemeDirectoryExists();
@@ -840,10 +840,10 @@ void ThemeRename(const utf8* name)
break;
}
}
}
}
void ThemeDuplicate(const utf8* name)
{
void ThemeDuplicate(const utf8* name)
{
ThemeManager::EnsureThemeDirectoryExists();
auto newPath = ThemeManager::GetThemeFileName(name);
@@ -865,53 +865,53 @@ void ThemeDuplicate(const utf8* name)
break;
}
}
}
}
void ThemeDelete()
{
void ThemeDelete()
{
File::Delete(ThemeManager::CurrentThemePath);
ThemeManager::LoadTheme(const_cast<UITheme*>(&PredefinedThemeRCT2));
ThemeManager::ActiveAvailableThemeIndex = 1;
Config::Get().interface.CurrentThemePreset = ThemeManagerGetAvailableThemeConfigName(1);
}
}
void ThemeManagerInitialise()
{
void ThemeManagerInitialise()
{
ThemeManager::Initialise();
}
}
uint8_t ThemeDescGetNumColours(WindowClass wc)
{
uint8_t ThemeDescGetNumColours(WindowClass wc)
{
const WindowThemeDesc* desc = GetWindowThemeDescriptor(wc);
if (desc == nullptr)
{
return 0;
}
return desc->NumColours;
}
}
StringId ThemeDescGetName(WindowClass wc)
{
StringId ThemeDescGetName(WindowClass wc)
{
const WindowThemeDesc* desc = GetWindowThemeDescriptor(wc);
if (desc == nullptr)
{
return STR_EMPTY;
}
return desc->WindowName;
}
}
void ColourSchemeUpdateAll()
{
void ColourSchemeUpdateAll()
{
WindowVisitEach([](WindowBase* w) { ColourSchemeUpdate(w); });
}
}
void ColourSchemeUpdate(WindowBase* window)
{
void ColourSchemeUpdate(WindowBase* window)
{
ColourSchemeUpdateByClass(window, window->classification);
}
}
void ColourSchemeUpdateByClass(WindowBase* window, WindowClass classification)
{
void ColourSchemeUpdateByClass(WindowBase* window, WindowClass classification)
{
const WindowTheme* windowTheme;
const UIThemeWindowEntry* entry = ThemeManager::CurrentTheme->GetEntry(classification);
if (entry != nullptr)
@@ -938,4 +938,5 @@ void ColourSchemeUpdateByClass(WindowBase* window, WindowClass classification)
// Some windows need to be transparent even if the colours aren't.
// There doesn't seem to be any side-effects for all windows being transparent
window->flags |= WF_TRANSPARENT;
}
}
} // namespace OpenRCT2::Ui

View File

@@ -12,37 +12,40 @@
#include <openrct2/interface/Colour.h>
#include <openrct2/interface/Window.h>
enum
namespace OpenRCT2::Ui
{
enum
{
UITHEME_FLAG_PREDEFINED = 1 << 0,
UITHEME_FLAG_USE_LIGHTS_RIDE = 1 << 1,
UITHEME_FLAG_USE_LIGHTS_PARK = 1 << 2,
UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT = 1 << 3,
UITHEME_FLAG_USE_FULL_BOTTOM_TOOLBAR = 1 << 4,
};
};
void ColourSchemeUpdate(WindowBase* window);
void ColourSchemeUpdateAll();
void ColourSchemeUpdateByClass(WindowBase* window, WindowClass classification);
void ColourSchemeUpdate(WindowBase* window);
void ColourSchemeUpdateAll();
void ColourSchemeUpdateByClass(WindowBase* window, WindowClass classification);
void ThemeManagerInitialise();
void ThemeManagerLoadAvailableThemes();
size_t ThemeManagerGetNumAvailableThemes();
const utf8* ThemeManagerGetAvailableThemePath(size_t index);
const utf8* ThemeManagerGetAvailableThemeConfigName(size_t index);
const utf8* ThemeManagerGetAvailableThemeName(size_t index);
size_t ThemeManagerGetAvailableThemeIndex();
void ThemeManagerSetActiveAvailableTheme(size_t index);
size_t ThemeGetIndexForName(const utf8* name);
void ThemeManagerInitialise();
void ThemeManagerLoadAvailableThemes();
size_t ThemeManagerGetNumAvailableThemes();
const utf8* ThemeManagerGetAvailableThemePath(size_t index);
const utf8* ThemeManagerGetAvailableThemeConfigName(size_t index);
const utf8* ThemeManagerGetAvailableThemeName(size_t index);
size_t ThemeManagerGetAvailableThemeIndex();
void ThemeManagerSetActiveAvailableTheme(size_t index);
size_t ThemeGetIndexForName(const utf8* name);
ColourWithFlags ThemeGetColour(WindowClass wc, uint8_t index);
void ThemeSetColour(WindowClass wc, uint8_t index, ColourWithFlags colour);
uint8_t ThemeGetFlags();
void ThemeSetFlags(uint8_t flags);
void ThemeSave();
void ThemeRename(const utf8* name);
void ThemeDuplicate(const utf8* name);
void ThemeDelete();
ColourWithFlags ThemeGetColour(WindowClass wc, uint8_t index);
void ThemeSetColour(WindowClass wc, uint8_t index, ColourWithFlags colour);
uint8_t ThemeGetFlags();
void ThemeSetFlags(uint8_t flags);
void ThemeSave();
void ThemeRename(const utf8* name);
void ThemeDuplicate(const utf8* name);
void ThemeDelete();
uint8_t ThemeDescGetNumColours(WindowClass wc);
StringId ThemeDescGetName(WindowClass wc);
uint8_t ThemeDescGetNumColours(WindowClass wc);
StringId ThemeDescGetName(WindowClass wc);
} // namespace OpenRCT2::Ui

View File

@@ -25,34 +25,36 @@
using namespace OpenRCT2;
static void WidgetFrameDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetResizeDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetTabDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetFlatButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetTextButton(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetTextCentred(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetText(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetTextInset(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetProgressBarDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetGroupboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetCaptionDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetCheckboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetCloseboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetScrollDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetHScrollbarDraw(
namespace OpenRCT2::Ui
{
static void WidgetFrameDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetResizeDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetTabDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetFlatButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetTextButton(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetTextCentred(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetText(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetTextInset(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetProgressBarDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetGroupboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetCaptionDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetCheckboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetCloseboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetScrollDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetHScrollbarDraw(
DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, ColourWithFlags colour);
static void WidgetVScrollbarDraw(
static void WidgetVScrollbarDraw(
DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, ColourWithFlags colour);
static void WidgetDrawImage(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
static void WidgetDrawImage(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
/**
/**
*
* rct2: 0x006EB2A8
*/
void WidgetDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
void WidgetDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
const auto* widget = GetWidgetByIndex(w, widgetIndex);
if (widget == nullptr)
{
@@ -118,14 +120,14 @@ void WidgetDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
default:
break;
}
}
}
/**
/**
*
* rct2: 0x006EB6CE
*/
static void WidgetFrameDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetFrameDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -151,14 +153,14 @@ static void WidgetFrameDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widge
// Draw the resize sprite at the bottom right corner
leftTop = w.windowPos + ScreenCoordsXY{ widget.right - 18, widget.bottom - 18 };
GfxDrawSprite(dpi, ImageId(SPR_RESIZE, colour.colour), leftTop);
}
}
/**
/**
*
* rct2: 0x006EB765
*/
static void WidgetResizeDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetResizeDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -181,14 +183,14 @@ static void WidgetResizeDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg
// Draw the resize sprite at the bottom right corner
leftTop = w.windowPos + ScreenCoordsXY{ widget.right - 18, widget.bottom - 18 };
GfxDrawSprite(dpi, ImageId(SPR_RESIZE, colour.colour), leftTop);
}
}
/**
/**
*
* rct2: 0x006EB8E5
*/
static void WidgetButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -197,7 +199,8 @@ static void WidgetButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg
w.windowPos + ScreenCoordsXY{ widget.right, widget.bottom } };
// Check if the button is pressed down
uint8_t press = WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex) ? INSET_RECT_FLAG_BORDER_INSET : 0;
uint8_t press = WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex) ? INSET_RECT_FLAG_BORDER_INSET
: 0;
auto colour = w.colours[widget.colour];
@@ -212,14 +215,14 @@ static void WidgetButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg
GfxFillRectInset(dpi, rect, colour, press);
WidgetDrawImage(dpi, w, widgetIndex);
}
}
/**
/**
*
* rct2: 0x006EB806
*/
static void WidgetTabDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetTabDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
auto& widget = w.widgets[widgetIndex];
@@ -261,14 +264,14 @@ static void WidgetTabDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetI
// Draw disabled image
GfxDrawSprite(dpi, image, leftTop);
}
}
/**
/**
*
* rct2: 0x006EB861
*/
static void WidgetFlatButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetFlatButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
if (!WidgetIsDisabled(w, widgetIndex) && WidgetIsHighlighted(w, widgetIndex))
{
WidgetButtonDraw(dpi, w, widgetIndex);
@@ -300,14 +303,14 @@ static void WidgetFlatButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex
// Draw image
WidgetDrawImage(dpi, w, widgetIndex);
}
}
/**
/**
*
* rct2: 0x006EBBEB
*/
static void WidgetTextButton(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetTextButton(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -318,7 +321,8 @@ static void WidgetTextButton(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg
auto colour = w.colours[widget.colour];
// Border
uint8_t press = WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex) ? INSET_RECT_FLAG_BORDER_INSET : 0;
uint8_t press = WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex) ? INSET_RECT_FLAG_BORDER_INSET
: 0;
GfxFillRectInset(dpi, rect, colour, press);
// Button caption
@@ -330,14 +334,14 @@ static void WidgetTextButton(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg
{
WidgetText(dpi, w, widgetIndex);
}
}
}
/**
/**
*
* rct2: 0x006EBC41
*/
static void WidgetTextCentred(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetTextCentred(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -375,14 +379,14 @@ static void WidgetTextCentred(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid
{
DrawTextEllipsised(dpi, coords, widget.width() - 2, stringId, ft, { colour, TextAlignment::CENTRE });
}
}
}
/**
/**
*
* rct2: 0x006EBD52
*/
static void WidgetText(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetText(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -423,14 +427,14 @@ static void WidgetText(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetInde
{
DrawTextEllipsised(dpi, coords, r - l, stringId, ft, colour);
}
}
}
/**
/**
*
* rct2: 0x006EBD1F
*/
static void WidgetTextInset(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetTextInset(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -442,10 +446,10 @@ static void WidgetTextInset(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widge
GfxFillRectInset(dpi, rect, colour, INSET_RECT_F_60);
WidgetText(dpi, w, widgetIndex);
}
}
static std::pair<StringId, void*> WidgetGetStringidAndArgs(const Widget& widget)
{
static std::pair<StringId, void*> WidgetGetStringidAndArgs(const Widget& widget)
{
auto stringId = widget.text;
void* formatArgs = gCommonFormatArgs;
if (widget.flags & WIDGET_FLAGS::TEXT_IS_STRING)
@@ -462,14 +466,14 @@ static std::pair<StringId, void*> WidgetGetStringidAndArgs(const Widget& widget)
}
}
return std::make_pair(stringId, formatArgs);
}
}
/**
/**
*
* rct2: 0x006EB535
*/
static void WidgetGroupboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetGroupboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -522,14 +526,14 @@ static void WidgetGroupboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wi
// Border left
GfxFillRect(dpi, { { l, t + 1 }, { l, b - 2 } }, ColourMapA[colour].mid_dark);
GfxFillRect(dpi, { { l + 1, t + 2 }, { l + 1, b - 2 } }, ColourMapA[colour].lighter);
}
}
/**
/**
*
* rct2: 0x006EB2F9
*/
static void WidgetCaptionDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetCaptionDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto* widget = &w.widgets[widgetIndex];
@@ -574,14 +578,14 @@ static void WidgetCaptionDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid
DrawTextEllipsised(
dpi, topLeft, width, widget->text, Formatter::Common(),
{ ColourWithFlags{ COLOUR_WHITE }.withFlag(ColourFlag::withOutline, true), TextAlignment::CENTRE });
}
}
/**
/**
*
* rct2: 0x006EBB85
*/
static void WidgetCloseboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetCloseboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -610,15 +614,16 @@ static void WidgetCloseboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wi
colour.setFlag(ColourFlag::inset, true);
;
DrawTextEllipsised(dpi, topLeft, widget.width() - 2, widget.text, Formatter::Common(), { colour, TextAlignment::CENTRE });
}
DrawTextEllipsised(
dpi, topLeft, widget.width() - 2, widget.text, Formatter::Common(), { colour, TextAlignment::CENTRE });
}
/**
/**
*
* rct2: 0x006EBAD9
*/
static void WidgetCheckboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetCheckboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -641,7 +646,8 @@ static void WidgetCheckboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wi
if (WidgetIsPressed(w, widgetIndex))
{
DrawText(
dpi, { midLeft - ScreenCoordsXY{ 0, 5 } }, { colour.withFlag(ColourFlag::translucent, false) }, kCheckMarkString);
dpi, { midLeft - ScreenCoordsXY{ 0, 5 } }, { colour.withFlag(ColourFlag::translucent, false) },
kCheckMarkString);
}
// draw the text
@@ -650,14 +656,14 @@ static void WidgetCheckboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wi
auto [stringId, formatArgs] = WidgetGetStringidAndArgs(widget);
GfxDrawStringLeftCentred(dpi, stringId, formatArgs, colour, { midLeft + ScreenCoordsXY{ 14, 0 } });
}
}
/**
/**
*
* rct2: 0x006EBD96
*/
static void WidgetScrollDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetScrollDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
int32_t scrollIndex = WindowGetScrollDataIndex(w, widgetIndex);
const auto& widget = w.widgets[widgetIndex];
@@ -721,20 +727,22 @@ static void WidgetScrollDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg
// Draw the scroll contents
if (scroll_dpi.width > 0 && scroll_dpi.height > 0)
w.OnScrollDraw(scrollIndex, scroll_dpi);
}
}
static void WidgetHScrollbarDraw(
static void WidgetHScrollbarDraw(
DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, ColourWithFlags colour)
{
{
colour.setFlag(ColourFlag::translucent, false);
// Trough
GfxFillRect(dpi, { { l + kScrollBarWidth, t }, { r - kScrollBarWidth, b } }, ColourMapA[colour.colour].lighter);
GfxFillRect(
dpi, { { l + kScrollBarWidth, t }, { r - kScrollBarWidth, b } }, 0x1000000 | ColourMapA[colour.colour].mid_dark);
GfxFillRect(dpi, { { l + kScrollBarWidth, t + 2 }, { r - kScrollBarWidth, t + 2 } }, ColourMapA[colour.colour].mid_dark);
GfxFillRect(
dpi, { { l + kScrollBarWidth, t + 2 }, { r - kScrollBarWidth, t + 2 } }, ColourMapA[colour.colour].mid_dark);
GfxFillRect(dpi, { { l + kScrollBarWidth, t + 3 }, { r - kScrollBarWidth, t + 3 } }, ColourMapA[colour.colour].lighter);
GfxFillRect(dpi, { { l + kScrollBarWidth, t + 7 }, { r - kScrollBarWidth, t + 7 } }, ColourMapA[colour.colour].mid_dark);
GfxFillRect(
dpi, { { l + kScrollBarWidth, t + 7 }, { r - kScrollBarWidth, t + 7 } }, ColourMapA[colour.colour].mid_dark);
GfxFillRect(dpi, { { l + kScrollBarWidth, t + 8 }, { r - kScrollBarWidth, t + 8 } }, ColourMapA[colour.colour].lighter);
// Left button
@@ -761,20 +769,22 @@ static void WidgetHScrollbarDraw(
GfxFillRectInset(dpi, { { r - (kScrollBarWidth - 1), t }, { r, b } }, colour, flags);
DrawText(dpi, { r - 6, t }, {}, kBlackRightArrowString);
}
}
}
static void WidgetVScrollbarDraw(
static void WidgetVScrollbarDraw(
DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, ColourWithFlags colour)
{
{
colour.setFlag(ColourFlag::translucent, false);
// Trough
GfxFillRect(dpi, { { l, t + kScrollBarWidth }, { r, b - kScrollBarWidth } }, ColourMapA[colour.colour].lighter);
GfxFillRect(
dpi, { { l, t + kScrollBarWidth }, { r, b - kScrollBarWidth } }, 0x1000000 | ColourMapA[colour.colour].mid_dark);
GfxFillRect(dpi, { { l + 2, t + kScrollBarWidth }, { l + 2, b - kScrollBarWidth } }, ColourMapA[colour.colour].mid_dark);
GfxFillRect(
dpi, { { l + 2, t + kScrollBarWidth }, { l + 2, b - kScrollBarWidth } }, ColourMapA[colour.colour].mid_dark);
GfxFillRect(dpi, { { l + 3, t + kScrollBarWidth }, { l + 3, b - kScrollBarWidth } }, ColourMapA[colour.colour].lighter);
GfxFillRect(dpi, { { l + 7, t + kScrollBarWidth }, { l + 7, b - kScrollBarWidth } }, ColourMapA[colour.colour].mid_dark);
GfxFillRect(
dpi, { { l + 7, t + kScrollBarWidth }, { l + 7, b - kScrollBarWidth } }, ColourMapA[colour.colour].mid_dark);
GfxFillRect(dpi, { { l + 8, t + kScrollBarWidth }, { l + 8, b - kScrollBarWidth } }, ColourMapA[colour.colour].lighter);
// Up button
@@ -795,14 +805,14 @@ static void WidgetVScrollbarDraw(
dpi, { { l, b - (kScrollBarWidth - 1) }, { r, b } }, colour,
((scroll.flags & VSCROLLBAR_DOWN_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0));
DrawText(dpi, { l + 1, b - (kScrollBarWidth - 1) }, {}, kBlackDownArrowString);
}
}
/**
/**
*
* rct2: 0x006EB951
*/
static void WidgetDrawImage(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetDrawImage(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -844,29 +854,29 @@ static void WidgetDrawImage(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widge
GfxDrawSprite(dpi, image, screenCoords);
}
}
}
bool WidgetIsDisabled(const WindowBase& w, WidgetIndex widgetIndex)
{
bool WidgetIsDisabled(const WindowBase& w, WidgetIndex widgetIndex)
{
if (w.classification == WindowClass::Custom)
return w.widgets[widgetIndex].flags & WIDGET_FLAGS::IS_DISABLED;
return (w.disabled_widgets & (1LL << widgetIndex)) != 0;
}
}
bool WidgetIsHoldable(const WindowBase& w, WidgetIndex widgetIndex)
{
bool WidgetIsHoldable(const WindowBase& w, WidgetIndex widgetIndex)
{
if (w.classification == WindowClass::Custom)
return w.widgets[widgetIndex].flags & WIDGET_FLAGS::IS_HOLDABLE;
return (w.hold_down_widgets & (1LL << widgetIndex)) != 0;
}
}
bool WidgetIsVisible(const WindowBase& w, WidgetIndex widgetIndex)
{
bool WidgetIsVisible(const WindowBase& w, WidgetIndex widgetIndex)
{
return w.widgets[widgetIndex].IsVisible();
}
}
bool WidgetIsPressed(const WindowBase& w, WidgetIndex widgetIndex)
{
bool WidgetIsPressed(const WindowBase& w, WidgetIndex widgetIndex)
{
if (w.classification == WindowClass::Custom)
{
if (w.widgets[widgetIndex].flags & WIDGET_FLAGS::IS_PRESSED)
@@ -895,10 +905,10 @@ bool WidgetIsPressed(const WindowBase& w, WidgetIndex widgetIndex)
return true;
}
return false;
}
}
bool WidgetIsHighlighted(const WindowBase& w, WidgetIndex widgetIndex)
{
bool WidgetIsHighlighted(const WindowBase& w, WidgetIndex widgetIndex)
{
if (gHoverWidget.window_classification != w.classification)
return false;
if (gHoverWidget.window_number != w.number)
@@ -906,10 +916,10 @@ bool WidgetIsHighlighted(const WindowBase& w, WidgetIndex widgetIndex)
if (gHoverWidget.widget_index != widgetIndex)
return false;
return true;
}
}
bool WidgetIsActiveTool(const WindowBase& w, WidgetIndex widgetIndex)
{
bool WidgetIsActiveTool(const WindowBase& w, WidgetIndex widgetIndex)
{
if (!(InputTestFlag(INPUT_FLAG_TOOL_ACTIVE)))
return false;
if (gCurrentToolWidget.window_classification != w.classification)
@@ -920,9 +930,9 @@ bool WidgetIsActiveTool(const WindowBase& w, WidgetIndex widgetIndex)
return false;
return true;
}
}
/**
/**
*
* rct2: 0x006E9F92
* eax: x / output_x
@@ -932,10 +942,10 @@ bool WidgetIsActiveTool(const WindowBase& w, WidgetIndex widgetIndex)
* esi: w
* edi: widget
*/
void WidgetScrollGetPart(
void WidgetScrollGetPart(
WindowBase& w, const Widget* widget, const ScreenCoordsXY& screenCoords, ScreenCoordsXY& retScreenCoords,
int32_t* output_scroll_area, int32_t* scroll_id)
{
{
*scroll_id = 0;
for (Widget* iterator = w.widgets; iterator != widget; iterator++)
{
@@ -982,7 +992,8 @@ void WidgetScrollGetPart(
*output_scroll_area = SCROLL_PART_HSCROLLBAR_THUMB;
}
}
else if ((scroll.flags & VSCROLLBAR_VISIBLE) && (screenCoords.x >= w.windowPos.x + widget->right - (kScrollBarWidth + 1)))
else if (
(scroll.flags & VSCROLLBAR_VISIBLE) && (screenCoords.x >= w.windowPos.x + widget->right - (kScrollBarWidth + 1)))
{
// vertical scrollbar
int32_t bottomOffset = 0;
@@ -1035,10 +1046,10 @@ void WidgetScrollGetPart(
retScreenCoords.y += scroll.v_top - 1;
}
}
}
}
Widget* GetWidgetByIndex(const WindowBase& w, WidgetIndex widgetIndex)
{
Widget* GetWidgetByIndex(const WindowBase& w, WidgetIndex widgetIndex)
{
// Make sure we don't go out of bounds if we are given a bad widget index
WidgetIndex index = 0;
for (auto* widget = w.widgets; widget->type != WindowWidgetType::Last; widget++)
@@ -1053,10 +1064,10 @@ Widget* GetWidgetByIndex(const WindowBase& w, WidgetIndex widgetIndex)
LOG_ERROR("Widget index %i out of bounds for window class %u", widgetIndex, w.classification);
return nullptr;
}
}
static void SafeSetWidgetFlag(WindowBase& w, WidgetIndex widgetIndex, WidgetFlags mask, bool value)
{
static void SafeSetWidgetFlag(WindowBase& w, WidgetIndex widgetIndex, WidgetFlags mask, bool value)
{
Widget* widget = GetWidgetByIndex(w, widgetIndex);
if (widget == nullptr)
{
@@ -1067,15 +1078,15 @@ static void SafeSetWidgetFlag(WindowBase& w, WidgetIndex widgetIndex, WidgetFlag
widget->flags |= mask;
else
widget->flags &= ~mask;
}
}
void WidgetSetEnabled(WindowBase& w, WidgetIndex widgetIndex, bool enabled)
{
void WidgetSetEnabled(WindowBase& w, WidgetIndex widgetIndex, bool enabled)
{
WidgetSetDisabled(w, widgetIndex, !enabled);
}
}
void WidgetSetDisabled(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
void WidgetSetDisabled(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
SafeSetWidgetFlag(w, widgetIndex, WIDGET_FLAGS::IS_DISABLED, value);
if (value)
{
@@ -1085,10 +1096,10 @@ void WidgetSetDisabled(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
w.disabled_widgets &= ~(1uLL << widgetIndex);
}
}
}
void WidgetSetHoldable(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
void WidgetSetHoldable(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
SafeSetWidgetFlag(w, widgetIndex, WIDGET_FLAGS::IS_HOLDABLE, value);
if (value)
{
@@ -1098,29 +1109,29 @@ void WidgetSetHoldable(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
w.hold_down_widgets &= ~(1uLL << widgetIndex);
}
}
}
void WidgetSetVisible(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
void WidgetSetVisible(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
SafeSetWidgetFlag(w, widgetIndex, WIDGET_FLAGS::IS_HIDDEN, !value);
}
}
void WidgetSetPressed(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
void WidgetSetPressed(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
SafeSetWidgetFlag(w, widgetIndex, WIDGET_FLAGS::IS_PRESSED, value);
if (value)
w.pressed_widgets |= (1uLL << widgetIndex);
else
w.pressed_widgets &= ~(1uLL << widgetIndex);
}
}
void WidgetSetCheckboxValue(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
void WidgetSetCheckboxValue(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
WidgetSetPressed(w, widgetIndex, value);
}
}
static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
const auto& widget = w.widgets[widgetIndex];
@@ -1170,7 +1181,8 @@ static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid
// Make a new 1 character wide string for measuring the width
// of the character that the cursor is under. (NOTE: this is broken for multi byte utf8 codepoints)
width = std::max(
GfxGetStringWidthNoFormatting(u8string{ (*textInput->Buffer)[textInput->SelectionStart] }, FontStyle::Medium) - 2,
GfxGetStringWidthNoFormatting(u8string{ (*textInput->Buffer)[textInput->SelectionStart] }, FontStyle::Medium)
- 2,
4);
}
@@ -1180,10 +1192,10 @@ static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid
auto y = topLeft.y + (widget.height() - 1);
GfxFillRect(dpi, { { curX, y }, { curX + width, y } }, colour + 5);
}
}
}
static void WidgetProgressBarDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
static void WidgetProgressBarDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex)
{
const auto& widget = w.widgets[widgetIndex];
ScreenCoordsXY topLeft{ w.windowPos + ScreenCoordsXY{ widget.left, widget.top } };
@@ -1211,10 +1223,10 @@ static void WidgetProgressBarDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex
dpi, { topLeft + ScreenCoordsXY{ 1, 1 }, topLeft + ScreenCoordsXY{ fillSize + 1, widget.height() - 1 } },
{ widget.colour }, 0);
}
}
}
ImageId GetColourButtonImage(colour_t colour)
{
ImageId GetColourButtonImage(colour_t colour)
{
if (colour == COLOUR_INVISIBLE)
{
return ImageId(SPR_G2_ICON_PALETTE_INVISIBLE, colour).WithBlended(false);
@@ -1223,10 +1235,11 @@ ImageId GetColourButtonImage(colour_t colour)
{
return ImageId(SPR_PALETTE_BTN, colour).WithBlended(true);
}
}
}
void WidgetProgressBarSetNewPercentage(Widget& widget, uint8_t newPercentage)
{
void WidgetProgressBarSetNewPercentage(Widget& widget, uint8_t newPercentage)
{
widget.content &= ~0xFF;
widget.content |= newPercentage;
}
}
} // namespace OpenRCT2::Ui

View File

@@ -15,9 +15,9 @@
#include <openrct2/drawing/Drawing.h>
#include <openrct2/interface/Widget.h>
using namespace OpenRCT2;
// clang-format off
namespace OpenRCT2::Ui
{
// clang-format off
#define WINDOW_SHIM_RAW(TITLE, WIDTH, HEIGHT, CLOSE_STR) \
{ WindowWidgetType::Frame, 0, 0, WIDTH - 1, 0, HEIGHT - 1, 0xFFFFFFFF, STR_NONE }, \
{ WindowWidgetType::Caption, 0, 1, WIDTH - 2, 1, 14, TITLE, STR_WINDOW_TITLE_TIP }, \
@@ -25,36 +25,36 @@ using namespace OpenRCT2;
#define WINDOW_SHIM(TITLE, WIDTH, HEIGHT) WINDOW_SHIM_RAW(TITLE, WIDTH, HEIGHT, STR_CLOSE_X)
#define WINDOW_SHIM_WHITE(TITLE, WIDTH, HEIGHT) WINDOW_SHIM_RAW(TITLE, WIDTH, HEIGHT, STR_CLOSE_X_WHITE)
// clang-format on
// clang-format on
ImageId GetColourButtonImage(colour_t colour);
Widget* GetWidgetByIndex(const WindowBase& w, WidgetIndex widgetIndex);
ImageId GetColourButtonImage(colour_t colour);
Widget* GetWidgetByIndex(const WindowBase& w, WidgetIndex widgetIndex);
constexpr auto kWidgetsEnd = Widget{ WindowWidgetType::Last, 0, 0, 0, 0, 0, 0, 0 };
constexpr uint32_t kWidgetContentEmpty = 0xFFFFFFFF;
constexpr auto kBarBlink = (1u << 31);
constexpr uint8_t kScrollBarWidth = 10;
constexpr ScreenSize kTabSize = { 31, 27 };
constexpr auto kWidgetsEnd = Widget{ WindowWidgetType::Last, 0, 0, 0, 0, 0, 0, 0 };
constexpr uint32_t kWidgetContentEmpty = 0xFFFFFFFF;
constexpr auto kBarBlink = (1u << 31);
constexpr uint8_t kScrollBarWidth = 10;
constexpr ScreenSize kTabSize = { 31, 27 };
constexpr const char* kBlackUpArrowString = u8"{BLACK}▲";
constexpr const char* kBlackDownArrowString = u8"{BLACK}▼";
constexpr const char* kBlackLeftArrowString = u8"{BLACK}◀";
constexpr const char* kBlackRightArrowString = u8"{BLACK}▶";
constexpr const char* kCheckMarkString = u8"";
constexpr const char* kEyeString = u8"👁";
constexpr const char* kBlackUpArrowString = u8"{BLACK}▲";
constexpr const char* kBlackDownArrowString = u8"{BLACK}▼";
constexpr const char* kBlackLeftArrowString = u8"{BLACK}◀";
constexpr const char* kBlackRightArrowString = u8"{BLACK}▶";
constexpr const char* kCheckMarkString = u8"";
constexpr const char* kEyeString = u8"👁";
enum class WindowColour : uint8_t
{
enum class WindowColour : uint8_t
{
Primary,
Secondary,
Tertiary,
Quaternary,
};
};
constexpr Widget MakeWidget(
constexpr Widget MakeWidget(
const ScreenCoordsXY& origin, const ScreenSize& size, WindowWidgetType type, WindowColour colour,
uint32_t content = kWidgetContentEmpty, StringId tooltip = STR_NONE)
{
{
Widget out = {};
out.left = origin.x;
out.right = origin.x + size.width - 1;
@@ -66,12 +66,12 @@ constexpr Widget MakeWidget(
out.tooltip = tooltip;
return out;
}
}
constexpr Widget MakeWidget(
constexpr Widget MakeWidget(
const ScreenCoordsXY& origin, const ScreenSize& size, WindowWidgetType type, WindowColour colour, ImageId image,
StringId tooltip = STR_NONE)
{
{
Widget out = {};
out.left = origin.x;
out.right = origin.x + size.width - 1;
@@ -83,29 +83,29 @@ constexpr Widget MakeWidget(
out.tooltip = tooltip;
return out;
}
}
constexpr Widget MakeRemapWidget(
constexpr Widget MakeRemapWidget(
const ScreenCoordsXY& origin, const ScreenSize& size, WindowWidgetType type, WindowColour colour, ImageIndex content,
StringId tooltip = STR_NONE)
{
{
return MakeWidget(origin, size, type, colour, ImageId(content, FilterPaletteID::PaletteNull), tooltip);
}
}
constexpr Widget MakeTab(const ScreenCoordsXY& origin, StringId tooltip = STR_NONE)
{
constexpr Widget MakeTab(const ScreenCoordsXY& origin, StringId tooltip = STR_NONE)
{
const ScreenSize size = kTabSize;
const WindowWidgetType type = WindowWidgetType::Tab;
const WindowColour colour = WindowColour::Secondary;
const auto content = ImageId(ImageIndexUndefined);
return MakeWidget(origin, size, type, colour, content, tooltip);
}
}
constexpr Widget MakeProgressBar(
constexpr Widget MakeProgressBar(
const ScreenCoordsXY& origin, const ScreenSize& size, colour_t colour, uint8_t lowerBlinkBound = 0,
uint8_t upperBlinkBound = 0)
{
{
Widget out = {};
out.left = origin.x;
out.right = origin.x + size.width - 1;
@@ -117,76 +117,77 @@ constexpr Widget MakeProgressBar(
out.tooltip = STR_NONE;
return out;
}
}
// NOLINTBEGIN
#define MakeSpinnerWidgets(...) \
MakeWidget(__VA_ARGS__), MakeSpinnerIncreaseWidget(__VA_ARGS__), MakeSpinnerDecreaseWidget(__VA_ARGS__)
// NOLINTEND
// NOLINTEND
constexpr Widget MakeSpinnerDecreaseWidget(
constexpr Widget MakeSpinnerDecreaseWidget(
const ScreenCoordsXY& origin, const ScreenSize& size, [[maybe_unused]] WindowWidgetType type, WindowColour colour,
[[maybe_unused]] uint32_t content = kWidgetContentEmpty, StringId tooltip = STR_NONE)
{
{
const int16_t xPos = origin.x + size.width - 26;
const int16_t yPos = origin.y + 1;
const uint16_t width = 13;
const uint16_t height = size.height - 2;
return MakeWidget({ xPos, yPos }, { width, height }, WindowWidgetType::Button, colour, STR_NUMERIC_DOWN, tooltip);
}
}
constexpr Widget MakeSpinnerIncreaseWidget(
constexpr Widget MakeSpinnerIncreaseWidget(
const ScreenCoordsXY& origin, const ScreenSize& size, [[maybe_unused]] WindowWidgetType type, WindowColour colour,
[[maybe_unused]] uint32_t content = kWidgetContentEmpty, StringId tooltip = STR_NONE)
{
{
const int16_t xPos = origin.x + size.width - 13;
const int16_t yPos = origin.y + 1;
const uint16_t width = 12;
const uint16_t height = size.height - 2;
return MakeWidget({ xPos, yPos }, { width, height }, WindowWidgetType::Button, colour, STR_NUMERIC_UP, tooltip);
}
}
// NOLINTNEXTLINE
#define MakeDropdownWidgets(...) MakeDropdownBoxWidget(__VA_ARGS__), MakeDropdownButtonWidget(__VA_ARGS__)
constexpr Widget MakeDropdownBoxWidget(
constexpr Widget MakeDropdownBoxWidget(
const ScreenCoordsXY& origin, const ScreenSize& size, [[maybe_unused]] WindowWidgetType type, WindowColour colour,
[[maybe_unused]] uint32_t content = kWidgetContentEmpty, StringId tooltip = STR_NONE)
{
{
return MakeWidget(origin, size, type, colour, content);
}
}
constexpr Widget MakeDropdownButtonWidget(
constexpr Widget MakeDropdownButtonWidget(
const ScreenCoordsXY& origin, const ScreenSize& size, [[maybe_unused]] WindowWidgetType type, WindowColour colour,
[[maybe_unused]] uint32_t content = kWidgetContentEmpty, StringId tooltip = STR_NONE)
{
{
const int16_t xPos = origin.x + size.width - 11;
const int16_t yPos = origin.y + 1;
const uint16_t width = 11;
const uint16_t height = 10;
return MakeWidget({ xPos, yPos }, { width, height }, WindowWidgetType::Button, colour, STR_DROPDOWN_GLYPH, tooltip);
}
}
void WidgetDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
void WidgetDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsDisabled(const WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsHoldable(const WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsVisible(const WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsPressed(const WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsHighlighted(const WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsActiveTool(const WindowBase& w, WidgetIndex widgetIndex);
void WidgetScrollGetPart(
bool WidgetIsDisabled(const WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsHoldable(const WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsVisible(const WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsPressed(const WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsHighlighted(const WindowBase& w, WidgetIndex widgetIndex);
bool WidgetIsActiveTool(const WindowBase& w, WidgetIndex widgetIndex);
void WidgetScrollGetPart(
WindowBase& w, const Widget* widget, const ScreenCoordsXY& screenCoords, ScreenCoordsXY& retScreenCoords,
int32_t* output_scroll_area, int32_t* scroll_id);
void WidgetSetEnabled(WindowBase& w, WidgetIndex widgetIndex, bool enabled);
void WidgetSetDisabled(WindowBase& w, WidgetIndex widgetIndex, bool value);
void WidgetSetHoldable(WindowBase& w, WidgetIndex widgetIndex, bool value);
void WidgetSetVisible(WindowBase& w, WidgetIndex widgetIndex, bool value);
void WidgetSetPressed(WindowBase& w, WidgetIndex widgetIndex, bool value);
void WidgetSetCheckboxValue(WindowBase& w, WidgetIndex widgetIndex, bool value);
void WidgetSetEnabled(WindowBase& w, WidgetIndex widgetIndex, bool enabled);
void WidgetSetDisabled(WindowBase& w, WidgetIndex widgetIndex, bool value);
void WidgetSetHoldable(WindowBase& w, WidgetIndex widgetIndex, bool value);
void WidgetSetVisible(WindowBase& w, WidgetIndex widgetIndex, bool value);
void WidgetSetPressed(WindowBase& w, WidgetIndex widgetIndex, bool value);
void WidgetSetCheckboxValue(WindowBase& w, WidgetIndex widgetIndex, bool value);
void WidgetProgressBarSetNewPercentage(Widget& widget, uint8_t newPercentage);
void WidgetProgressBarSetNewPercentage(Widget& widget, uint8_t newPercentage);
} // namespace OpenRCT2::Ui

View File

@@ -30,6 +30,7 @@
#include <openrct2/world/Location.hpp>
using namespace OpenRCT2;
using namespace OpenRCT2::Ui;
// The amount of pixels to scroll per wheel click
constexpr int32_t WindowScrollPixels = 17;

View File

@@ -300,7 +300,7 @@ namespace OpenRCT2::Scripting
auto w = GetWindow();
if (w != nullptr)
{
return WidgetIsDisabled(*w, _widgetIndex);
return Ui::WidgetIsDisabled(*w, _widgetIndex);
}
return false;
}
@@ -309,19 +309,19 @@ namespace OpenRCT2::Scripting
auto w = GetWindow();
if (w != nullptr)
{
WidgetSetDisabled(*w, _widgetIndex, value);
Ui::WidgetSetDisabled(*w, _widgetIndex, value);
auto widget = GetWidget();
if (widget != nullptr)
{
if (widget->type == WindowWidgetType::DropdownMenu)
{
WidgetSetDisabled(*w, _widgetIndex + 1, value);
Ui::WidgetSetDisabled(*w, _widgetIndex + 1, value);
}
else if (widget->type == WindowWidgetType::Spinner)
{
WidgetSetDisabled(*w, _widgetIndex + 1, value);
WidgetSetDisabled(*w, _widgetIndex + 2, value);
Ui::WidgetSetDisabled(*w, _widgetIndex + 1, value);
Ui::WidgetSetDisabled(*w, _widgetIndex + 2, value);
}
}
Invalidate(widget);
@@ -333,7 +333,7 @@ namespace OpenRCT2::Scripting
auto w = GetWindow();
if (w != nullptr)
{
return WidgetIsVisible(*w, _widgetIndex);
return Ui::WidgetIsVisible(*w, _widgetIndex);
}
return false;
}
@@ -342,19 +342,19 @@ namespace OpenRCT2::Scripting
auto w = GetWindow();
if (w != nullptr)
{
WidgetSetVisible(*w, _widgetIndex, value);
Ui::WidgetSetVisible(*w, _widgetIndex, value);
auto widget = GetWidget();
if (widget != nullptr)
{
if (widget->type == WindowWidgetType::DropdownMenu)
{
WidgetSetVisible(*w, _widgetIndex + 1, value);
Ui::WidgetSetVisible(*w, _widgetIndex + 1, value);
}
else if (widget->type == WindowWidgetType::Spinner)
{
WidgetSetVisible(*w, _widgetIndex + 1, value);
WidgetSetVisible(*w, _widgetIndex + 2, value);
Ui::WidgetSetVisible(*w, _widgetIndex + 1, value);
Ui::WidgetSetVisible(*w, _widgetIndex + 2, value);
}
}
Invalidate(widget);
@@ -486,7 +486,7 @@ namespace OpenRCT2::Scripting
auto w = GetWindow();
if (w != nullptr)
{
return WidgetIsPressed(*w, _widgetIndex);
return Ui::WidgetIsPressed(*w, _widgetIndex);
}
return false;
}
@@ -495,7 +495,7 @@ namespace OpenRCT2::Scripting
auto w = GetWindow();
if (w != nullptr)
{
WidgetSetCheckboxValue(*w, _widgetIndex, value ? 1 : 0);
Ui::WidgetSetCheckboxValue(*w, _widgetIndex, value ? 1 : 0);
Invalidate();
}
}
@@ -548,7 +548,7 @@ namespace OpenRCT2::Scripting
auto w = GetWindow();
if (w != nullptr)
{
return WidgetIsPressed(*w, _widgetIndex);
return Ui::WidgetIsPressed(*w, _widgetIndex);
}
return false;
}
@@ -557,7 +557,7 @@ namespace OpenRCT2::Scripting
auto w = GetWindow();
if (w != nullptr)
{
WidgetSetCheckboxValue(*w, _widgetIndex, value ? 1 : 0);
Ui::WidgetSetCheckboxValue(*w, _widgetIndex, value ? 1 : 0);
Invalidate();
}
}

View File

@@ -536,6 +536,7 @@ static constexpr colour_t kColoursDropdownOrder[] = {
} // namespace OpenRCT2::Ui::Windows
using namespace OpenRCT2::Ui::Windows;
using namespace OpenRCT2;
bool Dropdown::IsChecked(int32_t index)
{