OpenRCT2/src/interface/Theme.cpp

457 lines
22 KiB
C++
Raw Normal View History

#include <jansson.h>
extern "C"
{
#include "../common.h"
#include "window.h"
}
2016-01-28 23:22:02 +01:00
#include "../core/Json.hpp"
#include "../core/List.hpp"
#include "../core/Math.hpp"
#include "../core/Memory.hpp"
#include "../core/String.hpp"
#include "../core/Util.hpp"
struct WindowThemeDesc;
// Don't try to load theme files that exceed 64 MiB
constexpr uint64 MAX_THEME_SIZE = 64 * 1024 * 1024;
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,
};
/**
* Represents a window theming style such as the colour scheme.
*/
struct WindowTheme
{
colour_t Colours[6];
};
/**
* Represents the style for a particular type of window.
*/
struct UIThemeEntry
{
rct_windowclass WindowClass;
WindowTheme Theme;
2016-01-28 23:22:02 +01:00
json_t * ToJson() const;
static UIThemeEntry FromJson(const WindowThemeDesc * wtDesc, const json_t * json);
};
/**
* Represents a user interface theme. Contains window colour schemes and appearance features.
*/
2016-01-28 23:22:02 +01:00
class UITheme
{
2016-01-28 23:22:02 +01:00
public:
utf8 * Name;
List<UIThemeEntry> Entries;
uint8 Flags;
2016-01-28 23:22:02 +01:00
UITheme(const utf8 * name);
UITheme(const UITheme & name);
~UITheme();
void SetEntry(const UIThemeEntry * entry);
void RemoveEntry(rct_windowclass windowClass);
json_t * ToJson() const;
bool WriteToFile(const utf8 * path) const;
static UITheme * FromJson(const json_t * json);
static UITheme * FromFile(const utf8 * path);
2016-01-28 23:22:02 +01:00
static UITheme CreatePredefined(const utf8 * name, const UIThemeEntry * entries, uint8 flags);
};
/**
* Represents the theme descriptor for a specific window type including the default colour scheme.
*/
struct WindowThemeDesc
{
rct_windowclass WindowClass;
const utf8 * WindowClassSZ;
rct_string_id WindowName;
uint8 NumColours;
WindowTheme DefaultTheme;
};
#pragma region Window Theme Descriptors
#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 }
#define THEME_WC(wc) wc, #wc
WindowThemeDesc WindowThemeDescriptors[] =
{
// WindowClass, WindowClassSZ WindowName NumColours, DefaultTheme
{ THEME_WC(WC_TOP_TOOLBAR), 5245, COLOURS_4(COLOUR_LIGHT_BLUE, COLOUR_DARK_GREEN, COLOUR_DARK_BROWN, COLOUR_GREY ) },
{ THEME_WC(WC_BOTTOM_TOOLBAR), 5246, COLOURS_4(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), COLOUR_BLACK, COLOUR_BRIGHT_GREEN ) },
{ THEME_WC(WC_RIDE), 5203, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_GREY ) },
{ THEME_WC(WC_RIDE_CONSTRUCTION), 5199, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
{ THEME_WC(WC_RIDE_LIST), 5204, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
{ THEME_WC(WC_SAVE_PROMPT), 5223, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
{ THEME_WC(WC_CONSTRUCT_RIDE), 5201, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
{ THEME_WC(WC_DEMOLISH_RIDE_PROMPT), 5224, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
{ THEME_WC(WC_SCENERY), 5197, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) },
{ THEME_WC(WC_OPTIONS), 5219, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
{ THEME_WC(WC_FOOTPATH), 5198, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
{ THEME_WC(WC_LAND), 5193, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
{ THEME_WC(WC_WATER), 5194, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
{ THEME_WC(WC_PEEP), 5205, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
{ THEME_WC(WC_GUEST_LIST), 5206, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
{ THEME_WC(WC_STAFF_LIST), 5208, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) },
{ THEME_WC(WC_FIRE_PROMPT), 5225, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
{ THEME_WC(WC_PARK_INFORMATION), 5253, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
{ THEME_WC(WC_FINANCES), 5187, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
{ THEME_WC(WC_TITLE_MENU), 5249, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
{ THEME_WC(WC_TITLE_EXIT), 5250, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
{ THEME_WC(WC_RECENT_NEWS), 5192, COLOURS_3(COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK ) },
{ THEME_WC(WC_SCENARIO_SELECT), 5252, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
{ THEME_WC(WC_TRACK_DESIGN_LIST), 5202, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
{ THEME_WC(WC_TRACK_DESIGN_PLACE), 5200, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
{ THEME_WC(WC_NEW_CAMPAIGN), 5188, COLOURS_3(COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
{ THEME_WC(WC_KEYBOARD_SHORTCUT_LIST), 5220, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
{ THEME_WC(WC_CHANGE_KEYBOARD_SHORTCUT), 5221, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
{ THEME_WC(WC_MAP), 5190, COLOURS_2(COLOUR_DARK_GREEN, COLOUR_DARK_BROWN ) },
{ THEME_WC(WC_BANNER), 5209, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
{ THEME_WC(WC_EDITOR_OBJECT_SELECTION), 5210, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
{ THEME_WC(WC_EDITOR_INVENTION_LIST), 5211, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
{ THEME_WC(WC_EDITOR_SCENARIO_OPTIONS), 5212, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
{ THEME_WC(WC_EDTIOR_OBJECTIVE_OPTIONS), 5213, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
{ THEME_WC(WC_MANAGE_TRACK_DESIGN), 5215, COLOURS_3(COLOUR_GREY, COLOUR_GREY, COLOUR_GREY ) },
{ THEME_WC(WC_TRACK_DELETE_PROMPT), 5226, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
{ THEME_WC(WC_INSTALL_TRACK), 5216, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
{ THEME_WC(WC_CLEAR_SCENERY), 5195, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
{ THEME_WC(WC_CHEATS), 5217, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
{ THEME_WC(WC_RESEARCH), 5189, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
{ THEME_WC(WC_VIEWPORT), 5191, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
{ THEME_WC(WC_MAPGEN), 5214, COLOURS_3(COLOUR_DARK_GREEN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
{ THEME_WC(WC_LOADSAVE), 5222, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
{ THEME_WC(WC_LOADSAVE_OVERWRITE_PROMPT), 5227, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
{ THEME_WC(WC_TITLE_OPTIONS), 5251, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
{ THEME_WC(WC_LAND_RIGHTS), 5196, COLOURS_3(COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
{ THEME_WC(WC_THEMES), 5218, COLOURS_3(COLOUR_GREY, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) },
{ THEME_WC(WC_STAFF), 5207, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) },
{ THEME_WC(WC_EDITOR_TRACK_BOTTOM_TOOLBAR), 5247, COLOURS_3(TRANSLUCENT(COLOUR_LIGHT_BLUE), TRANSLUCENT(COLOUR_LIGHT_BLUE), TRANSLUCENT(COLOUR_LIGHT_BLUE) ) },
{ THEME_WC(WC_EDITOR_SCENARIO_BOTTOM_TOOLBAR), 5248, COLOURS_3(TRANSLUCENT(COLOUR_LIGHT_BROWN), TRANSLUCENT(COLOUR_LIGHT_BROWN), TRANSLUCENT(COLOUR_MOSS_GREEN) ) },
{ THEME_WC(WC_TITLE_EDITOR), 5433, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
};
#pragma endregion
#pragma region Pre-defined Themes
#define COLOURS_RCT1(c0, c1, c2, c3, c4, c5) { { (c0), (c1), (c2), (c3), (c4), (c5) } }
UIThemeEntry PredefinedThemeRCT1_Entries[] =
{
{ 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
};
UIThemeEntry PredefinedThemeRCT2_Entries[] =
{
THEME_DEF_END
};
2016-01-28 23:22:02 +01:00
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);
const UITheme PredefinedThemeRCT2 = UITheme::CreatePredefined(
"RCT2", PredefinedThemeRCT2_Entries, 0);
const UITheme * PredefinedThemes[] = {
&PredefinedThemeRCT1,
&PredefinedThemeRCT2,
nullptr
};
#pragma endregion
static const WindowThemeDesc * GetWindowThemeDescriptor(rct_windowclass windowClass)
{
for (size_t i = 0; i < Util::CountOf(WindowThemeDescriptors); i++)
{
const WindowThemeDesc * desc = &WindowThemeDescriptors[i];
if (desc->WindowClass == windowClass)
{
return desc;
}
}
return nullptr;
}
static const WindowThemeDesc * GetWindowThemeDescriptor(const utf8 * windowClassSZ)
{
for (size_t i = 0; i < Util::CountOf(WindowThemeDescriptors); i++)
{
const WindowThemeDesc * desc = &WindowThemeDescriptors[i];
if (String::Equals(desc->WindowClassSZ, windowClassSZ))
{
return desc;
}
}
return nullptr;
}
static void ThrowThemeLoadException()
{
throw Exception("Invalid JSON UI theme entry.");
}
#pragma region UIThemeEntry
json_t * UIThemeEntry::ToJson() const
{
const WindowThemeDesc * wtDesc = GetWindowThemeDescriptor(WindowClass);
json_t * jsonColours = json_array();
for (uint8 i = 0; i < wtDesc->NumColours; i++) {
colour_t colour = Theme.Colours[i];
json_array_append_new(jsonColours, json_integer(colour));
}
json_t * jsonEntry = json_object();
json_object_set_new(jsonEntry, "colours", jsonColours);
return jsonEntry;
}
2016-01-28 23:22:02 +01:00
UIThemeEntry UIThemeEntry::FromJson(const WindowThemeDesc * wtDesc, const json_t * json)
{
json_t * jsonColours = json_object_get(json, "colours");
if (jsonColours == nullptr)
{
ThrowThemeLoadException();
}
uint8 numColours = (uint8)json_array_size(jsonColours);
numColours = Math::Min(numColours, wtDesc->NumColours);
2016-01-28 23:22:02 +01:00
UIThemeEntry result;
result.WindowClass = wtDesc->WindowClass;
result.Theme = wtDesc->DefaultTheme;
for (uint8 i = 0; i < numColours; i++)
{
2016-01-28 23:22:02 +01:00
result.Theme.Colours[i] = (colour_t)json_integer_value(json_array_get(jsonColours, i));
}
return result;
}
#pragma endregion
#pragma region UITheme
2016-01-28 23:22:02 +01:00
UITheme::UITheme(const utf8 * name)
{
2016-01-28 23:22:02 +01:00
Name = String::Duplicate(name);
Flags = 0;
}
UITheme::UITheme(const UITheme & copy)
{
Name = String::Duplicate(copy.Name);
Flags = copy.Flags;
Entries = copy.Entries;
}
2016-01-28 23:22:02 +01:00
UITheme::~UITheme()
{
Memory::Free(Name);
}
void UITheme::SetEntry(const UIThemeEntry * newEntry)
{
// Try to replace existing entry
2016-01-28 23:22:02 +01:00
for (size_t i = 0; i < Entries.GetCount(); i++)
{
2016-01-28 23:22:02 +01:00
UIThemeEntry * entry = &Entries[i];
if (entry->WindowClass == newEntry->WindowClass)
{
*entry = *newEntry;
return;
}
}
2016-01-28 23:22:02 +01:00
Entries.Add(*newEntry);
}
void UITheme::RemoveEntry(rct_windowclass windowClass)
{
// Remove existing entry
2016-01-28 23:22:02 +01:00
for (size_t i = 0; i < Entries.GetCount(); i++)
{
2016-01-28 23:22:02 +01:00
UIThemeEntry * entry = &Entries[i];
if (entry->WindowClass == windowClass)
{
2016-01-28 23:22:02 +01:00
Entries.RemoveAt(i);
break;
}
}
}
json_t * UITheme::ToJson() const
{
// Create entries
json_t * jsonEntries = json_object();
2016-01-28 23:22:02 +01:00
for (const UIThemeEntry & entry : Entries)
{
2016-01-28 23:22:02 +01:00
const WindowThemeDesc * wtDesc = GetWindowThemeDescriptor(entry.WindowClass);
json_object_set_new(jsonEntries, wtDesc->WindowClassSZ, entry.ToJson());
}
// Create theme object
json_t * jsonTheme = json_object();
json_object_set_new(jsonTheme, "name", json_string(Name));
json_object_set_new(jsonTheme, "entries", jsonEntries);
json_object_set_new(jsonTheme, "useLightsRide", json_boolean(Flags & UITHEME_FLAG_USE_LIGHTS_RIDE));
json_object_set_new(jsonTheme, "useLightsPark", json_boolean(Flags & UITHEME_FLAG_USE_LIGHTS_PARK));
json_object_set_new(jsonTheme,
"useAltScenarioSelectFont",
json_boolean(Flags & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT));
return jsonTheme;
}
bool UITheme::WriteToFile(const utf8 * path) const
{
json_t * jsonTheme = ToJson();
2016-01-28 23:22:02 +01:00
bool result;
try
{
2016-01-28 23:22:02 +01:00
Json::WriteToFile(path, jsonTheme, JSON_INDENT(4));
result = true;
}
catch (Exception ex)
{
log_error("Unable to save %s: %s", path, ex.GetMessage());
2016-01-28 23:22:02 +01:00
result = false;
}
2016-01-28 23:22:02 +01:00
json_decref(jsonTheme);
return result;
}
UITheme * UITheme::FromJson(const json_t * json)
{
const char * themeName = json_string_value(json_object_get(json, "name"));
if (themeName == nullptr)
{
ThrowThemeLoadException();
}
json_t * jsonEntries = json_object_get(json, "entries");
size_t numEntries = json_object_size(jsonEntries);
if (numEntries == 0)
{
ThrowThemeLoadException();
}
UITheme * result = nullptr;
try
{
2016-01-28 23:22:02 +01:00
result = new UITheme(themeName);
if (json_is_true(json_object_get(json, "useLightsRide")))
{
result->Flags |= UITHEME_FLAG_USE_LIGHTS_RIDE;
}
if (json_is_true(json_object_get(json, "useLightsPark")))
{
result->Flags |= UITHEME_FLAG_USE_LIGHTS_PARK;
}
if (json_is_true(json_object_get(json, "useAltScenarioSelectFont")))
{
result->Flags |= UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT;
}
const char * jkey;
json_t * jvalue;
size_t i = 0;
json_object_foreach(jsonEntries, jkey, jvalue)
{
const WindowThemeDesc * wtDesc = GetWindowThemeDescriptor(jkey);
if (wtDesc == nullptr) continue;
2016-01-28 23:22:02 +01:00
UIThemeEntry entry = UIThemeEntry::FromJson(wtDesc, jvalue);
result->SetEntry(&entry);
}
return result;
}
catch (Exception ex)
{
2016-01-28 23:22:02 +01:00
delete result;
throw ex;
}
}
UITheme * UITheme::FromFile(const utf8 * path)
{
json_t * json = nullptr;
UITheme * result = nullptr;
try
{
2016-01-28 23:22:02 +01:00
json = Json::ReadFromFile(path);
result = UITheme::FromJson(json);
}
catch (Exception ex)
{
result = nullptr;
}
json_decref(json);
return result;
}
2016-01-28 23:22:02 +01:00
UITheme UITheme::CreatePredefined(const utf8 * name, const UIThemeEntry * entries, uint8 flags)
{
auto theme = UITheme(name);
theme.Flags = flags | UITHEME_FLAG_PREDEFINED;
2016-01-28 23:22:02 +01:00
size_t numEntries = 0;
for (const UIThemeEntry * entry = entries; entry->WindowClass != 255; entry++)
{
numEntries++;
}
theme.Entries = List<UIThemeEntry>(entries, numEntries);
return theme;
}
#pragma endregion