mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #21653 from duncanspumpkin/moveTextInput
Move Text input widget to Ui library
This commit is contained in:
commit
7a1b4ce425
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue