mirror of
https://github.com/OpenRCT2/OpenRCT2.git
synced 2025-01-23 10:51:58 -05:00
Implement checkboxes and disabling widgets
This commit is contained in:
parent
a9a67a7a7e
commit
da98ef63d3
5 changed files with 136 additions and 22 deletions
9
distribution/openrct2.d.ts
vendored
9
distribution/openrct2.d.ts
vendored
|
@ -326,7 +326,7 @@ export interface Park {
|
|||
* Represents the type of a widget, e.g. button or label.
|
||||
*/
|
||||
export type WidgetType =
|
||||
"button" | "dropdown" | "groupbox" | "label" | "tabview" | "viewport";
|
||||
"button" | "checkbox" | "dropdown" | "groupbox" | "label" | "tabview" | "viewport";
|
||||
|
||||
export interface Widget {
|
||||
type: WidgetType;
|
||||
|
@ -334,6 +334,7 @@ export interface Widget {
|
|||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
isDisabled: boolean;
|
||||
}
|
||||
|
||||
export interface ButtonWidget extends Widget {
|
||||
|
@ -341,6 +342,12 @@ export interface ButtonWidget extends Widget {
|
|||
onClick: () => void;
|
||||
}
|
||||
|
||||
export interface CheckboxWidget extends Widget {
|
||||
text: string;
|
||||
isChecked: number;
|
||||
onChanged: (isChecked: boolean) => void;
|
||||
}
|
||||
|
||||
export interface DropdownWidget extends Widget {
|
||||
items: string[];
|
||||
selectedIndex: number;
|
||||
|
|
|
@ -438,6 +438,26 @@ static void widget_text_inset(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti
|
|||
widget_text(dpi, w, widgetIndex);
|
||||
}
|
||||
|
||||
static std::pair<rct_string_id, void*> widget_get_stringid_and_args(const rct_widget* widget)
|
||||
{
|
||||
auto stringId = widget->text;
|
||||
void* formatArgs = gCommonFormatArgs;
|
||||
if (widget->flags & WIDGET_FLAGS::TEXT_IS_STRING)
|
||||
{
|
||||
if (widget->string == nullptr || widget->string[0] == '\0')
|
||||
{
|
||||
stringId = STR_NONE;
|
||||
formatArgs = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
stringId = STR_STRING;
|
||||
formatArgs = (void*)&widget->string;
|
||||
}
|
||||
}
|
||||
return std::make_pair(stringId, formatArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006EB535
|
||||
|
@ -455,21 +475,7 @@ static void widget_groupbox_draw(rct_drawpixelinfo* dpi, rct_window* w, rct_widg
|
|||
int32_t textRight = l;
|
||||
|
||||
// Text
|
||||
auto stringId = widget->text;
|
||||
void* formatArgs = gCommonFormatArgs;
|
||||
if (widget->flags & WIDGET_FLAGS::TEXT_IS_STRING)
|
||||
{
|
||||
if (widget->string == nullptr || widget->string[0] == '\0')
|
||||
{
|
||||
stringId = STR_NONE;
|
||||
formatArgs = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
stringId = STR_STRING;
|
||||
formatArgs = &widget->string;
|
||||
}
|
||||
}
|
||||
auto [stringId, formatArgs] = widget_get_stringid_and_args(widget);
|
||||
if (stringId != STR_NONE)
|
||||
{
|
||||
uint8_t colour = w->colours[widget->colour] & 0x7F;
|
||||
|
@ -639,7 +645,8 @@ static void widget_checkbox_draw(rct_drawpixelinfo* dpi, rct_window* w, rct_widg
|
|||
if (widget->text == STR_NONE)
|
||||
return;
|
||||
|
||||
gfx_draw_string_left_centred(dpi, widget->text, gCommonFormatArgs, colour, l + 14, yMid);
|
||||
auto [stringId, formatArgs] = widget_get_stringid_and_args(widget);
|
||||
gfx_draw_string_left_centred(dpi, stringId, formatArgs, colour, l + 14, yMid);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -91,11 +91,20 @@ namespace OpenRCT2::Ui::Windows
|
|||
std::string Text;
|
||||
std::vector<std::string> Items;
|
||||
int32_t SelectedIndex{};
|
||||
bool IsChecked{};
|
||||
bool IsDisabled{};
|
||||
|
||||
// Event handlers
|
||||
DukValue OnClick;
|
||||
DukValue OnChange;
|
||||
|
||||
static std::string ProcessString(const DukValue& value)
|
||||
{
|
||||
if (value.type() == DukValue::Type::STRING)
|
||||
return ProcessString(value.as_string());
|
||||
return {};
|
||||
}
|
||||
|
||||
static std::string ProcessString(const std::string_view& s)
|
||||
{
|
||||
std::string result;
|
||||
|
@ -124,22 +133,32 @@ namespace OpenRCT2::Ui::Windows
|
|||
result.Height = desc["height"].as_int();
|
||||
if (result.Type == "button")
|
||||
{
|
||||
result.Text = desc["text"].as_string();
|
||||
result.Text = ProcessString(desc["text"]);
|
||||
result.OnClick = desc["onClick"];
|
||||
}
|
||||
else if (result.Type == "checkbox")
|
||||
{
|
||||
result.Text = ProcessString(desc["text"]);
|
||||
auto dukIsChecked = desc["isChecked"];
|
||||
if (dukIsChecked.type() == DukValue::Type::BOOLEAN)
|
||||
{
|
||||
result.IsChecked = dukIsChecked.as_bool();
|
||||
}
|
||||
result.OnChange = desc["onChange"];
|
||||
}
|
||||
else if (result.Type == "dropdown")
|
||||
{
|
||||
auto dukItems = desc["items"].as_array();
|
||||
for (const auto& dukItem : dukItems)
|
||||
{
|
||||
result.Items.push_back(dukItem.as_string());
|
||||
result.Items.push_back(ProcessString(dukItem));
|
||||
}
|
||||
result.SelectedIndex = desc["selectedIndex"].as_int();
|
||||
result.OnChange = desc["onChange"];
|
||||
}
|
||||
else if (result.Type == "groupbox" || result.Type == "label")
|
||||
{
|
||||
result.Text = ProcessString(desc["text"].as_string());
|
||||
result.Text = ProcessString(desc["text"]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -312,6 +331,20 @@ namespace OpenRCT2::Ui::Windows
|
|||
{
|
||||
InvokeEventHandler(info.Owner, widgetDesc->OnClick);
|
||||
}
|
||||
else if (widgetDesc->Type == "checkbox")
|
||||
{
|
||||
auto& widget = w->widgets[widgetIndex];
|
||||
widget.flags ^= WIDGET_FLAGS::IS_PRESSED;
|
||||
bool isChecked = widget.flags & WIDGET_FLAGS::IS_PRESSED;
|
||||
|
||||
widget_set_checkbox_value(w, widgetIndex, isChecked);
|
||||
|
||||
std::vector<DukValue> args;
|
||||
auto ctx = widgetDesc->OnChange.context();
|
||||
duk_push_boolean(ctx, isChecked);
|
||||
args.push_back(DukValue::take_from_stack(ctx));
|
||||
InvokeEventHandler(info.Owner, widgetDesc->OnChange, args);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -429,6 +462,8 @@ namespace OpenRCT2::Ui::Windows
|
|||
widget.bottom = desc.Y + desc.Height;
|
||||
widget.tooltip = STR_NONE;
|
||||
widget.flags = WIDGET_FLAGS::IS_ENABLED;
|
||||
if (desc.IsDisabled)
|
||||
widget.flags |= WIDGET_FLAGS::IS_DISABLED;
|
||||
|
||||
if (desc.Type == "button")
|
||||
{
|
||||
|
@ -437,6 +472,17 @@ namespace OpenRCT2::Ui::Windows
|
|||
widget.flags |= WIDGET_FLAGS::TEXT_IS_STRING;
|
||||
widgetList.push_back(widget);
|
||||
}
|
||||
else if (desc.Type == "checkbox")
|
||||
{
|
||||
widget.type = WWT_CHECKBOX;
|
||||
widget.string = (utf8*)desc.Text.c_str();
|
||||
widget.flags |= WIDGET_FLAGS::TEXT_IS_STRING;
|
||||
if (desc.IsChecked)
|
||||
{
|
||||
widget.flags |= WIDGET_FLAGS::IS_PRESSED;
|
||||
}
|
||||
widgetList.push_back(widget);
|
||||
}
|
||||
else if (desc.Type == "dropdown")
|
||||
{
|
||||
widget.type = WWT_DROPDOWN;
|
||||
|
@ -510,9 +556,19 @@ namespace OpenRCT2::Ui::Windows
|
|||
w->enabled_widgets = 1ULL << WIDX_CLOSE;
|
||||
for (size_t i = 0; i < std::min<size_t>(widgets.size(), 64); i++)
|
||||
{
|
||||
if (widgets[i].flags & WIDGET_FLAGS::IS_ENABLED)
|
||||
auto mask = 1ULL << i;
|
||||
auto flags = widgets[i].flags;
|
||||
if (flags & WIDGET_FLAGS::IS_ENABLED)
|
||||
{
|
||||
w->enabled_widgets |= 1ULL << i;
|
||||
w->enabled_widgets |= mask;
|
||||
}
|
||||
if (flags & WIDGET_FLAGS::IS_PRESSED)
|
||||
{
|
||||
w->pressed_widgets |= mask;
|
||||
}
|
||||
if (flags & WIDGET_FLAGS::IS_DISABLED)
|
||||
{
|
||||
w->disabled_widgets |= mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,6 +163,46 @@ namespace OpenRCT2::Scripting
|
|||
}
|
||||
}
|
||||
|
||||
bool isDisabled_get()
|
||||
{
|
||||
auto w = GetWindow();
|
||||
if (w != nullptr)
|
||||
{
|
||||
return widget_is_disabled(w, _widgetIndex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void isDisabled_set(bool value)
|
||||
{
|
||||
auto w = GetWindow();
|
||||
if (w != nullptr)
|
||||
{
|
||||
auto mask = 1ULL << _widgetIndex;
|
||||
if (value)
|
||||
w->disabled_widgets |= mask;
|
||||
else
|
||||
w->disabled_widgets &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
bool isChecked_get()
|
||||
{
|
||||
auto w = GetWindow();
|
||||
if (w != nullptr)
|
||||
{
|
||||
return widget_is_pressed(w, _widgetIndex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void isChecked_set(bool value)
|
||||
{
|
||||
auto w = GetWindow();
|
||||
if (w != nullptr)
|
||||
{
|
||||
widget_set_checkbox_value(w, _widgetIndex, value ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
std::string text_get()
|
||||
{
|
||||
if (IsCustomWindow())
|
||||
|
@ -193,9 +233,11 @@ namespace OpenRCT2::Scripting
|
|||
dukglue_register_property(ctx, &y_get, &y_set, "y");
|
||||
dukglue_register_property(ctx, &width_get, &width_set, "width");
|
||||
dukglue_register_property(ctx, &height_get, &height_set, "height");
|
||||
dukglue_register_property(ctx, &isDisabled_get, &isDisabled_set, "isDisabled");
|
||||
|
||||
// No so common
|
||||
dukglue_register_property(ctx, &text_get, &text_set, "text");
|
||||
dukglue_register_property(ctx, &isChecked_get, &isChecked_set, "isChecked");
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -69,6 +69,8 @@ namespace WIDGET_FLAGS
|
|||
{
|
||||
const WidgetFlags TEXT_IS_STRING = 1 << 0;
|
||||
const WidgetFlags IS_ENABLED = 1 << 1;
|
||||
const WidgetFlags IS_PRESSED = 1 << 2;
|
||||
const WidgetFlags IS_DISABLED = 1 << 3;
|
||||
} // namespace WIDGET_FLAGS
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue