mirror of https://github.com/OpenRCT2/OpenRCT2.git
Add text box widget
This commit is contained in:
parent
be350f7e2e
commit
c0d8786af8
|
@ -18,6 +18,7 @@
|
|||
- Feature: [#13613] Add single-rail roller coaster (Rocky Mountain Construction Raptor).
|
||||
- Feature: [#13614] Add terrain surfaces from RollerCoaster Tycoon 1.
|
||||
- Feature: [#13675] [Plugin] Add context.setInterval and context.setTimeout.
|
||||
- Feature: [#13927] [Plugin] Add isVisible and text box widget.
|
||||
- Change: [#13346] [Plugin] Renamed FootpathScenery to FootpathAddition, fix typos.
|
||||
- Fix: [#4605, #11912] Water palettes are not updated properly when selected in Object Selection.
|
||||
- Fix: [#9631, #10716] Banners drawing glitches when there are more than 32 on the screen at once.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2020 OpenRCT2 developers
|
||||
* Copyright (c) 2014-2021 OpenRCT2 developers
|
||||
*
|
||||
* For a complete list of all authors, please refer to contributors.md
|
||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||
|
@ -1861,7 +1861,7 @@ declare global {
|
|||
* Represents the type of a widget, e.g. button or label.
|
||||
*/
|
||||
type WidgetType =
|
||||
"button" | "checkbox" | "colourpicker" | "dropdown" | "groupbox" | "label" | "listview" | "spinner" | "viewport";
|
||||
"button" | "checkbox" | "colourpicker" | "dropdown" | "groupbox" | "label" | "listview" | "spinner" | "textbox" | "viewport";
|
||||
|
||||
interface Widget {
|
||||
type: WidgetType;
|
||||
|
@ -1956,6 +1956,12 @@ declare global {
|
|||
onIncrement: () => void;
|
||||
}
|
||||
|
||||
interface TextBoxWidget extends Widget {
|
||||
text: string;
|
||||
maxLength: number;
|
||||
onChange: (text: string) => void;
|
||||
}
|
||||
|
||||
interface ViewportWidget extends Widget {
|
||||
viewport: Viewport
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ namespace OpenRCT2::Ui::Windows
|
|||
static void window_custom_mousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget);
|
||||
static void window_custom_resize(rct_window* w);
|
||||
static void window_custom_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex);
|
||||
static void window_custom_textinput(rct_window* w, rct_widgetindex widgetIndex, char* text);
|
||||
static void window_custom_update(rct_window* w);
|
||||
static void window_custom_scrollgetsize(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height);
|
||||
static void window_custom_scrollmousedrag(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords);
|
||||
|
@ -70,6 +71,7 @@ namespace OpenRCT2::Ui::Windows
|
|||
events.resize = &window_custom_resize;
|
||||
events.mouse_down = &window_custom_mousedown;
|
||||
events.dropdown = &window_custom_dropdown;
|
||||
events.text_input = &window_custom_textinput;
|
||||
events.update = &window_custom_update;
|
||||
events.get_scroll_size = &window_custom_scrollgetsize;
|
||||
events.scroll_mousedown = &window_custom_scrollmousedown;
|
||||
|
@ -98,6 +100,7 @@ namespace OpenRCT2::Ui::Windows
|
|||
std::vector<ListViewColumn> ListViewColumns;
|
||||
ScrollbarType Scrollbars{};
|
||||
int32_t SelectedIndex{};
|
||||
int32_t MaxLength{};
|
||||
std::optional<RowColumn> SelectedCell;
|
||||
bool IsChecked{};
|
||||
bool IsDisabled{};
|
||||
|
@ -194,6 +197,12 @@ namespace OpenRCT2::Ui::Windows
|
|||
result.OnIncrement = desc["onIncrement"];
|
||||
result.OnDecrement = desc["onDecrement"];
|
||||
}
|
||||
else if (result.Type == "textbox")
|
||||
{
|
||||
result.Text = ProcessString(desc["text"]);
|
||||
result.MaxLength = AsOrDefault(desc["maxLength"], 32);
|
||||
result.OnChange = desc["onChange"];
|
||||
}
|
||||
result.HasBorder = AsOrDefault(desc["border"], result.HasBorder);
|
||||
return result;
|
||||
}
|
||||
|
@ -554,6 +563,11 @@ namespace OpenRCT2::Ui::Windows
|
|||
InvokeEventHandler(info.Owner, widgetDesc->OnIncrement);
|
||||
}
|
||||
}
|
||||
else if (widgetDesc->Type == "textbox")
|
||||
{
|
||||
auto* text = const_cast<char*>(widgetDesc->Text.c_str());
|
||||
window_start_textbox(w, widgetIndex, STR_STRING, text, widgetDesc->MaxLength + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -577,6 +591,28 @@ namespace OpenRCT2::Ui::Windows
|
|||
}
|
||||
}
|
||||
|
||||
static void window_custom_textinput(rct_window* w, rct_widgetindex widgetIndex, char* text)
|
||||
{
|
||||
if (text == nullptr)
|
||||
return;
|
||||
|
||||
auto& info = GetInfo(w);
|
||||
auto widgetDesc = info.GetCustomWidgetDesc(w, widgetIndex);
|
||||
if (widgetDesc != nullptr)
|
||||
{
|
||||
if (widgetDesc->Type == "textbox")
|
||||
{
|
||||
UpdateWidgetText(w, widgetIndex, text);
|
||||
|
||||
std::vector<DukValue> args;
|
||||
auto ctx = widgetDesc->OnChange.context();
|
||||
duk_push_string(ctx, text);
|
||||
args.push_back(DukValue::take_from_stack(ctx));
|
||||
InvokeEventHandler(info.Owner, widgetDesc->OnChange, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void window_custom_update(rct_window* w)
|
||||
{
|
||||
const auto& info = GetInfo(w);
|
||||
|
@ -961,6 +997,13 @@ namespace OpenRCT2::Ui::Windows
|
|||
widget.text = STR_NUMERIC_UP;
|
||||
widgetList.push_back(widget);
|
||||
}
|
||||
else if (desc.Type == "textbox")
|
||||
{
|
||||
widget.type = WindowWidgetType::TextBox;
|
||||
widget.string = const_cast<utf8*>(desc.Text.c_str());
|
||||
widget.flags |= WIDGET_FLAGS::TEXT_IS_STRING;
|
||||
widgetList.push_back(widget);
|
||||
}
|
||||
else if (desc.Type == "viewport")
|
||||
{
|
||||
widget.type = WindowWidgetType::Viewport;
|
||||
|
@ -1327,6 +1370,33 @@ namespace OpenRCT2::Ui::Windows
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t GetWidgetMaxLength(rct_window* w, rct_widgetindex widgetIndex)
|
||||
{
|
||||
if (w->custom_info != nullptr)
|
||||
{
|
||||
auto& customInfo = GetInfo(w);
|
||||
auto customWidgetInfo = customInfo.GetCustomWidgetDesc(w, widgetIndex);
|
||||
if (customWidgetInfo != nullptr)
|
||||
{
|
||||
return customWidgetInfo->MaxLength;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetWidgetMaxLength(rct_window* w, rct_widgetindex widgetIndex, int32_t value)
|
||||
{
|
||||
if (w->custom_info != nullptr)
|
||||
{
|
||||
auto& customInfo = GetInfo(w);
|
||||
auto customWidgetInfo = customInfo.GetCustomWidgetDesc(w, widgetIndex);
|
||||
if (customWidgetInfo != nullptr)
|
||||
{
|
||||
customWidgetInfo->MaxLength = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenRCT2::Ui::Windows
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,8 @@ namespace OpenRCT2::Ui::Windows
|
|||
std::string GetWidgetName(rct_window* w, rct_widgetindex widgetIndex);
|
||||
void SetWidgetName(rct_window* w, rct_widgetindex widgetIndex, std::string_view name);
|
||||
CustomListView* GetCustomListView(rct_window* w, rct_widgetindex widgetIndex);
|
||||
int32_t GetWidgetMaxLength(rct_window* w, rct_widgetindex widgetIndex);
|
||||
void SetWidgetMaxLength(rct_window* w, rct_widgetindex widgetIndex, int32_t value);
|
||||
} // namespace OpenRCT2::Ui::Windows
|
||||
|
||||
#endif
|
||||
|
|
|
@ -832,6 +832,41 @@ namespace OpenRCT2::Scripting
|
|||
}
|
||||
};
|
||||
|
||||
class ScTextBoxWidget : public ScWidget
|
||||
{
|
||||
public:
|
||||
ScTextBoxWidget(rct_windowclass c, rct_windownumber n, rct_widgetindex widgetIndex)
|
||||
: ScWidget(c, n, widgetIndex)
|
||||
{
|
||||
}
|
||||
|
||||
static void Register(duk_context* ctx)
|
||||
{
|
||||
dukglue_set_base_class<ScWidget, ScTextBoxWidget>(ctx);
|
||||
dukglue_register_property(ctx, &ScTextBoxWidget::maxLength_get, &ScTextBoxWidget::maxLength_set, "maxLength");
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t maxLength_get() const
|
||||
{
|
||||
auto w = GetWindow();
|
||||
if (w != nullptr && IsCustomWindow())
|
||||
{
|
||||
return OpenRCT2::Ui::Windows::GetWidgetMaxLength(w, _widgetIndex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void maxLength_set(int32_t value)
|
||||
{
|
||||
auto w = GetWindow();
|
||||
if (w != nullptr && IsCustomWindow())
|
||||
{
|
||||
OpenRCT2::Ui::Windows::SetWidgetMaxLength(w, _widgetIndex, value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline DukValue ScWidget::ToDukValue(duk_context* ctx, rct_window* w, rct_widgetindex widgetIndex)
|
||||
{
|
||||
const auto& widget = w->widgets[widgetIndex];
|
||||
|
@ -851,6 +886,8 @@ namespace OpenRCT2::Scripting
|
|||
return GetObjectAsDukValue(ctx, std::make_shared<ScDropdownWidget>(c, n, widgetIndex));
|
||||
case WindowWidgetType::Scroll:
|
||||
return GetObjectAsDukValue(ctx, std::make_shared<ScListViewWidget>(c, n, widgetIndex));
|
||||
case WindowWidgetType::TextBox:
|
||||
return GetObjectAsDukValue(ctx, std::make_shared<ScTextBoxWidget>(c, n, widgetIndex));
|
||||
default:
|
||||
return GetObjectAsDukValue(ctx, std::make_shared<ScWidget>(c, n, widgetIndex));
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ void UiScriptExtensions::Extend(ScriptEngine& scriptEngine)
|
|||
ScCheckBoxWidget::Register(ctx);
|
||||
ScDropdownWidget::Register(ctx);
|
||||
ScListViewWidget::Register(ctx);
|
||||
ScTextBoxWidget::Register(ctx);
|
||||
ScWindow::Register(ctx);
|
||||
|
||||
InitialiseCustomMenuItems(scriptEngine);
|
||||
|
|
|
@ -2003,12 +2003,18 @@ void window_cancel_textbox()
|
|||
if (gUsingWidgetTextBox)
|
||||
{
|
||||
rct_window* w = window_find_by_number(gCurrentTextBox.window.classification, gCurrentTextBox.window.number);
|
||||
window_event_textinput_call(w, gCurrentTextBox.widget_index, nullptr);
|
||||
if (w != nullptr)
|
||||
{
|
||||
window_event_textinput_call(w, gCurrentTextBox.widget_index, nullptr);
|
||||
}
|
||||
gCurrentTextBox.window.classification = WC_NULL;
|
||||
gCurrentTextBox.window.number = 0;
|
||||
context_stop_text_input();
|
||||
gUsingWidgetTextBox = false;
|
||||
widget_invalidate(w, gCurrentTextBox.widget_index);
|
||||
if (w != nullptr)
|
||||
{
|
||||
widget_invalidate(w, gCurrentTextBox.widget_index);
|
||||
}
|
||||
gCurrentTextBox.widget_index = static_cast<uint16_t>(WindowWidgetType::Last);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue