1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-24 08:12:53 +01:00

Fix #13078: [Plugin] Add colour picker widget

This commit is contained in:
Ted John
2020-12-02 00:21:33 +00:00
parent a55bcff99c
commit 030713e126
8 changed files with 123 additions and 4 deletions

View File

@@ -1,6 +1,7 @@
0.3.2+ (in development)
------------------------------------------------------------------------
- Feature: [#13057] Make GameAction flags accessible by plugins.
- Feature: [#13078] [Plugin] Add colour picker widget.
- Feature: [#13376] Open custom window at specified tab.
- Feature: [#13398] Add pause button to the Track Designer.
- Feature: [#13495] [Plugin] Add properties for park value, guests and company value.

View File

@@ -1784,7 +1784,7 @@ declare global {
* Represents the type of a widget, e.g. button or label.
*/
type WidgetType =
"button" | "checkbox" | "dropdown" | "groupbox" | "label" | "listview" | "spinner" | "viewport";
"button" | "checkbox" | "colourpicker" | "dropdown" | "groupbox" | "label" | "listview" | "spinner" | "viewport";
interface Widget {
type: WidgetType;
@@ -1815,6 +1815,11 @@ declare global {
onChange: (isChecked: boolean) => void;
}
interface ColourPickerWidget extends Widget {
colour: number;
onChange: (colour: number) => void;
}
interface DropdownWidget extends Widget {
items: string[];
selectedIndex: number;

View File

@@ -1105,3 +1105,8 @@ static void WidgetTextBoxDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti
gfx_fill_rect(dpi, { { cur_x, y }, { cur_x + width, y } }, colour + 5);
}
}
uint32_t GetColourButtonImage(colour_t colour)
{
return SPRITE_ID_PALETTE_COLOUR_1(colour) | IMAGE_TYPE_TRANSPARENT | SPR_PALETTE_BTN;
}

View File

@@ -10,3 +10,5 @@
#pragma once
#include <openrct2/interface/Widget.h>
uint32_t GetColourButtonImage(colour_t colour);

View File

@@ -91,6 +91,7 @@ namespace OpenRCT2::Ui::Windows
std::string Name;
ImageId Image;
std::string Text;
colour_t Colour;
std::string Tooltip;
std::vector<std::string> Items;
std::vector<ListViewItem> ListViewItems;
@@ -147,6 +148,15 @@ namespace OpenRCT2::Ui::Windows
result.IsChecked = AsOrDefault(desc["isChecked"], false);
result.OnChange = desc["onChange"];
}
else if (result.Type == "colourpicker")
{
auto colour = AsOrDefault(desc["colour"], 0);
if (colour < COLOUR_COUNT)
{
result.Colour = colour;
}
result.OnChange = desc["onChange"];
}
else if (result.Type == "dropdown")
{
auto dukItems = desc["items"].as_array();
@@ -510,7 +520,11 @@ namespace OpenRCT2::Ui::Windows
const auto widgetDesc = info.GetCustomWidgetDesc(w, widgetIndex);
if (widgetDesc != nullptr)
{
if (widgetDesc->Type == "dropdown")
if (widgetDesc->Type == "colourpicker")
{
WindowDropdownShowColour(w, widget, w->colours[widget->colour], widgetDesc->Colour);
}
else if (widgetDesc->Type == "dropdown")
{
widget--;
auto selectedIndex = widgetDesc->SelectedIndex;
@@ -550,7 +564,11 @@ namespace OpenRCT2::Ui::Windows
auto widgetDesc = info.GetCustomWidgetDesc(w, widgetIndex);
if (widgetDesc != nullptr)
{
if (widgetDesc->Type == "dropdown")
if (widgetDesc->Type == "colourpicker")
{
UpdateWidgetColour(w, widgetIndex, dropdownIndex);
}
else if (widgetDesc->Type == "dropdown")
{
UpdateWidgetSelectedIndex(w, widgetIndex - 1, dropdownIndex);
}
@@ -846,6 +864,12 @@ namespace OpenRCT2::Ui::Windows
}
widgetList.push_back(widget);
}
else if (desc.Type == "colourpicker")
{
widget.type = WindowWidgetType::ColourBtn;
widget.image = GetColourButtonImage(desc.Colour);
widgetList.push_back(widget);
}
else if (desc.Type == "dropdown")
{
widget.type = WindowWidgetType::DropdownMenu;
@@ -1102,6 +1126,33 @@ namespace OpenRCT2::Ui::Windows
}
}
void UpdateWidgetColour(rct_window* w, rct_widgetindex widgetIndex, colour_t colour)
{
if (w->custom_info != nullptr)
{
auto& customInfo = GetInfo(w);
auto customWidgetInfo = customInfo.GetCustomWidgetDesc(w, widgetIndex);
if (customWidgetInfo != nullptr)
{
auto& widget = w->widgets[widgetIndex];
auto lastColour = customWidgetInfo->Colour;
if (lastColour != colour && colour < COLOUR_COUNT)
{
customWidgetInfo->Colour = colour;
widget.image = GetColourButtonImage(colour);
widget_invalidate(w, widgetIndex);
std::vector<DukValue> args;
auto ctx = customWidgetInfo->OnChange.context();
duk_push_int(ctx, colour);
args.push_back(DukValue::take_from_stack(ctx));
InvokeEventHandler(customInfo.Owner, customWidgetInfo->OnChange, args);
}
}
}
}
void UpdateWidgetSelectedIndex(rct_window* w, rct_widgetindex widgetIndex, int32_t selectedIndex)
{
if (w->custom_info != nullptr)
@@ -1163,6 +1214,20 @@ namespace OpenRCT2::Ui::Windows
return {};
}
colour_t GetWidgetColour(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->Colour;
}
}
return COLOUR_BLACK;
}
int32_t GetWidgetSelectedIndex(rct_window* w, rct_widgetindex widgetIndex)
{
if (w->custom_info != nullptr)

View File

@@ -24,8 +24,10 @@ namespace OpenRCT2::Ui::Windows
void UpdateWindowTitle(rct_window* w, const std::string_view& value);
void UpdateWidgetText(rct_window* w, rct_widgetindex widget, const std::string_view& string_view);
void UpdateWidgetItems(rct_window* w, rct_widgetindex widgetIndex, const std::vector<std::string>& items);
void UpdateWidgetColour(rct_window* w, rct_widgetindex widgetIndex, colour_t colour);
void UpdateWidgetSelectedIndex(rct_window* w, rct_widgetindex widgetIndex, int32_t selectedIndex);
std::vector<std::string> GetWidgetItems(rct_window* w, rct_widgetindex widgetIndex);
colour_t GetWidgetColour(rct_window* w, rct_widgetindex widgetIndex);
int32_t GetWidgetSelectedIndex(rct_window* w, rct_widgetindex widgetIndex);
rct_window* FindCustomWindowByClassification(const std::string_view& classification);
std::optional<rct_widgetindex> FindWidgetIndexByName(rct_window* w, const std::string_view& name);

View File

@@ -74,12 +74,13 @@ namespace OpenRCT2::Scripting
case WindowWidgetType::Resize:
return "resize";
case WindowWidgetType::ImgBtn:
case WindowWidgetType::ColourBtn:
case WindowWidgetType::TrnBtn:
case WindowWidgetType::FlatBtn:
case WindowWidgetType::Button:
case WindowWidgetType::CloseBox:
return "button";
case WindowWidgetType::ColourBtn:
return "colourpicker";
case WindowWidgetType::Tab:
return "tab";
case WindowWidgetType::LabelCentred:
@@ -517,6 +518,41 @@ namespace OpenRCT2::Scripting
}
};
class ScColourPickerWidget : public ScWidget
{
public:
ScColourPickerWidget(rct_windowclass c, rct_windownumber n, rct_widgetindex widgetIndex)
: ScWidget(c, n, widgetIndex)
{
}
static void Register(duk_context* ctx)
{
dukglue_set_base_class<ScWidget, ScColourPickerWidget>(ctx);
dukglue_register_property(ctx, &ScColourPickerWidget::colour_get, &ScColourPickerWidget::colour_set, "colour");
}
private:
colour_t colour_get() const
{
auto w = GetWindow();
if (w != nullptr)
{
return GetWidgetColour(w, _widgetIndex);
}
return COLOUR_BLACK;
}
void colour_set(colour_t value)
{
auto w = GetWindow();
if (w != nullptr)
{
UpdateWidgetColour(w, _widgetIndex, value);
Invalidate();
}
}
};
class ScDropdownWidget : public ScWidget
{
public:
@@ -776,6 +812,8 @@ namespace OpenRCT2::Scripting
return GetObjectAsDukValue(ctx, std::make_shared<ScButtonWidget>(c, n, widgetIndex));
case WindowWidgetType::Checkbox:
return GetObjectAsDukValue(ctx, std::make_shared<ScCheckBoxWidget>(c, n, widgetIndex));
case WindowWidgetType::ColourBtn:
return GetObjectAsDukValue(ctx, std::make_shared<ScColourPickerWidget>(c, n, widgetIndex));
case WindowWidgetType::DropdownMenu:
return GetObjectAsDukValue(ctx, std::make_shared<ScDropdownWidget>(c, n, widgetIndex));
case WindowWidgetType::Scroll:

View File

@@ -33,6 +33,7 @@ void UiScriptExtensions::Extend(ScriptEngine& scriptEngine)
ScViewport::Register(ctx);
ScWidget::Register(ctx);
ScButtonWidget::Register(ctx);
ScColourPickerWidget::Register(ctx);
ScCheckBoxWidget::Register(ctx);
ScDropdownWidget::Register(ctx);
ScListViewWidget::Register(ctx);