Merge pull request #21653 from duncanspumpkin/moveTextInput

Move Text input widget to Ui library
This commit is contained in:
Michael Steenbeek 2024-04-26 18:53:43 +02:00 committed by GitHub
commit 7a1b4ce425
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 136 additions and 126 deletions

View File

@ -84,7 +84,7 @@ void TextComposition::HandleMessage(const SDL_Event* e)
Insert(e->text.text); Insert(e->text.text);
console.RefreshCaret(_session.SelectionStart); console.RefreshCaret(_session.SelectionStart);
WindowUpdateTextbox(); OpenRCT2::Ui::Windows::WindowUpdateTextbox();
} }
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
@ -127,7 +127,7 @@ void TextComposition::HandleMessage(const SDL_Event* e)
Delete(); Delete();
console.RefreshCaret(_session.SelectionStart); console.RefreshCaret(_session.SelectionStart);
WindowUpdateTextbox(); OpenRCT2::Ui::Windows::WindowUpdateTextbox();
} }
break; break;
case SDLK_HOME: case SDLK_HOME:
@ -149,11 +149,11 @@ void TextComposition::HandleMessage(const SDL_Event* e)
_session.SelectionStart = startOffset; _session.SelectionStart = startOffset;
Delete(); Delete();
console.RefreshCaret(_session.SelectionStart); console.RefreshCaret(_session.SelectionStart);
WindowUpdateTextbox(); OpenRCT2::Ui::Windows::WindowUpdateTextbox();
break; break;
} }
case SDLK_RETURN: case SDLK_RETURN:
WindowCancelTextbox(); OpenRCT2::Ui::Windows::WindowCancelTextbox();
break; break;
case SDLK_LEFT: case SDLK_LEFT:
if (modifier & KEYBOARD_PRIMARY_MODIFIER) if (modifier & KEYBOARD_PRIMARY_MODIFIER)
@ -182,7 +182,7 @@ void TextComposition::HandleMessage(const SDL_Event* e)
utf8* text = SDL_GetClipboardText(); utf8* text = SDL_GetClipboardText();
Insert(text); Insert(text);
SDL_free(text); SDL_free(text);
WindowUpdateTextbox(); OpenRCT2::Ui::Windows::WindowUpdateTextbox();
} }
break; break;
} }

View File

@ -207,7 +207,7 @@ void InputManager::Process(const InputEvent& e)
return; return;
} }
if (gUsingWidgetTextBox) if (OpenRCT2::Ui::Windows::IsUsingWidgetTextBox())
{ {
return; return;
} }
@ -383,7 +383,7 @@ bool InputManager::GetState(const ShortcutInput& shortcut) const
bool InputManager::HasTextInputFocus() const bool InputManager::HasTextInputFocus() const
{ {
if (gUsingWidgetTextBox || gChatOpen) if (OpenRCT2::Ui::Windows::IsUsingWidgetTextBox() || gChatOpen)
return true; return true;
auto w = WindowFindByClass(WindowClass::Textinput); auto w = WindowFindByClass(WindowClass::Textinput);

View File

@ -1022,8 +1022,8 @@ static void InputWidgetLeft(const ScreenCoordsXY& screenCoords, WindowBase* w, W
if (widgetIndex == -1) if (widgetIndex == -1)
return; return;
if (windowClass != gCurrentTextBox.window.classification || windowNumber != gCurrentTextBox.window.number if (windowClass != GetCurrentTextBox().window.classification || windowNumber != GetCurrentTextBox().window.number
|| widgetIndex != gCurrentTextBox.widget_index) || widgetIndex != GetCurrentTextBox().widget_index)
{ {
WindowCancelTextbox(); WindowCancelTextbox();
} }

View File

@ -1137,8 +1137,9 @@ static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid
// Get the colour // Get the colour
uint8_t colour = w.colours[widget.colour]; uint8_t colour = w.colours[widget.colour];
bool active = w.classification == gCurrentTextBox.window.classification && w.number == gCurrentTextBox.window.number auto& tbIdent = OpenRCT2::Ui::Windows::GetCurrentTextBox();
&& widgetIndex == gCurrentTextBox.widget_index; bool active = w.classification == tbIdent.window.classification && w.number == tbIdent.window.number
&& widgetIndex == tbIdent.widget_index;
// GfxFillRectInset(dpi, l, t, r, b, colour, 0x20 | (!active ? 0x40 : 0x00)); // GfxFillRectInset(dpi, l, t, r, b, colour, 0x20 | (!active ? 0x40 : 0x00));
GfxFillRectInset(dpi, { topLeft, bottomRight }, colour, INSET_RECT_F_60); GfxFillRectInset(dpi, { topLeft, bottomRight }, colour, INSET_RECT_F_60);
@ -1146,7 +1147,8 @@ static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid
// Figure out where the text should be positioned vertically. // Figure out where the text should be positioned vertically.
topLeft.y = w.windowPos.y + widget.textTop(); topLeft.y = w.windowPos.y + widget.textTop();
if (!active || gTextInput == nullptr) auto* textInput = OpenRCT2::Ui::Windows::GetTextboxSession();
if (!active || textInput == nullptr)
{ {
if (widget.text != 0) if (widget.text != 0)
{ {
@ -1160,27 +1162,27 @@ static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid
// String length needs to add 12 either side of box // String length needs to add 12 either side of box
// +13 for cursor when max length. // +13 for cursor when max length.
u8string wrappedString; u8string wrappedString;
GfxWrapString(gTextBoxInput, bottomRight.x - topLeft.x - 5 - 6, FontStyle::Medium, &wrappedString, nullptr); GfxWrapString(*textInput->Buffer, bottomRight.x - topLeft.x - 5 - 6, FontStyle::Medium, &wrappedString, nullptr);
DrawText(dpi, { topLeft.x + 2, topLeft.y }, { w.colours[1] }, wrappedString.c_str(), true); DrawText(dpi, { topLeft.x + 2, topLeft.y }, { w.colours[1] }, wrappedString.c_str(), true);
// Make a trimmed view of the string for measuring the width. // Make a trimmed view of the string for measuring the width.
int32_t curX = topLeft.x int32_t curX = topLeft.x
+ GfxGetStringWidthNoFormatting( + GfxGetStringWidthNoFormatting(
u8string_view{ wrappedString.c_str(), std::min(wrappedString.length(), gTextInput->SelectionStart) }, u8string_view{ wrappedString.c_str(), std::min(wrappedString.length(), textInput->SelectionStart) },
FontStyle::Medium) FontStyle::Medium)
+ 3; + 3;
int32_t width = 6; int32_t width = 6;
if (static_cast<uint32_t>(gTextInput->SelectionStart) < gTextBoxInput.size()) if (static_cast<uint32_t>(textInput->SelectionStart) < textInput->Buffer->size())
{ {
// Make a new 1 character wide string for measuring the width // Make a new 1 character wide string for measuring the width
// of the character that the cursor is under. // of the character that the cursor is under. (NOTE: this is broken for multi byte utf8 codepoints)
width = std::max( width = std::max(
GfxGetStringWidthNoFormatting(u8string{ gTextBoxInput[gTextInput->SelectionStart] }, FontStyle::Medium) - 2, 4); GfxGetStringWidthNoFormatting(u8string{ textInput->Buffer[textInput->SelectionStart] }, FontStyle::Medium) - 2, 4);
} }
if (gTextBoxFrameNo <= 15) if (OpenRCT2::Ui::Windows::TextBoxCaretIsFlashed())
{ {
colour = ColourMapA[w.colours[1]].mid_light; colour = ColourMapA[w.colours[1]].mid_light;
auto y = topLeft.y + (widget.height() - 1); auto y = topLeft.y + (widget.height() - 1);

View File

@ -835,6 +835,12 @@ ScreenCoordsXY WindowGetViewportSoundIconPos(WindowBase& w)
namespace OpenRCT2::Ui::Windows namespace OpenRCT2::Ui::Windows
{ {
static u8string _textBoxInput;
static int32_t _textBoxFrameNo = 0;
static bool _usingWidgetTextBox = false;
static TextInputSession* _textInput;
static WidgetIdentifier _currentTextBox = { { WindowClass::Null, 0 }, 0 };
WindowBase* WindowGetListening() WindowBase* WindowGetListening()
{ {
for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++) for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++)
@ -859,4 +865,77 @@ namespace OpenRCT2::Ui::Windows
{ {
return window.classification; return window.classification;
} }
void WindowStartTextbox(const WindowBase& callW, WidgetIndex callWidget, u8string existingText, int32_t maxLength)
{
if (_usingWidgetTextBox)
WindowCancelTextbox();
_usingWidgetTextBox = true;
_currentTextBox.window.classification = callW.classification;
_currentTextBox.window.number = callW.number;
_currentTextBox.widget_index = callWidget;
_textBoxFrameNo = 0;
WindowCloseByClass(WindowClass::Textinput);
_textBoxInput = existingText;
_textInput = ContextStartTextInput(_textBoxInput, maxLength);
}
void WindowCancelTextbox()
{
if (_usingWidgetTextBox)
{
WindowBase* w = WindowFindByNumber(_currentTextBox.window.classification, _currentTextBox.window.number);
_currentTextBox.window.classification = WindowClass::Null;
_currentTextBox.window.number = 0;
ContextStopTextInput();
_usingWidgetTextBox = false;
if (w != nullptr)
{
WidgetInvalidate(*w, _currentTextBox.widget_index);
}
_currentTextBox.widget_index = static_cast<uint16_t>(WindowWidgetType::Last);
}
}
void WindowUpdateTextboxCaret()
{
_textBoxFrameNo++;
if (_textBoxFrameNo > 30)
_textBoxFrameNo = 0;
}
void WindowUpdateTextbox()
{
if (_usingWidgetTextBox)
{
_textBoxFrameNo = 0;
WindowBase* w = WindowFindByNumber(_currentTextBox.window.classification, _currentTextBox.window.number);
WidgetInvalidate(*w, _currentTextBox.widget_index);
w->OnTextInput(_currentTextBox.widget_index, _textBoxInput);
}
}
const TextInputSession* GetTextboxSession()
{
return _textInput;
}
void SetTexboxSession(TextInputSession* session)
{
_textInput = session;
}
bool IsUsingWidgetTextBox()
{
return _usingWidgetTextBox;
}
bool TextBoxCaretIsFlashed()
{
return _textBoxFrameNo <= 15;
}
const WidgetIdentifier& GetCurrentTextBox()
{
return _currentTextBox;
}
} // namespace OpenRCT2::Ui::Windows } // namespace OpenRCT2::Ui::Windows

View File

@ -12,6 +12,8 @@
#include <openrct2/interface/Window.h> #include <openrct2/interface/Window.h>
#include <openrct2/interface/Window_internal.h> #include <openrct2/interface/Window_internal.h>
struct TextInputSession;
struct Window : WindowBase struct Window : WindowBase
{ {
virtual void OnDraw(DrawPixelInfo& dpi) override; virtual void OnDraw(DrawPixelInfo& dpi) override;
@ -73,4 +75,15 @@ namespace OpenRCT2::Ui::Windows
WindowBase* WindowGetListening(); WindowBase* WindowGetListening();
WindowClass WindowGetClassification(const WindowBase& window); WindowClass WindowGetClassification(const WindowBase& window);
void WindowStartTextbox(const WindowBase& callW, WidgetIndex callWidget, u8string existingText, int32_t maxLength);
void WindowCancelTextbox();
void WindowUpdateTextboxCaret();
void WindowUpdateTextbox();
const TextInputSession* GetTextboxSession();
void SetTexboxSession(TextInputSession* session);
bool IsUsingWidgetTextBox();
bool TextBoxCaretIsFlashed();
const WidgetIdentifier& GetCurrentTextBox();
} // namespace OpenRCT2::Ui::Windows } // namespace OpenRCT2::Ui::Windows

View File

@ -653,8 +653,7 @@ namespace OpenRCT2::Ui::Windows
} }
else if (widgetDesc->Type == "textbox") else if (widgetDesc->Type == "textbox")
{ {
auto* text = const_cast<char*>(widgetDesc->Text.c_str()); WindowStartTextbox(*this, widgetIndex, widgetDesc->Text, widgetDesc->MaxLength + 1);
WindowStartTextbox(*this, widgetIndex, STR_STRING, text, widgetDesc->MaxLength + 1);
} }
} }
} }

View File

@ -328,7 +328,7 @@ static std::vector<Widget> _window_editor_object_selection_widgets = {
void OnUpdate() override void OnUpdate() override
{ {
if (gCurrentTextBox.window.classification == classification && gCurrentTextBox.window.number == number) if (GetCurrentTextBox().window.classification == classification && GetCurrentTextBox().window.number == number)
{ {
WindowUpdateTextboxCaret(); WindowUpdateTextboxCaret();
WidgetInvalidate(*this, WIDX_FILTER_TEXT_BOX); WidgetInvalidate(*this, WIDX_FILTER_TEXT_BOX);
@ -422,7 +422,7 @@ static std::vector<Widget> _window_editor_object_selection_widgets = {
break; break;
} }
case WIDX_FILTER_TEXT_BOX: case WIDX_FILTER_TEXT_BOX:
WindowStartTextbox(*this, widgetIndex, STR_STRING, _filter_string, sizeof(_filter_string)); WindowStartTextbox(*this, widgetIndex, _filter_string, sizeof(_filter_string));
break; break;
case WIDX_FILTER_CLEAR_BUTTON: case WIDX_FILTER_CLEAR_BUTTON:
std::fill_n(_filter_string, sizeof(_filter_string), 0x00); std::fill_n(_filter_string, sizeof(_filter_string), 0x00);

View File

@ -325,7 +325,7 @@ static Widget window_new_ride_widgets[] = {
WidgetInvalidate(*this, WIDX_TAB_1 + static_cast<int32_t>(_currentTab)); WidgetInvalidate(*this, WIDX_TAB_1 + static_cast<int32_t>(_currentTab));
if (gCurrentTextBox.window.classification == classification && gCurrentTextBox.window.number == number) if (GetCurrentTextBox().window.classification == classification && GetCurrentTextBox().window.number == number)
{ {
WindowUpdateTextboxCaret(); WindowUpdateTextboxCaret();
WidgetInvalidate(*this, WIDX_FILTER_TEXT_BOX); WidgetInvalidate(*this, WIDX_FILTER_TEXT_BOX);
@ -370,7 +370,7 @@ static Widget window_new_ride_widgets[] = {
SetPage(_currentTab); SetPage(_currentTab);
break; break;
case WIDX_FILTER_TEXT_BOX: case WIDX_FILTER_TEXT_BOX:
WindowStartTextbox(*this, widgetIndex, STR_STRING, _filter.data(), kTextInputSize); WindowStartTextbox(*this, widgetIndex, _filter, kTextInputSize);
break; break;
case WIDX_FILTER_CLEAR_BUTTON: case WIDX_FILTER_CLEAR_BUTTON:
_filter.clear(); _filter.clear();

View File

@ -276,7 +276,7 @@ static Widget WindowSceneryBaseWidgets[] = {
Invalidate(); Invalidate();
break; break;
case WIDX_FILTER_TEXT_BOX: case WIDX_FILTER_TEXT_BOX:
WindowStartTextbox(*this, widgetIndex, STR_STRING, _filteredSceneryTab.Filter.data(), kTextInputSize); WindowStartTextbox(*this, widgetIndex, _filteredSceneryTab.Filter, kTextInputSize);
break; break;
case WIDX_FILTER_CLEAR_BUTTON: case WIDX_FILTER_CLEAR_BUTTON:
_tabEntries[_activeTabIndex].Filter.clear(); _tabEntries[_activeTabIndex].Filter.clear();
@ -463,7 +463,7 @@ static Widget WindowSceneryBaseWidgets[] = {
} }
} }
if (gCurrentTextBox.window.classification == classification && gCurrentTextBox.window.number == number) if (GetCurrentTextBox().window.classification == classification && GetCurrentTextBox().window.number == number)
{ {
WindowUpdateTextboxCaret(); WindowUpdateTextboxCaret();
WidgetInvalidate(*this, WIDX_FILTER_TEXT_BOX); WidgetInvalidate(*this, WIDX_FILTER_TEXT_BOX);

View File

@ -131,7 +131,7 @@ static Widget _serverListWidgets[] = {
Close(); Close();
break; break;
case WIDX_PLAYER_NAME_INPUT: case WIDX_PLAYER_NAME_INPUT:
WindowStartTextbox(*this, widgetIndex, STR_STRING, _playerName.c_str(), MaxPlayerNameLength); WindowStartTextbox(*this, widgetIndex, _playerName, MaxPlayerNameLength);
break; break;
case WIDX_LIST: case WIDX_LIST:
{ {
@ -205,7 +205,7 @@ static Widget _serverListWidgets[] = {
void OnUpdate() override void OnUpdate() override
{ {
if (gCurrentTextBox.window.classification == classification && gCurrentTextBox.window.number == number) if (GetCurrentTextBox().window.classification == classification && GetCurrentTextBox().window.number == number)
{ {
WindowUpdateTextboxCaret(); WindowUpdateTextboxCaret();
InvalidateWidget(WIDX_PLAYER_NAME_INPUT); InvalidateWidget(WIDX_PLAYER_NAME_INPUT);

View File

@ -95,19 +95,19 @@ static Widget _windowServerStartWidgets[] = {
Close(); Close();
break; break;
case WIDX_PORT_INPUT: case WIDX_PORT_INPUT:
WindowStartTextbox(*this, widgetIndex, STR_STRING, _port, 6); WindowStartTextbox(*this, widgetIndex, _port, 6);
break; break;
case WIDX_NAME_INPUT: case WIDX_NAME_INPUT:
WindowStartTextbox(*this, widgetIndex, STR_STRING, _name, 64); WindowStartTextbox(*this, widgetIndex, _name, 64);
break; break;
case WIDX_DESCRIPTION_INPUT: case WIDX_DESCRIPTION_INPUT:
WindowStartTextbox(*this, widgetIndex, STR_STRING, _description, MAX_SERVER_DESCRIPTION_LENGTH); WindowStartTextbox(*this, widgetIndex, _description, MAX_SERVER_DESCRIPTION_LENGTH);
break; break;
case WIDX_GREETING_INPUT: case WIDX_GREETING_INPUT:
WindowStartTextbox(*this, widgetIndex, STR_STRING, _greeting, kChatInputSize); WindowStartTextbox(*this, widgetIndex, _greeting, kChatInputSize);
break; break;
case WIDX_PASSWORD_INPUT: case WIDX_PASSWORD_INPUT:
WindowStartTextbox(*this, widgetIndex, STR_STRING, _password, 32); WindowStartTextbox(*this, widgetIndex, _password, 32);
break; break;
case WIDX_MAXPLAYERS_INCREASE: case WIDX_MAXPLAYERS_INCREASE:
if (gConfigNetwork.Maxplayers < 255) if (gConfigNetwork.Maxplayers < 255)
@ -154,7 +154,7 @@ static Widget _windowServerStartWidgets[] = {
} }
void OnUpdate() override void OnUpdate() override
{ {
if (gCurrentTextBox.window.classification == classification && gCurrentTextBox.window.number == number) if (GetCurrentTextBox().window.classification == classification && GetCurrentTextBox().window.number == number)
{ {
WindowUpdateTextboxCaret(); WindowUpdateTextboxCaret();
WidgetInvalidate(*this, WIDX_NAME_INPUT); WidgetInvalidate(*this, WIDX_NAME_INPUT);

View File

@ -114,7 +114,7 @@ namespace OpenRCT2::Ui::Windows
text = String::UTF8TruncateCodePoints(text, maxLength); text = String::UTF8TruncateCodePoints(text, maxLength);
_buffer = u8string{ text }; _buffer = u8string{ text };
_maxInputLength = maxLength; _maxInputLength = maxLength;
gTextInput = ContextStartTextInput(_buffer, maxLength); SetTexboxSession(ContextStartTextInput(_buffer, maxLength));
} }
void SetCallback(std::function<void(std::string_view)> callback, std::function<void()> cancelCallback) void SetCallback(std::function<void(std::string_view)> callback, std::function<void()> cancelCallback)
@ -238,6 +238,7 @@ namespace OpenRCT2::Ui::Windows
size_t char_count = 0; size_t char_count = 0;
uint8_t cur_drawn = 0; uint8_t cur_drawn = 0;
auto* textInput = GetTextboxSession();
int32_t cursorX = 0; int32_t cursorX = 0;
int32_t cursorY = 0; int32_t cursorY = 0;
for (int32_t line = 0; line <= no_lines; line++) for (int32_t line = 0; line <= no_lines; line++)
@ -246,22 +247,21 @@ namespace OpenRCT2::Ui::Windows
DrawText(dpi, screenCoords, { colours[1], FontStyle::Medium, TextAlignment::LEFT }, wrapPointer, true); DrawText(dpi, screenCoords, { colours[1], FontStyle::Medium, TextAlignment::LEFT }, wrapPointer, true);
size_t string_length = GetStringSize(wrapPointer) - 1; size_t string_length = GetStringSize(wrapPointer) - 1;
if (!cur_drawn && (textInput->SelectionStart <= char_count + string_length))
if (!cur_drawn && (gTextInput->SelectionStart <= char_count + string_length))
{ {
// Make a view of the string for measuring the width. // Make a view of the string for measuring the width.
cursorX = windowPos.x + 13 cursorX = windowPos.x + 13
+ GfxGetStringWidthNoFormatting( + GfxGetStringWidthNoFormatting(
u8string_view{ wrapPointer, gTextInput->SelectionStart - char_count }, FontStyle::Medium); u8string_view{ wrapPointer, textInput->SelectionStart - char_count }, FontStyle::Medium);
cursorY = screenCoords.y; cursorY = screenCoords.y;
int32_t textWidth = 6; int32_t textWidth = 6;
if (gTextInput->SelectionStart < strlen(_buffer.data())) if (textInput->SelectionStart < strlen(_buffer.data()))
{ {
// Make a 1 utf8-character wide string for measuring the width // Make a 1 utf8-character wide string for measuring the width
// of the currently selected character. // of the currently selected character.
utf8 tmp[5] = {}; // This is easier than setting temp_string[0..5] utf8 tmp[5] = {}; // This is easier than setting temp_string[0..5]
uint32_t codepoint = UTF8GetNext(_buffer.data() + gTextInput->SelectionStart, nullptr); uint32_t codepoint = UTF8GetNext(_buffer.data() + textInput->SelectionStart, nullptr);
UTF8WriteCodepoint(tmp, codepoint); UTF8WriteCodepoint(tmp, codepoint);
textWidth = std::max(GfxGetStringWidthNoFormatting(tmp, FontStyle::Medium) - 2, 4); textWidth = std::max(GfxGetStringWidthNoFormatting(tmp, FontStyle::Medium) - 2, 4);
} }
@ -293,7 +293,7 @@ namespace OpenRCT2::Ui::Windows
} }
// IME composition // IME composition
if (!String::IsNullOrEmpty(gTextInput->ImeBuffer)) if (!String::IsNullOrEmpty(textInput->ImeBuffer))
{ {
IMEComposition(cursorX, cursorY); IMEComposition(cursorX, cursorY);
} }

View File

@ -297,8 +297,7 @@ static Widget _trackListWidgets[] = {
} }
break; break;
case WIDX_FILTER_STRING: case WIDX_FILTER_STRING:
WindowStartTextbox( WindowStartTextbox(*this, widgetIndex, _filterString, sizeof(_filterString));
*this, widgetIndex, STR_STRING, _filterString, sizeof(_filterString)); // TODO check this out
break; break;
case WIDX_FILTER_CLEAR: case WIDX_FILTER_CLEAR:
// Keep the highlighted item selected // Keep the highlighted item selected
@ -434,7 +433,7 @@ static Widget _trackListWidgets[] = {
void OnUpdate() override void OnUpdate() override
{ {
if (gCurrentTextBox.window.classification == classification && gCurrentTextBox.window.number == number) if (GetCurrentTextBox().window.classification == classification && GetCurrentTextBox().window.number == number)
{ {
WindowUpdateTextboxCaret(); WindowUpdateTextboxCaret();
WidgetInvalidate(*this, WIDX_FILTER_STRING); // TODO Check this WidgetInvalidate(*this, WIDX_FILTER_STRING); // TODO Check this

View File

@ -45,12 +45,7 @@ using namespace OpenRCT2;
std::list<std::shared_ptr<WindowBase>> g_window_list; std::list<std::shared_ptr<WindowBase>> g_window_list;
WindowBase* gWindowAudioExclusive; WindowBase* gWindowAudioExclusive;
WidgetIdentifier gCurrentTextBox = { { WindowClass::Null, 0 }, 0 };
WindowCloseModifier gLastCloseModifier = { { WindowClass::Null, 0 }, CloseWindowModifier::None }; WindowCloseModifier gLastCloseModifier = { { WindowClass::Null, 0 }, CloseWindowModifier::None };
u8string gTextBoxInput;
int32_t gTextBoxFrameNo = 0;
bool gUsingWidgetTextBox = false;
TextInputSession* gTextInput;
uint32_t gWindowUpdateTicks; uint32_t gWindowUpdateTicks;
uint16_t gWindowMapFlashingFlags; uint16_t gWindowMapFlashingFlags;
@ -1649,70 +1644,6 @@ void TextinputCancel()
WindowCloseByClass(WindowClass::Textinput); WindowCloseByClass(WindowClass::Textinput);
} }
void WindowStartTextbox(
WindowBase& call_w, WidgetIndex call_widget, StringId existing_text, const char* existing_args, int32_t maxLength)
{
if (gUsingWidgetTextBox)
WindowCancelTextbox();
gUsingWidgetTextBox = true;
gCurrentTextBox.window.classification = call_w.classification;
gCurrentTextBox.window.number = call_w.number;
gCurrentTextBox.widget_index = call_widget;
gTextBoxFrameNo = 0;
WindowCloseByClass(WindowClass::Textinput);
// Clear the text input buffer
gTextBoxInput.clear();
// Enter in the text input buffer any existing
// text.
if (existing_text != STR_NONE)
{
char tempBuf[kTextInputSize]{};
size_t len = FormatStringLegacy(tempBuf, kTextInputSize, existing_text, &existing_args);
gTextBoxInput.assign(tempBuf, len);
}
gTextInput = ContextStartTextInput(gTextBoxInput, maxLength);
}
void WindowCancelTextbox()
{
if (gUsingWidgetTextBox)
{
WindowBase* w = WindowFindByNumber(gCurrentTextBox.window.classification, gCurrentTextBox.window.number);
gCurrentTextBox.window.classification = WindowClass::Null;
gCurrentTextBox.window.number = 0;
ContextStopTextInput();
gUsingWidgetTextBox = false;
if (w != nullptr)
{
WidgetInvalidate(*w, gCurrentTextBox.widget_index);
}
gCurrentTextBox.widget_index = static_cast<uint16_t>(WindowWidgetType::Last);
}
}
void WindowUpdateTextboxCaret()
{
gTextBoxFrameNo++;
if (gTextBoxFrameNo > 30)
gTextBoxFrameNo = 0;
}
void WindowUpdateTextbox()
{
if (gUsingWidgetTextBox)
{
gTextBoxFrameNo = 0;
WindowBase* w = WindowFindByNumber(gCurrentTextBox.window.classification, gCurrentTextBox.window.number);
WidgetInvalidate(*w, gCurrentTextBox.widget_index);
w->OnTextInput(gCurrentTextBox.widget_index, gTextBoxInput);
}
}
bool WindowIsVisible(WindowBase& w) bool WindowIsVisible(WindowBase& w)
{ {
// w->visibility is used to prevent repeat calculations within an iteration by caching the result // w->visibility is used to prevent repeat calculations within an iteration by caching the result

View File

@ -31,7 +31,6 @@
struct DrawPixelInfo; struct DrawPixelInfo;
struct WindowBase; struct WindowBase;
struct TrackDesignFileRef; struct TrackDesignFileRef;
struct TextInputSession;
struct ScenarioIndexEntry; struct ScenarioIndexEntry;
struct WindowCloseModifier; struct WindowCloseModifier;
@ -52,11 +51,6 @@ constexpr uint8_t kDropdownHeight = 12;
constexpr uint16_t kTextInputSize = 1024; constexpr uint16_t kTextInputSize = 1024;
constexpr uint16_t kTopToolbarHeight = 27; constexpr uint16_t kTopToolbarHeight = 27;
extern u8string gTextBoxInput;
extern int32_t gTextBoxFrameNo;
extern bool gUsingWidgetTextBox;
extern struct TextInputSession* gTextInput;
using rct_windownumber = uint16_t; using rct_windownumber = uint16_t;
using WidgetIndex = int16_t; using WidgetIndex = int16_t;
@ -72,7 +66,6 @@ struct WidgetIdentifier
WidgetIndex widget_index; WidgetIndex widget_index;
}; };
extern WidgetIdentifier gCurrentTextBox;
extern WindowCloseModifier gLastCloseModifier; extern WindowCloseModifier gLastCloseModifier;
using WidgetFlags = uint32_t; using WidgetFlags = uint32_t;
@ -631,12 +624,6 @@ void TextinputCancel();
void WindowMoveAndSnap(WindowBase& w, ScreenCoordsXY newWindowCoords, int32_t snapProximity); void WindowMoveAndSnap(WindowBase& w, ScreenCoordsXY newWindowCoords, int32_t snapProximity);
int32_t WindowCanResize(const WindowBase& w); int32_t WindowCanResize(const WindowBase& w);
void WindowStartTextbox(
WindowBase& call_w, WidgetIndex call_widget, StringId existing_text, const char* existing_args, int32_t maxLength);
void WindowCancelTextbox();
void WindowUpdateTextboxCaret();
void WindowUpdateTextbox();
bool WindowIsVisible(WindowBase& w); bool WindowIsVisible(WindowBase& w);
bool SceneryToolIsActive(); bool SceneryToolIsActive();