1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-23 06:44:38 +01:00

Improve string handling and allow window update

This commit is contained in:
Ted John
2020-02-27 22:13:49 +00:00
parent 09c8c6d508
commit 4d221341da
5 changed files with 121 additions and 21 deletions

View File

@@ -17,6 +17,7 @@
# include <openrct2-ui/interface/Widget.h>
# include <openrct2-ui/windows/Window.h>
# include <openrct2/drawing/Drawing.h>
# include <openrct2/localisation/Language.h>
# include <openrct2/localisation/Localisation.h>
# include <openrct2/localisation/StringIds.h>
# include <openrct2/scripting/Plugin.h>
@@ -109,28 +110,10 @@ namespace OpenRCT2::Ui::Windows
static std::string ProcessString(const DukValue& value)
{
if (value.type() == DukValue::Type::STRING)
return ProcessString(value.as_string());
return language_convert_string(value.as_string());
return {};
}
static std::string ProcessString(const std::string_view& s)
{
std::string result;
result.reserve(s.size());
for (char c : s)
{
if (c == '\n')
{
result.push_back(FORMAT_NEWLINE);
}
else
{
result.push_back(c);
}
}
return result;
}
static CustomWidgetDesc FromDukValue(DukValue desc)
{
CustomWidgetDesc result;
@@ -228,7 +211,7 @@ namespace OpenRCT2::Ui::Windows
result.MaxWidth = GetOptionalInt(desc["maxWidth"]);
result.MinHeight = GetOptionalInt(desc["minHeight"]);
result.MaxHeight = GetOptionalInt(desc["maxHeight"]);
result.Title = desc["title"].as_string();
result.Title = language_convert_string(desc["title"].as_string());
result.Id = GetOptionalInt(desc["id"]);
if (desc["widgets"].is_array())
@@ -742,6 +725,25 @@ namespace OpenRCT2::Ui::Windows
}
}
std::string GetWindowTitle(rct_window* w)
{
if (w->custom_info != nullptr)
{
auto& customInfo = GetInfo(w);
return customInfo.Desc.Title;
}
return {};
}
void UpdateWindowTitle(rct_window* w, const std::string_view& value)
{
if (w->custom_info != nullptr)
{
auto& customInfo = GetInfo(w);
customInfo.Desc.Title = value;
}
}
void UpdateWidgetText(rct_window* w, rct_widgetindex widgetIndex, const std::string_view& value)
{
if (w->custom_info != nullptr)
@@ -750,7 +752,7 @@ namespace OpenRCT2::Ui::Windows
auto customWidgetInfo = customInfo.GetCustomWidgetDesc(widgetIndex);
if (customWidgetInfo != nullptr)
{
customWidgetInfo->Text = CustomWidgetDesc::ProcessString(value);
customWidgetInfo->Text = language_convert_string(value);
w->widgets[widgetIndex].string = customWidgetInfo->Text.data();
widget_invalidate(w, widgetIndex);
}

View File

@@ -18,6 +18,8 @@
namespace OpenRCT2::Ui::Windows
{
std::string GetWindowTitle(rct_window* w);
void UpdateWindowTitle(rct_window* w, const std::string_view& value);
void UpdateWidgetText(rct_window* w, rct_widgetindex widget, const std::string_view& string_view);
rct_window* FindCustomWindowByClassification(const std::string_view& classification);
std::optional<rct_widgetindex> FindWidgetIndexByName(rct_window* w, const std::string_view& name);

View File

@@ -16,6 +16,7 @@
# include <openrct2/common.h>
# include <openrct2/interface/Window.h>
# include <openrct2/interface/Window_internal.h>
# include <openrct2/localisation/Language.h>
# include <openrct2/scripting/Duktape.hpp>
namespace OpenRCT2::Scripting
@@ -125,6 +126,24 @@ namespace OpenRCT2::Scripting
}
}
std::string title_get()
{
auto w = GetWindow();
if (w != nullptr && w->classification == WC_CUSTOM)
{
return GetWindowTitle(w);
}
return {};
}
void title_set(std::string value)
{
auto w = GetWindow();
if (w != nullptr && w->classification == WC_CUSTOM)
{
UpdateWindowTitle(w, language_convert_string(value));
}
}
void close()
{
auto w = GetWindow();
@@ -169,6 +188,7 @@ namespace OpenRCT2::Scripting
dukglue_register_property(ctx, &ScWindow::isSticky_get, nullptr, "isSticky");
dukglue_register_property(ctx, &ScWindow::widgets_get, nullptr, "widgets");
dukglue_register_property(ctx, &ScWindow::colours_get, &ScWindow::colours_set, "colours");
dukglue_register_property(ctx, &ScWindow::title_get, &ScWindow::title_set, "title");
dukglue_register_method(ctx, &ScWindow::close, "close");
dukglue_register_method(ctx, &ScWindow::findWidget, "findWidget");

View File

@@ -136,3 +136,78 @@ rct_string_id language_allocate_object_string(const std::string& target)
auto& localisationService = OpenRCT2::GetContext()->GetLocalisationService();
return localisationService.AllocateObjectString(target);
}
std::string language_convert_string(const std::string_view& s)
{
enum class PARSE_STATE
{
DEFAULT,
CR,
TOKEN,
};
std::string result;
std::string token;
PARSE_STATE state{};
token.reserve(64);
result.reserve(s.size() * 2);
for (char c : s)
{
switch (state)
{
case PARSE_STATE::CR:
result.push_back(FORMAT_NEWLINE);
state = PARSE_STATE::DEFAULT;
[[fallthrough]];
case PARSE_STATE::DEFAULT:
switch (c)
{
case '\r':
state = PARSE_STATE::CR;
break;
case '\n':
result.push_back(FORMAT_NEWLINE);
break;
case '{':
token.clear();
state = PARSE_STATE::TOKEN;
break;
default:
if (c >= 32)
{
result.push_back(c);
}
break;
}
break;
case PARSE_STATE::TOKEN:
if (c == '}')
{
auto code = format_get_code(token.c_str());
if (code == 0)
{
int32_t number{};
if (sscanf(token.c_str(), "%d", &number) == 1)
{
auto b = static_cast<uint8_t>(std::clamp(number, 0, 255));
token.push_back(b);
}
}
else
{
char buffer[8]{};
utf8_write_codepoint(buffer, code);
result.append(buffer);
}
state = PARSE_STATE::DEFAULT;
}
else
{
token.push_back(c);
}
break;
}
}
result.shrink_to_fit();
return result;
}

View File

@@ -107,6 +107,7 @@ bool language_get_localised_scenario_strings(const utf8* scenarioFilename, rct_s
void language_free_object_string(rct_string_id stringId);
rct_string_id language_get_object_override_string_id(const char* identifier, uint8_t index);
rct_string_id language_allocate_object_string(const std::string& target);
std::string language_convert_string(const std::string_view& s);
constexpr utf8* utf8_write_codepoint(utf8* dst, uint32_t codepoint)
{