diff --git a/openrct2.vcxproj b/openrct2.vcxproj
index 16dfe52ca6..73fe4a6021 100644
--- a/openrct2.vcxproj
+++ b/openrct2.vcxproj
@@ -53,7 +53,6 @@
-
@@ -110,6 +109,7 @@
+
@@ -179,7 +179,6 @@
-
diff --git a/openrct2.vcxproj.filters b/openrct2.vcxproj.filters
index df0b6eb8d6..3fddff8512 100644
--- a/openrct2.vcxproj.filters
+++ b/openrct2.vcxproj.filters
@@ -453,12 +453,6 @@
Source\Network
-
- Source\Interface
-
-
- Source\Windows
-
Source\Windows
@@ -586,6 +580,7 @@
Source\Interface
+
diff --git a/src/config.h b/src/config.h
index 60f733f26c..6372bfeecd 100644
--- a/src/config.h
+++ b/src/config.h
@@ -253,13 +253,6 @@ typedef struct {
bool guest_died;
} notification_configuration;
-typedef struct theme_window {
- uint8 colours[6];
-
- // Define any other settings for all windows here
-
-} theme_window;
-
// Define structures for any other settings here
typedef struct {
uint8 rct1_ride_lights;
diff --git a/src/core/Path.cpp b/src/core/Path.cpp
index 90b8e0f031..514f53ddeb 100644
--- a/src/core/Path.cpp
+++ b/src/core/Path.cpp
@@ -18,11 +18,26 @@ namespace Path
return safe_strcat_path(buffer, src, bufferSize);
}
+ utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path)
+ {
+ const char pathSeperator = platform_get_path_separator();
+ size_t lastPathSepIndex = String::LastIndexOf(path, pathSeperator);
+ if (lastPathSepIndex == SIZE_MAX)
+ {
+ return String::Set(buffer, bufferSize, String::Empty);
+ }
+
+ size_t copyLength = Math::Min(lastPathSepIndex, bufferSize - 1);
+ Memory::Copy(buffer, path, copyLength);
+ buffer[copyLength] = '\0';
+ return buffer;
+ }
+
utf8 * GetFileNameWithoutExtension(utf8 * buffer, size_t bufferSize, const utf8 * path)
{
const utf8 * lastDot = nullptr;
const utf8 * ch = path;
- for (; ch != '\0'; ch++)
+ for (; *ch != '\0'; ch++)
{
if (*ch == '.')
{
diff --git a/src/core/Path.hpp b/src/core/Path.hpp
index 1186f86e51..b3aa163f72 100644
--- a/src/core/Path.hpp
+++ b/src/core/Path.hpp
@@ -8,6 +8,7 @@ extern "C"
namespace Path
{
utf8 * Append(utf8 * buffer, size_t bufferSize, const utf8 * src);
+ utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path);
utf8 * GetFileNameWithoutExtension(utf8 * buffer, size_t bufferSize, const utf8 * path);
utf8 * GetAbsolute(utf8 * buffer, size_t bufferSize, const utf8 * relativePath);
bool Equals(const utf8 * a, const utf8 * b);
diff --git a/src/core/String.cpp b/src/core/String.cpp
index ba000bc7f7..ca1a7f97a9 100644
--- a/src/core/String.cpp
+++ b/src/core/String.cpp
@@ -10,6 +10,11 @@ extern "C"
namespace String
{
+ bool IsNullOrEmpty(const utf8 * str)
+ {
+ return str == nullptr || str[0] == '\0';
+ }
+
bool Equals(const utf8 * a, const utf8 * b, bool ignoreCase)
{
if (a == b) return true;
@@ -51,6 +56,28 @@ namespace String
}
}
+ size_t LastIndexOf(const utf8 * str, utf8 match)
+ {
+ const utf8 * lastOccurance = nullptr;
+ const utf8 * ch = str;
+ for (; ch != '\0'; ch++)
+ {
+ if (*ch == match)
+ {
+ lastOccurance = ch;
+ }
+ }
+
+ if (lastOccurance == nullptr)
+ {
+ return SIZE_MAX;
+ }
+ else
+ {
+ return (size_t)(lastOccurance - str);
+ }
+ }
+
size_t LengthOf(const utf8 * str)
{
return utf8_length(str);
@@ -137,7 +164,7 @@ namespace String
return replacement;
}
- utf8 * DiscardDuplicate(utf8 * * ptr, utf8 * replacement)
+ utf8 * DiscardDuplicate(utf8 * * ptr, const utf8 * replacement)
{
return DiscardUse(ptr, String::Duplicate(replacement));
}
diff --git a/src/core/String.hpp b/src/core/String.hpp
index c286ebd27e..7af30db4f4 100644
--- a/src/core/String.hpp
+++ b/src/core/String.hpp
@@ -9,8 +9,10 @@ namespace String
{
constexpr utf8 * Empty = "";
+ bool IsNullOrEmpty(const utf8 * str);
bool Equals(const utf8 * a, const utf8 * b, bool ignoreCase = false);
bool StartsWith(const utf8 * str, const utf8 * match, bool ignoreCase = false);
+ size_t LastIndexOf(const utf8 * str, utf8 match);
/**
* Gets the length of the given string in codepoints.
@@ -37,7 +39,7 @@ namespace String
/**
* Helper method to free the string a string pointer points to and set it to a copy of a replacement string.
*/
- utf8 * DiscardDuplicate(utf8 * * ptr, utf8 * replacement);
+ utf8 * DiscardDuplicate(utf8 * * ptr, const utf8 * replacement);
utf8 * SkipBOM(utf8 * buffer);
const utf8 * SkipBOM(const utf8 * buffer);
diff --git a/src/interface/Theme.cpp b/src/interface/Theme.cpp
index f40961a88c..6459751713 100644
--- a/src/interface/Theme.cpp
+++ b/src/interface/Theme.cpp
@@ -3,6 +3,7 @@
extern "C"
{
#include "../common.h"
+ #include "../config.h"
#include "themes.h"
#include "window.h"
}
@@ -55,6 +56,7 @@ public:
UITheme(const UITheme & name);
~UITheme();
+ void SetName(const utf8 * name);
const UIThemeWindowEntry * GetEntry(rct_windowclass windowClass) const;
void SetEntry(const UIThemeWindowEntry * entry);
void RemoveEntry(rct_windowclass windowClass);
@@ -290,6 +292,11 @@ UITheme::~UITheme()
Memory::Free(Name);
}
+void UITheme::SetName(const utf8 * name)
+{
+ String::DiscardDuplicate(&Name, name);
+}
+
const UIThemeWindowEntry * UITheme::GetEntry(rct_windowclass windowClass) const
{
for (size_t i = 0; i < Entries.GetCount(); i++)
@@ -363,7 +370,7 @@ bool UITheme::WriteToFile(const utf8 * path) const
bool result;
try
{
- Json::WriteToFile(path, jsonTheme, JSON_INDENT(4));
+ Json::WriteToFile(path, jsonTheme, JSON_INDENT(4) | JSON_PRESERVE_ORDER);
result = true;
}
catch (Exception ex)
@@ -386,10 +393,6 @@ UITheme * UITheme::FromJson(const json_t * json)
json_t * jsonEntries = json_object_get(json, "entries");
size_t numEntries = json_object_size(jsonEntries);
- if (numEntries == 0)
- {
- ThrowThemeLoadException();
- }
UITheme * result = nullptr;
try
@@ -441,6 +444,7 @@ UITheme * UITheme::FromFile(const utf8 * path)
}
catch (Exception ex)
{
+ log_error("Unable to read theme: %s", path);
result = nullptr;
}
@@ -470,15 +474,17 @@ namespace ThemeManager
struct AvailableTheme
{
utf8 Path[MAX_PATH];
- utf8 Name[64];
+ utf8 Name[96];
};
- const utf8 * CurrentThemePath;
+ utf8 * CurrentThemePath;
UITheme * CurrentTheme;
List AvailableThemes;
size_t ActiveAvailableThemeIndex = SIZE_MAX;
size_t NumPredefinedThemes = 0;
+ void GetThemeFileName(utf8 * buffer, size_t bufferSize, const utf8 * name);
+
void GetAvailableThemes(List * outThemes)
{
Guard::ArgumentNotNull(outThemes);
@@ -500,33 +506,44 @@ namespace ThemeManager
platform_get_user_directory(themesPattern, "themes");
Path::Append(themesPattern, sizeof(themesPattern), "*.json");
- utf8 path[MAX_PATH];
int handle = platform_enumerate_files_begin(themesPattern);
- while (platform_enumerate_directories_next(handle, path))
+ if (handle != INVALID_HANDLE)
{
- AvailableTheme theme;
- String::Set(theme.Path, sizeof(theme.Path), path);
- Path::GetFileNameWithoutExtension(theme.Path, sizeof(theme.Path), path);
- outThemes->Add(theme);
-
- if (Path::Equals(CurrentThemePath, path))
+ file_info fileInfo;
+ while (platform_enumerate_files_next(handle, &fileInfo))
{
- ActiveAvailableThemeIndex = outThemes->GetCount() - 1;
+ AvailableTheme theme;
+ Path::GetFileNameWithoutExtension(theme.Name, sizeof(theme.Name), fileInfo.path);
+ GetThemeFileName(theme.Path, sizeof(theme.Path), theme.Name);
+
+ outThemes->Add(theme);
+
+ if (Path::Equals(CurrentThemePath, fileInfo.path))
+ {
+ ActiveAvailableThemeIndex = outThemes->GetCount() - 1;
+ }
}
+ platform_enumerate_files_end(handle);
}
}
void LoadTheme(UITheme * theme)
{
+ if (CurrentTheme == theme)
+ {
+ return;
+ }
+
if (CurrentTheme != nullptr)
{
- if (!(theme->Flags & UITHEME_FLAG_PREDEFINED))
+ if (!(CurrentTheme->Flags & UITHEME_FLAG_PREDEFINED))
{
delete CurrentTheme;
}
}
CurrentTheme = theme;
+ String::DiscardUse(&CurrentThemePath, nullptr);
gfx_invalidate_screen();
}
@@ -538,8 +555,35 @@ namespace ThemeManager
{
// Fall-back to default
theme = (UITheme *)&PredefinedThemeRCT2;
+ LoadTheme(theme);
}
- LoadTheme(theme);
+ else
+ {
+ LoadTheme(theme);
+ String::DiscardDuplicate(&CurrentThemePath, path);
+ }
+ }
+
+ bool LoadThemeByName(const utf8 * name)
+ {
+ for (size_t i = 0; i < ThemeManager::AvailableThemes.GetCount(); i++)
+ {
+ if (String::Equals(name, ThemeManager::AvailableThemes[i].Name))
+ {
+ const utf8 * path = ThemeManager::AvailableThemes[i].Path;
+ if (String::IsNullOrEmpty(path))
+ {
+ LoadTheme((UITheme *)PredefinedThemes[i]);
+ }
+ else
+ {
+ LoadTheme(ThemeManager::AvailableThemes[i].Path);
+ }
+ ActiveAvailableThemeIndex = i;
+ return true;
+ }
+ }
+ return false;
}
void Initialise()
@@ -547,6 +591,27 @@ namespace ThemeManager
ThemeManager::GetAvailableThemes(&ThemeManager::AvailableThemes);
LoadTheme((UITheme *)&PredefinedThemeRCT2);
ActiveAvailableThemeIndex = 1;
+
+ bool configValid = false;
+ if (!String::IsNullOrEmpty(gConfigInterface.current_theme_preset))
+ {
+ if (LoadThemeByName(gConfigInterface.current_theme_preset))
+ {
+ configValid = true;
+ }
+ }
+
+ if (!configValid)
+ {
+ String::DiscardDuplicate(&gConfigInterface.current_theme_preset, theme_manager_get_available_theme_name(1));
+ }
+ }
+
+ void GetThemeFileName(utf8 * buffer, size_t bufferSize, const utf8 * name)
+ {
+ platform_get_user_directory(buffer, "themes");
+ Path::Append(buffer, bufferSize, name);
+ String::Append(buffer, bufferSize, ".json");
}
}
@@ -587,8 +652,51 @@ extern "C"
{
const utf8 * path = ThemeManager::AvailableThemes[index].Path;
ThemeManager::LoadTheme(path);
+
+ // HACK Check if theme load failed and fell back to RCT2
+ if (ThemeManager::CurrentThemePath == nullptr)
+ {
+ index = 1;
+ }
}
ThemeManager::ActiveAvailableThemeIndex = index;
+ String::DiscardDuplicate(&gConfigInterface.current_theme_preset, theme_manager_get_available_theme_name(index));
+ }
+
+ uint8 theme_get_colour(rct_windowclass wc, uint8 index)
+ {
+ const UIThemeWindowEntry * entry = ThemeManager::CurrentTheme->GetEntry(wc);
+ if (entry == nullptr)
+ {
+ const WindowThemeDesc * desc = GetWindowThemeDescriptor(wc);
+ return desc->DefaultTheme.Colours[index];
+ }
+ else
+ {
+ return entry->Theme.Colours[index];
+ }
+ }
+
+ void theme_set_colour(rct_windowclass wc, uint8 index, colour_t colour)
+ {
+ UIThemeWindowEntry entry;
+ entry.WindowClass = wc;
+
+ auto currentEntry = (UIThemeWindowEntry *)ThemeManager::CurrentTheme->GetEntry(wc);
+ if (currentEntry != nullptr)
+ {
+ entry.Theme = currentEntry->Theme;
+ }
+ else
+ {
+ const WindowThemeDesc * desc = GetWindowThemeDescriptor(wc);
+ entry.Theme = desc->DefaultTheme;
+ }
+
+ entry.Theme.Colours[index] = colour;
+ ThemeManager::CurrentTheme->SetEntry(&entry);
+
+ theme_save();
}
uint8 theme_get_flags()
@@ -596,11 +704,89 @@ extern "C"
return ThemeManager::CurrentTheme->Flags;
}
+ void theme_set_flags(uint8 flags)
+ {
+ ThemeManager::CurrentTheme->Flags = flags;
+ theme_save();
+ }
+
+ void theme_save()
+ {
+ ThemeManager::CurrentTheme->WriteToFile(ThemeManager::CurrentThemePath);
+ }
+
+ void theme_rename(const utf8 * name)
+ {
+ const utf8 * oldPath = ThemeManager::CurrentThemePath;
+ utf8 newPath[MAX_PATH];
+
+ ThemeManager::GetThemeFileName(newPath, sizeof(newPath), name);
+ platform_file_move(oldPath, newPath);
+ String::DiscardDuplicate(&ThemeManager::CurrentThemePath, newPath);
+
+ ThemeManager::CurrentTheme->SetName(name);
+ ThemeManager::CurrentTheme->WriteToFile(ThemeManager::CurrentThemePath);
+
+ theme_manager_load_available_themes();
+ for (size_t i = 0; i < ThemeManager::AvailableThemes.GetCount(); i++)
+ {
+ if (Path::Equals(newPath, ThemeManager::AvailableThemes[i].Path))
+ {
+ ThemeManager::ActiveAvailableThemeIndex = i;
+ String::DiscardDuplicate(&gConfigInterface.current_theme_preset, theme_manager_get_available_theme_name(1));
+ break;
+ }
+ }
+ }
+
+ void theme_duplicate(const utf8 * name)
+ {
+ utf8 newPath[MAX_PATH];
+
+ ThemeManager::GetThemeFileName(newPath, sizeof(newPath), name);
+ String::DiscardDuplicate(&ThemeManager::CurrentThemePath, newPath);
+
+ ThemeManager::CurrentTheme->SetName(name);
+ ThemeManager::CurrentTheme->Flags &= ~UITHEME_FLAG_PREDEFINED;
+ ThemeManager::CurrentTheme->WriteToFile(ThemeManager::CurrentThemePath);
+
+ theme_manager_load_available_themes();
+ for (size_t i = 0; i < ThemeManager::AvailableThemes.GetCount(); i++)
+ {
+ if (Path::Equals(newPath, ThemeManager::AvailableThemes[i].Path))
+ {
+ ThemeManager::ActiveAvailableThemeIndex = i;
+ String::DiscardDuplicate(&gConfigInterface.current_theme_preset, theme_manager_get_available_theme_name(i));
+ break;
+ }
+ }
+ }
+
+ void theme_delete()
+ {
+ platform_file_delete(ThemeManager::CurrentThemePath);
+ ThemeManager::LoadTheme((UITheme *)&PredefinedThemeRCT2);
+ ThemeManager::ActiveAvailableThemeIndex = 1;
+ String::DiscardDuplicate(&gConfigInterface.current_theme_preset, theme_manager_get_available_theme_name(1));
+ }
+
void theme_manager_initialise()
{
ThemeManager::Initialise();
}
+ uint8 theme_desc_get_num_colours(rct_windowclass wc)
+ {
+ const WindowThemeDesc * desc = GetWindowThemeDescriptor(wc);
+ return desc->NumColours;
+ }
+
+ rct_string_id theme_desc_get_name(rct_windowclass wc)
+ {
+ const WindowThemeDesc * desc = GetWindowThemeDescriptor(wc);
+ return desc->WindowName;
+ }
+
void colour_scheme_update(rct_window * window)
{
colour_scheme_update_by_class(window, window->classification);
diff --git a/src/interface/themes.c b/src/interface/themes.c
deleted file mode 100644
index 2fb4d36e5a..0000000000
--- a/src/interface/themes.c
+++ /dev/null
@@ -1,255 +0,0 @@
-#if 0
-
-/*****************************************************************************
-* Copyright (c) 2014 Ted John, Peter Hill
-* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
-*
-* This file is part of OpenRCT2.
-*
-* OpenRCT2 is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-*****************************************************************************/
-
-#include "../localisation/string_ids.h"
-#include "../util/util.h"
-#include "colour.h"
-#include "window.h"
-#include "themes.h"
-
-#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 } }
-#define COLOURS_4(c0, c1, c2, c3) 4, { { (c0), (c1), (c2), (c3), 0, 0 } }
-#define COLOURS_5(c0, c1, c2, c3, c4) 5, { { (c0), (c1), (c2), (c3), (c4), 0 } }
-#define COLOURS_6(c0, c1, c2, c3, c4, c5) 6, { { (c0), (c1), (c2), (c3), (c4), (c5) } }
-
-#define THEME_DEF_END { 0xFF, { 0, 0, 0, 0, 0, 0 } }
-
-#define TWINDOW(window_class, window_name, window_string_id, theme) { window_class, window_name, window_string_id, theme }
-
-theme_window_definition gThemeWindowDefinitions[] = {
- /* Window Class ini section name stringid window defaults */
- { WC_TOP_TOOLBAR, "top_toolbar", 5245, COLOURS_4(COLOUR_LIGHT_BLUE, COLOUR_DARK_GREEN, COLOUR_DARK_BROWN, COLOUR_GREY ) },
- { WC_BOTTOM_TOOLBAR, "bottom_toolbar", 5246, COLOURS_4(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), COLOUR_BLACK, COLOUR_BRIGHT_GREEN ) },
- { WC_RIDE, "ride", 5203, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_GREY ) },
- { WC_RIDE_CONSTRUCTION, "ride_construction", 5199, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
- { WC_RIDE_LIST, "ride_list", 5204, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
- { WC_SAVE_PROMPT, "save_prompt", 5223, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
- { WC_CONSTRUCT_RIDE, "new_ride", 5201, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
- { WC_DEMOLISH_RIDE_PROMPT, "demolish_ride_prompt", 5224, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
- { WC_SCENERY, "scenery", 5197, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) },
- { WC_OPTIONS, "options", 5219, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
- { WC_FOOTPATH, "footpath", 5198, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
- { WC_LAND, "land", 5193, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
- { WC_WATER, "water", 5194, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
- { WC_PEEP, "guest", 5205, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
- { WC_GUEST_LIST, "guest_list", 5206, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
- { WC_STAFF_LIST, "staff_list", 5208, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) },
- { WC_FIRE_PROMPT, "staff_fire_prompt", 5225, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
- { WC_PARK_INFORMATION, "park_information", 5253, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
- { WC_FINANCES, "finances", 5187, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
- { WC_TITLE_MENU, "title_menu", 5249, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
- { WC_TITLE_EXIT, "title_exit", 5250, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
- { WC_RECENT_NEWS, "recent_news", 5192, COLOURS_3(COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK ) },
- { WC_SCENARIO_SELECT, "scenario_select", 5252, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
- { WC_TRACK_DESIGN_LIST, "track_design_list", 5202, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
- { WC_TRACK_DESIGN_PLACE, "track_design_place", 5200, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
- { WC_NEW_CAMPAIGN, "new_campaign", 5188, COLOURS_3(COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
- { WC_KEYBOARD_SHORTCUT_LIST, "keyboard_shortcuts", 5220, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
- { WC_CHANGE_KEYBOARD_SHORTCUT, "change_keyboard_shortcut", 5221, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
- { WC_MAP, "map", 5190, COLOURS_2(COLOUR_DARK_GREEN, COLOUR_DARK_BROWN ) },
- { WC_BANNER, "banner", 5209, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
- { WC_EDITOR_OBJECT_SELECTION, "editor_object_selection", 5210, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
- { WC_EDITOR_INVENTION_LIST, "editor_invention_list", 5211, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
- { WC_EDITOR_SCENARIO_OPTIONS, "editor_scenario_options", 5212, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
- { WC_EDTIOR_OBJECTIVE_OPTIONS, "editor_objection_options", 5213, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
- { WC_MANAGE_TRACK_DESIGN, "manage_track_design", 5215, COLOURS_3(COLOUR_GREY, COLOUR_GREY, COLOUR_GREY ) },
- { WC_TRACK_DELETE_PROMPT, "track_delete_prompt", 5226, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
- { WC_INSTALL_TRACK, "install_track", 5216, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
- { WC_CLEAR_SCENERY, "clear_scenery", 5195, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
- { WC_CHEATS, "cheats", 5217, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
- { WC_RESEARCH, "research", 5189, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
- { WC_VIEWPORT, "viewport", 5191, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
- { WC_MAPGEN, "map_generation", 5214, COLOURS_3(COLOUR_DARK_GREEN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
- { WC_LOADSAVE, "loadsave", 5222, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
- { WC_LOADSAVE_OVERWRITE_PROMPT, "loadsave_overwrite_prompt", 5227, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
- { WC_TITLE_OPTIONS, "title_options", 5251, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
- { WC_LAND_RIGHTS, "land_rights", 5196, COLOURS_3(COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
- { WC_THEMES, "themes", 5218, COLOURS_3(COLOUR_GREY, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) },
- { WC_STAFF, "staff", 5207, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) },
- { WC_EDITOR_TRACK_BOTTOM_TOOLBAR, "editor_track_bottom_toolbar", 5247, COLOURS_3(TRANSLUCENT(COLOUR_LIGHT_BLUE), TRANSLUCENT(COLOUR_LIGHT_BLUE), TRANSLUCENT(COLOUR_LIGHT_BLUE) ) },
- { WC_EDITOR_SCENARIO_BOTTOM_TOOLBAR, "editor_scenario_bottom_toolbar", 5248, COLOURS_3(TRANSLUCENT(COLOUR_LIGHT_BROWN), TRANSLUCENT(COLOUR_LIGHT_BROWN), TRANSLUCENT(COLOUR_MOSS_GREEN) ) },
- { WC_TITLE_EDITOR, "title_sequences", 5433, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
-};
-
-#define COLOURS_RCT1(c0, c1, c2, c3, c4, c5) { { (c0), (c1), (c2), (c3), (c4), (c5) } }
-
-theme_window_preset gThemeWindowsRCT1[] = {
- { WC_TOP_TOOLBAR, COLOURS_RCT1(COLOUR_GREY, COLOUR_GREY, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_BOTTOM_TOOLBAR, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_YELLOW, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_RIDE, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_SATURATED_GREEN, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_RIDE_LIST, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_CONSTRUCT_RIDE, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_PEEP, COLOURS_RCT1(COLOUR_LIGHT_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_GUEST_LIST, COLOURS_RCT1(COLOUR_LIGHT_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_STAFF_LIST, COLOURS_RCT1(COLOUR_DARK_GREEN, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_FINANCES, COLOURS_RCT1(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_TITLE_MENU, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_TITLE_EXIT, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_NEW_CAMPAIGN, COLOURS_RCT1(COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_TITLE_OPTIONS, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- { WC_STAFF, COLOURS_RCT1(COLOUR_DARK_GREEN, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
- THEME_DEF_END
-};
-
-uint16 gCurrentTheme = 0;
-uint32 gNumThemeWindows = sizeof(gThemeWindowDefinitions) / sizeof(theme_window_definition);
-
-
-theme_preset* theme_get_preset()
-{
- return &gConfigThemes.presets[gCurrentTheme];
-}
-
-theme_window_definition* theme_window_definition_get_by_class(rct_windowclass classification)
-{
- for (int i = 0; i < (int)gNumThemeWindows; i++) {
- if (gThemeWindowDefinitions[i].classification == classification) {
- return &gThemeWindowDefinitions[i];
- }
- }
- return NULL;
-}
-
-theme_window* theme_window_get_by_class(rct_windowclass classification)
-{
- for (int i = 0; i < (int)gNumThemeWindows; i++) {
- if (gThemeWindowDefinitions[i].classification == classification) {
- return &gConfigThemes.presets[gCurrentTheme].windows[i];
- }
- }
- return NULL;
-}
-
-void colour_scheme_update(rct_window *window)
-{
- theme_window* theme = theme_window_get_by_class(window->classification);
-
- bool transparent = false;
- for (int i = 0; i < 6; i++) {
- window->colours[i] = theme->colours[i];
- if (theme->colours[i] & 0x80) {
- transparent = true;
- }
- }
- // 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;
-}
-
-void colour_scheme_update_by_class(rct_window *window, rct_windowclass classification)
-{
- theme_window* theme = theme_window_get_by_class(classification);
-
- bool transparent = false;
- for (int i = 0; i < 6; i++) {
- window->colours[i] = theme->colours[i];
- if (theme->colours[i] & 0x80) {
- transparent = true;
- }
- }
- // 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;
-}
-
-static void theme_set_preset_string(const utf8string preset)
-{
- SafeFree(gConfigInterface.current_theme_preset);
- gConfigInterface.current_theme_preset = _strdup(preset);
-}
-
-void theme_change_preset(int preset)
-{
- if (preset >= 0 && preset < gConfigThemes.num_presets) {
- switch (preset) {
- case 0:
- theme_set_preset_string("*RCT2");
- break;
- case 1:
- theme_set_preset_string("*RCT1");
- break;
- default:
- theme_set_preset_string(gConfigThemes.presets[preset].name);
- break;
- }
- gCurrentTheme = preset;
- }
- window_invalidate_all();
-}
-
-void theme_create_preset(int duplicate, const char *name)
-{
- int preset = gConfigThemes.num_presets;
- gConfigThemes.num_presets++;
- gConfigThemes.presets = realloc(gConfigThemes.presets, sizeof(theme_preset) * gConfigThemes.num_presets);
- safe_strcpy(gConfigThemes.presets[preset].name, name, THEME_PRESET_NAME_SIZE);
- gConfigThemes.presets[preset].windows = malloc(sizeof(theme_window) * gNumThemeWindows);
- for (int i = 0; i < (int)gNumThemeWindows; i++) {
- gConfigThemes.presets[preset].windows[i] = gConfigThemes.presets[duplicate].windows[i];
- }
- gConfigThemes.presets[preset].features = gConfigThemes.presets[duplicate].features;
- themes_save_preset(preset);
- theme_change_preset(preset);
-}
-
-void theme_delete_preset(int preset)
-{
- if (preset >= 2) {
- utf8 path[MAX_PATH];
- platform_get_user_directory(path, "themes");
- strcat(path, gConfigThemes.presets[preset].name);
- strcat(path, ".ini");
- platform_file_delete(path);
-
- free(gConfigThemes.presets[preset].windows);
-
- for (int i = preset; i < gConfigThemes.num_presets - 1; i++) {
- gConfigThemes.presets[i] = gConfigThemes.presets[i + 1];
- }
- gConfigThemes.num_presets--;
- theme_change_preset(0);
- }
-}
-
-void theme_rename_preset(int preset, const char *newName)
-{
- if (preset >= 2) {
- utf8 src[MAX_PATH], dest[MAX_PATH];
- platform_get_user_directory(src, "themes");
- platform_get_user_directory(dest, "themes");
- strcat(src, gConfigThemes.presets[preset].name);
- strcat(dest, newName);
- strcat(src, ".ini");
- strcat(dest, ".ini");
- platform_file_move(src, dest);
-
- safe_strcpy(gConfigThemes.presets[preset].name, newName, THEME_PRESET_NAME_SIZE);
-
- if (preset == gCurrentTheme) {
- gConfigInterface.current_theme_preset = gConfigThemes.presets[preset].name;
- }
- }
-}
-
-#endif
diff --git a/src/interface/themes.h b/src/interface/themes.h
index fb5feda672..3de9401afc 100644
--- a/src/interface/themes.h
+++ b/src/interface/themes.h
@@ -42,48 +42,16 @@ const utf8 * theme_manager_get_available_theme_name(size_t index);
size_t theme_manager_get_active_available_theme_index();
void theme_manager_set_active_available_theme(size_t index);
-uint8 theme_get_flags();
-
-
-#if 0
-
-
-
-#include "../config.h"
-
-typedef struct {
- rct_windowclass classification;
- char *section_name;
- rct_string_id name;
- uint8 num_colours;
- theme_window window;
-} theme_window_definition;
-
-typedef struct {
- rct_windowclass classification;
- theme_window window;
-} theme_window_preset;
-
-// The definitions for window themes as well as the RCT2 preset
-extern theme_window_definition gThemeWindowDefinitions[];
-// The preset for RCT1 window themes
-extern theme_window_preset gThemeWindowsRCT1[];
-
-// The index of the current theme
-extern uint16 gCurrentTheme;
-// The number of theme-able windows
-extern uint32 gNumThemeWindows;
-
-theme_preset* theme_get_preset();
-theme_window_definition* theme_window_definition_get_by_class(rct_windowclass classification);
-theme_window* theme_window_get_by_class(rct_windowclass classification);
-
-void theme_change_preset(int preset);
-void theme_create_preset(int duplicate, const char *name);
-void theme_delete_preset(int preset);
-void theme_rename_preset(int preset, const char *newName);
-
-#endif
+colour_t theme_get_colour(rct_windowclass wc, uint8 index);
+void theme_set_colour(rct_windowclass wc, uint8 index, colour_t colour);
+uint8 theme_get_flags();
+void theme_set_flags(uint8 flags);
+void theme_save();
+void theme_rename(const utf8 * name);
+void theme_duplicate(const utf8 * name);
+void theme_delete();
+uint8 theme_desc_get_num_colours(rct_windowclass wc);
+rct_string_id theme_desc_get_name(rct_windowclass wc);
#endif
diff --git a/src/windows/themes.c b/src/windows/themes.c
index 6e9da3803d..eddb70fe94 100644
--- a/src/windows/themes.c
+++ b/src/windows/themes.c
@@ -36,8 +36,6 @@
#include "error.h"
#include "../util/util.h"
-#if 0
-
enum {
WINDOW_THEMES_TAB_SETTINGS,
WINDOW_THEMES_TAB_MAIN_UI,
@@ -256,6 +254,17 @@ static rct_windowclass window_themes_tab_7_classes[] = {
WC_LOADSAVE_OVERWRITE_PROMPT
};
+static rct_windowclass *window_themes_tab_classes[] = {
+ NULL,
+ window_themes_tab_1_classes,
+ window_themes_tab_2_classes,
+ window_themes_tab_3_classes,
+ window_themes_tab_4_classes,
+ window_themes_tab_5_classes,
+ window_themes_tab_6_classes,
+ window_themes_tab_7_classes,
+};
+
static uint8 _selected_tab = 0;
static sint16 _color_index_1 = -1;
static sint8 _color_index_2 = -1;
@@ -269,57 +278,10 @@ void window_themes_init_vars()
_selected_tab = WINDOW_THEMES_TAB_SETTINGS;
}
-static theme_window_definition* get_colour_scheme_tab_definition()
+static rct_windowclass get_window_class_tab_index(int index)
{
- switch (_selected_tab) {
- case 1: return theme_window_definition_get_by_class(window_themes_tab_1_classes[_color_index_1]);
- case 2: return theme_window_definition_get_by_class(window_themes_tab_2_classes[_color_index_1]);
- case 3: return theme_window_definition_get_by_class(window_themes_tab_3_classes[_color_index_1]);
- case 4: return theme_window_definition_get_by_class(window_themes_tab_4_classes[_color_index_1]);
- case 5: return theme_window_definition_get_by_class(window_themes_tab_5_classes[_color_index_1]);
- case 6: return theme_window_definition_get_by_class(window_themes_tab_6_classes[_color_index_1]);
- case 7: return theme_window_definition_get_by_class(window_themes_tab_7_classes[_color_index_1]);
- }
- return NULL;
-}
-static theme_window_definition* get_colour_scheme_tab_definition_by_index(int index)
-{
- switch (_selected_tab) {
- case 1: return theme_window_definition_get_by_class(window_themes_tab_1_classes[index]);
- case 2: return theme_window_definition_get_by_class(window_themes_tab_2_classes[index]);
- case 3: return theme_window_definition_get_by_class(window_themes_tab_3_classes[index]);
- case 4: return theme_window_definition_get_by_class(window_themes_tab_4_classes[index]);
- case 5: return theme_window_definition_get_by_class(window_themes_tab_5_classes[index]);
- case 6: return theme_window_definition_get_by_class(window_themes_tab_6_classes[index]);
- case 7: return theme_window_definition_get_by_class(window_themes_tab_7_classes[index]);
- }
- return NULL;
-}
-static theme_window* get_colour_scheme_tab()
-{
- switch (_selected_tab) {
- case 1: return theme_window_get_by_class(window_themes_tab_1_classes[_color_index_1]);
- case 2: return theme_window_get_by_class(window_themes_tab_2_classes[_color_index_1]);
- case 3: return theme_window_get_by_class(window_themes_tab_3_classes[_color_index_1]);
- case 4: return theme_window_get_by_class(window_themes_tab_4_classes[_color_index_1]);
- case 5: return theme_window_get_by_class(window_themes_tab_5_classes[_color_index_1]);
- case 6: return theme_window_get_by_class(window_themes_tab_6_classes[_color_index_1]);
- case 7: return theme_window_get_by_class(window_themes_tab_7_classes[_color_index_1]);
- }
- return NULL;
-}
-static theme_window* get_colour_scheme_tab_by_index(int index)
-{
- switch (_selected_tab) {
- case 1: return theme_window_get_by_class(window_themes_tab_1_classes[index]);
- case 2: return theme_window_get_by_class(window_themes_tab_2_classes[index]);
- case 3: return theme_window_get_by_class(window_themes_tab_3_classes[index]);
- case 4: return theme_window_get_by_class(window_themes_tab_4_classes[index]);
- case 5: return theme_window_get_by_class(window_themes_tab_5_classes[index]);
- case 6: return theme_window_get_by_class(window_themes_tab_6_classes[index]);
- case 7: return theme_window_get_by_class(window_themes_tab_7_classes[index]);
- }
- return NULL;
+ rct_windowclass * classes = window_themes_tab_classes[_selected_tab];
+ return classes[index];
}
static int get_colour_scheme_tab_count()
@@ -336,19 +298,6 @@ static int get_colour_scheme_tab_count()
return 0;
}
-/*static int get_colour_scheme_index() {
- switch (_selected_tab) {
- case 1: return theme_window_get_index_by_class(window_themes_tab_1_classes[_color_index_1]);
- case 2: return theme_window_get_index_by_class(window_themes_tab_2_classes[_color_index_1]);
- case 3: return theme_window_get_index_by_class(window_themes_tab_3_classes[_color_index_1]);
- case 4: return theme_window_get_index_by_class(window_themes_tab_4_classes[_color_index_1]);
- case 5: return theme_window_get_index_by_class(window_themes_tab_5_classes[_color_index_1]);
- case 6: return theme_window_get_index_by_class(window_themes_tab_6_classes[_color_index_1]);
- case 7: return theme_window_get_index_by_class(window_themes_tab_7_classes[_color_index_1]);
- }
- return -1;
-}*/
-
static void window_themes_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w)
{
int sprite_idx;
@@ -407,27 +356,32 @@ void window_themes_open()
static void window_themes_mouseup(rct_window *w, int widgetIndex)
{
+ int activeAvailableThemeIndex;
+ const utf8 * activeThemeName;
+
switch (widgetIndex) {
case WIDX_THEMES_CLOSE:
window_close(w);
break;
- case WIDX_THEMES_DUPLICATE_BUTTON:
- window_text_input_open(w, widgetIndex, 5239, 5240, 1170, (uint32)&gConfigThemes.presets[gCurrentTheme].name, 64);
+ case WIDX_THEMES_DUPLICATE_BUTTON:;
+ activeAvailableThemeIndex = theme_manager_get_active_available_theme_index();
+ activeThemeName = theme_manager_get_available_theme_name(activeAvailableThemeIndex);
+ window_text_input_open(w, widgetIndex, 5239, 5240, 1170, (uint32)activeThemeName, 64);
break;
case WIDX_THEMES_DELETE_BUTTON:
- if (gCurrentTheme >= 2) {
- theme_delete_preset(gCurrentTheme);
- }
- else {
+ if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
window_error_open(5241, STR_NONE);
+ } else {
+ theme_delete();
}
break;
case WIDX_THEMES_RENAME_BUTTON:
- if (gCurrentTheme >= 2) {
- window_text_input_open(w, widgetIndex, 3348, 5240, 1170, (uint32)&gConfigThemes.presets[gCurrentTheme].name, 64);
- }
- else {
+ if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
window_error_open(5241, STR_NONE);
+ } else {
+ activeAvailableThemeIndex = theme_manager_get_active_available_theme_index();
+ activeThemeName = theme_manager_get_available_theme_name(activeAvailableThemeIndex);
+ window_text_input_open(w, widgetIndex, 3348, 5240, 1170, (uint32)activeThemeName, 64);
}
break;
}
@@ -509,7 +463,7 @@ static void window_themes_resize(rct_window *w)
static void window_themes_mousedown(int widgetIndex, rct_window* w, rct_widget* widget)
{
short newSelectedTab;
- int num_items, i;
+ int num_items;
switch (widgetIndex) {
case WIDX_THEMES_SETTINGS_TAB:
@@ -531,19 +485,15 @@ static void window_themes_mousedown(int widgetIndex, rct_window* w, rct_widget*
window_invalidate(w);
break;
case WIDX_THEMES_PRESETS_DROPDOWN:
- num_items = gConfigThemes.num_presets;
+ theme_manager_load_available_themes();
+ num_items = (int)theme_manager_get_num_available_themes();
widget--;
- gDropdownItemsFormat[0] = 2777;
- gDropdownItemsArgs[0] = (uint32)&gConfigThemes.presets[1].name;
- gDropdownItemsFormat[1] = 2777;
- gDropdownItemsArgs[1] = (uint32)&gConfigThemes.presets[0].name;
-
- for (i = 2; i < num_items; i++) {
+ for (int i = 0; i < num_items; i++) {
gDropdownItemsFormat[i] = 2777;
- gDropdownItemsArgs[i] = (uint32)&gConfigThemes.presets[i].name;
+ gDropdownItemsArgs[i] = (uint32)theme_manager_get_available_theme_name(i);
}
-
+
window_dropdown_show_text_custom_width(
w->x + widget->left,
w->y + widget->top,
@@ -552,42 +502,35 @@ static void window_themes_mousedown(int widgetIndex, rct_window* w, rct_widget*
DROPDOWN_FLAG_STAY_OPEN,
num_items,
widget->right - widget->left - 3
- );
+ );
- if (gCurrentTheme == 0 || gCurrentTheme == 1) {
- dropdown_set_checked(gCurrentTheme ^ 1, true);
- } else {
- dropdown_set_checked(gCurrentTheme, true);
- }
+ dropdown_set_checked(theme_manager_get_active_available_theme_index(), true);
break;
case WIDX_THEMES_RCT1_RIDE_LIGHTS:
- if (gCurrentTheme >= 2) {
- theme_get_preset()->features.rct1_ride_lights ^= 1;
- themes_save_preset(gCurrentTheme);
- window_invalidate_all();
- }
- else {
+ if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
window_error_open(5241, STR_NONE);
+ } else {
+ theme_set_flags(theme_get_flags() ^ UITHEME_FLAG_USE_LIGHTS_RIDE);
+ theme_save();
+ window_invalidate_all();
}
break;
case WIDX_THEMES_RCT1_PARK_LIGHTS:
- if (gCurrentTheme >= 2) {
- theme_get_preset()->features.rct1_park_lights ^= 1;
- themes_save_preset(gCurrentTheme);
- window_invalidate_all();
- }
- else {
+ if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
window_error_open(5241, STR_NONE);
+ } else {
+ theme_set_flags(theme_get_flags() ^ UITHEME_FLAG_USE_LIGHTS_PARK);
+ theme_save();
+ window_invalidate_all();
}
break;
case WIDX_THEMES_RCT1_SCENARIO_FONT:
- if (gCurrentTheme >= 2) {
- theme_get_preset()->features.rct1_scenario_font ^= 1;
- themes_save_preset(gCurrentTheme);
- window_invalidate_all();
- }
- else {
+ if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
window_error_open(5241, STR_NONE);
+ } else {
+ theme_set_flags(theme_get_flags() ^ UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT);
+ theme_save();
+ window_invalidate_all();
}
break;
}
@@ -598,22 +541,22 @@ static void window_themes_dropdown(rct_window *w, int widgetIndex, int dropdownI
switch (widgetIndex) {
case WIDX_THEMES_LIST:
if (dropdownIndex != -1) {
- get_colour_scheme_tab()->colours[_color_index_2] = dropdownIndex | (get_colour_scheme_tab()->colours[_color_index_2] & 0x80);
+ rct_windowclass wc = get_window_class_tab_index(_color_index_1);
+ uint8 colour = theme_get_colour(wc, _color_index_2);
+ colour = (colour & COLOUR_FLAG_TRANSLUCENT) | dropdownIndex;
+ theme_set_colour(wc, _color_index_2, colour);
window_invalidate_all();
_color_index_1 = -1;
_color_index_2 = -1;
- if (gCurrentTheme >= 2)
- themes_save_preset(gCurrentTheme);
+ // if (gCurrentTheme >= 2)
+ // themes_save_preset(gCurrentTheme);
}
break;
case WIDX_THEMES_PRESETS_DROPDOWN:
if (dropdownIndex != -1) {
- if (dropdownIndex == 0 || dropdownIndex == 1)
- dropdownIndex ^= 1;
- theme_change_preset(dropdownIndex);
+ theme_manager_set_active_available_theme(dropdownIndex);
}
- config_save_default();
break;
}
@@ -653,33 +596,36 @@ void window_themes_scrollmousedown(rct_window *w, int scrollIndex, int x, int y)
int y2 = y % _row_height;
_color_index_1 = y / _row_height;
_color_index_2 = ((x - _button_offset_x) / 12);
- if (_color_index_2 < get_colour_scheme_tab_definition()->num_colours) {
+
+ rct_windowclass wc = get_window_class_tab_index(_color_index_1);
+ int numColours = theme_desc_get_num_colours(wc);
+ if (_color_index_2 < numColours) {
if (x >= _button_offset_x && x < _button_offset_x + 12 * 6 && y2 >= _button_offset_y && y2 < _button_offset_y + 11) {
- if (gCurrentTheme >= 2) {
+ if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
+ window_error_open(5241, 5256);
+ } else {
window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].left = _button_offset_x + _color_index_2 * 12 + window_themes_widgets[WIDX_THEMES_LIST].left;
window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].top = _color_index_1 * _row_height + _button_offset_y - w->scrolls[0].v_top + window_themes_widgets[WIDX_THEMES_LIST].top;
window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].right = window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].left + 12;
window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].bottom = window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].top + 12;
- window_dropdown_show_colour(w, &(window_themes_widgets[WIDX_THEMES_COLORBTN_MASK]), w->colours[1], get_colour_scheme_tab()->colours[_color_index_2]);
+
+ uint8 colour = theme_get_colour(wc, _color_index_2);
+ window_dropdown_show_colour(w, &(window_themes_widgets[WIDX_THEMES_COLORBTN_MASK]), w->colours[1], colour);
widget_invalidate(w, WIDX_THEMES_LIST);
}
- else {
- window_error_open(5241, 5256);
- }
}
else if (x >= _button_offset_x && x < _button_offset_x + 12 * 6 - 1 && y2 >= _check_offset_y && y2 < _check_offset_y + 11) {
- if (gCurrentTheme >= 2) {
- if (get_colour_scheme_tab()->colours[_color_index_2] & 0x80) {
- get_colour_scheme_tab()->colours[_color_index_2] &= 0x7F;
- }
- else {
- get_colour_scheme_tab()->colours[_color_index_2] |= 0x80;
- }
- themes_save_preset(gCurrentTheme);
- window_invalidate_all();
- }
- else {
+ if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
window_error_open(5241, 5256);
+ } else {
+ uint8 colour = theme_get_colour(wc, _color_index_2);
+ if (colour & COLOUR_FLAG_TRANSLUCENT) {
+ colour &= ~COLOUR_FLAG_TRANSLUCENT;
+ } else {
+ colour |= COLOUR_FLAG_TRANSLUCENT;
+ }
+ theme_set_colour(wc, _color_index_2, colour);
+ window_invalidate_all();
}
}
}
@@ -702,25 +648,26 @@ static void window_themes_textinput(rct_window *w, int widgetIndex, char *text)
case WIDX_THEMES_RENAME_BUTTON:
if (filename_valid_characters(text)) {
bool nameTaken = false;
- for (int i = 0; i < gConfigThemes.num_presets; i++) {
- if (strcmp(gConfigThemes.presets[i].name, text) == 0) {
- window_error_open(5242, STR_NONE);
+ int numAvailableThemes = (int)theme_manager_get_num_available_themes();
+ for (int i = 0; i < numAvailableThemes; i++) {
+ const utf8 * themeName = theme_manager_get_available_theme_name(i);
+ if (strcmp(themeName, text) == 0) {
+ if (widgetIndex != WIDX_THEMES_RENAME_BUTTON) {
+ window_error_open(5242, STR_NONE);
+ }
nameTaken = true;
break;
}
}
if (!nameTaken) {
if (widgetIndex == WIDX_THEMES_DUPLICATE_BUTTON) {
- theme_create_preset(gCurrentTheme, text);
+ theme_duplicate(text);
+ } else {
+ theme_rename(text);
}
- else {
- theme_rename_preset(gCurrentTheme, text);
- }
- config_save_default();
window_invalidate(w);
}
- }
- else {
+ } else {
window_error_open(5243, STR_NONE);
}
break;
@@ -789,9 +736,9 @@ void window_themes_invalidate(rct_window *w)
window_themes_widgets[WIDX_THEMES_PRESETS].type = WWT_EMPTY;
window_themes_widgets[WIDX_THEMES_PRESETS_DROPDOWN].type = WWT_EMPTY;
- widget_set_checkbox_value(w, WIDX_THEMES_RCT1_RIDE_LIGHTS, theme_get_preset()->features.rct1_ride_lights);
- widget_set_checkbox_value(w, WIDX_THEMES_RCT1_PARK_LIGHTS, theme_get_preset()->features.rct1_park_lights);
- widget_set_checkbox_value(w, WIDX_THEMES_RCT1_SCENARIO_FONT, theme_get_preset()->features.rct1_scenario_font);
+ widget_set_checkbox_value(w, WIDX_THEMES_RCT1_RIDE_LIGHTS, theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_RIDE);
+ widget_set_checkbox_value(w, WIDX_THEMES_RCT1_PARK_LIGHTS, theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_PARK);
+ widget_set_checkbox_value(w, WIDX_THEMES_RCT1_SCENARIO_FONT, theme_get_flags() & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT);
}
else {
window_themes_widgets[WIDX_THEMES_LIST].type = WWT_SCROLL;
@@ -813,7 +760,9 @@ void window_themes_paint(rct_window *w, rct_drawpixelinfo *dpi)
window_themes_draw_tab_images(dpi, w);
if (_selected_tab == WINDOW_THEMES_TAB_SETTINGS) {
- RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32) = (uint32)&gConfigThemes.presets[gCurrentTheme].name;
+ int activeAvailableThemeIndex = theme_manager_get_active_available_theme_index();
+ const utf8 * activeThemeName = theme_manager_get_available_theme_name(activeAvailableThemeIndex);
+ RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32) = (uint32)activeThemeName;
gfx_draw_string_left(dpi, 5238, NULL, w->colours[1], w->x + 10, w->y + window_themes_widgets[WIDX_THEMES_PRESETS].top + 1);
gfx_draw_string_left_clipped(
dpi,
@@ -823,7 +772,7 @@ void window_themes_paint(rct_window *w, rct_drawpixelinfo *dpi)
w->x + window_themes_widgets[WIDX_THEMES_PRESETS].left + 1,
w->y + window_themes_widgets[WIDX_THEMES_PRESETS].top,
w->x + window_themes_widgets[WIDX_THEMES_PRESETS_DROPDOWN].left - window_themes_widgets[WIDX_THEMES_PRESETS].left - 4
- );
+ );
}
else if (_selected_tab == WINDOW_THEMES_TAB_FEATURES) {
@@ -871,18 +820,20 @@ void window_themes_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scroll
}
}
- for (int j = 0; j < get_colour_scheme_tab_definition_by_index(i)->num_colours; j++) {
+ rct_windowclass wc = get_window_class_tab_index(i);
+ int numColours = theme_desc_get_num_colours(wc);
+ for (uint8 j = 0; j < numColours; j++) {
+ gfx_draw_string_left(dpi, theme_desc_get_name(wc), NULL, w->colours[1], 2, y + 4);
- gfx_draw_string_left(dpi, get_colour_scheme_tab_definition_by_index(i)->name, NULL, w->colours[1], 2, y + 4);
-
- uint32 image = ((get_colour_scheme_tab_by_index(i)->colours[j] & 0x7F) << 19) + 0x600013C3;
+ uint8 colour = theme_get_colour(wc, j);
+ uint32 image = ((colour & ~COLOUR_FLAG_TRANSLUCENT) << 19) + 0x600013C3;
if (i == _color_index_1 && j == _color_index_2) {
- image = ((get_colour_scheme_tab_by_index(i)->colours[j] & 0x7F) << 19) + 0x600013C4;
+ image = ((colour & ~COLOUR_FLAG_TRANSLUCENT) << 19) + 0x600013C4;
}
gfx_draw_sprite(dpi, image, _button_offset_x + 12 * j, y + _button_offset_y, 0);
gfx_fill_rect_inset(dpi, _button_offset_x + 12 * j, y + _check_offset_y, _button_offset_x + 12 * j + 9, y + _check_offset_y + 10, w->colours[1], 0xE0);
- if (get_colour_scheme_tab_by_index(i)->colours[j] & 0x80) {
+ if (colour & COLOUR_FLAG_TRANSLUCENT) {
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = -1;
gfx_draw_string(dpi, (char*)CheckBoxMarkString, w->colours[1] & 0x7F, _button_offset_x + 12 * j, y + _check_offset_y);
}
@@ -893,9 +844,3 @@ void window_themes_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scroll
y += _row_height;
}
}
-
-#endif
-
-void window_themes_open()
-{
-}