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:
@@ -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.
|
||||
|
||||
7
distribution/openrct2.d.ts
vendored
7
distribution/openrct2.d.ts
vendored
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -10,3 +10,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <openrct2/interface/Widget.h>
|
||||
|
||||
uint32_t GetColourButtonImage(colour_t colour);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user