mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-24 00:03:11 +01:00
Merge pull request #13927 from IntelOrca/plugin/extra-ui
* Add isVisible property to widgets so that you can easily show / hide widgets. * Add new text box widget for text input * Allow plugin windows to be transparent * Add `textAlign` property to label widget
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
- Feature: [#13613] Add single-rail roller coaster (Rocky Mountain Construction Raptor).
|
- Feature: [#13613] Add single-rail roller coaster (Rocky Mountain Construction Raptor).
|
||||||
- Feature: [#13614] Add terrain surfaces from RollerCoaster Tycoon 1.
|
- Feature: [#13614] Add terrain surfaces from RollerCoaster Tycoon 1.
|
||||||
- Feature: [#13675] [Plugin] Add context.setInterval and context.setTimeout.
|
- 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.
|
- Change: [#13346] [Plugin] Renamed FootpathScenery to FootpathAddition, fix typos.
|
||||||
- Change: [#13857] Change Rotation Control Toggle to track element number 256
|
- Change: [#13857] Change Rotation Control Toggle to track element number 256
|
||||||
- Fix: [#4605, #11912] Water palettes are not updated properly when selected in Object Selection.
|
- Fix: [#4605, #11912] Water palettes are not updated properly when selected in Object Selection.
|
||||||
|
|||||||
183
distribution/openrct2.d.ts
vendored
183
distribution/openrct2.d.ts
vendored
@@ -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
|
* For a complete list of all authors, please refer to contributors.md
|
||||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||||
@@ -990,7 +990,19 @@ declare global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type EntityType =
|
type EntityType =
|
||||||
"car" | "duck" | "peep" | "steam_particle" | "money_effect" | "crashed_vehicle_particle" | "explosion_cloud" | "crash_splash" | "explosion_flare" | "jumping_fountain_water" | "balloon" | "jumping_fountain_snow";
|
"balloon" |
|
||||||
|
"car" |
|
||||||
|
"crash_splash" |
|
||||||
|
"crashed_vehicle_particle" |
|
||||||
|
"duck" |
|
||||||
|
"explosion_cloud" |
|
||||||
|
"explosion_flare" |
|
||||||
|
"jumping_fountain_snow" |
|
||||||
|
"jumping_fountain_water" |
|
||||||
|
"litter" |
|
||||||
|
"money_effect" |
|
||||||
|
"peep" |
|
||||||
|
"steam_particle";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an object "entity" on the map that can typically moves and has a sub-tile coordinate.
|
* Represents an object "entity" on the map that can typically moves and has a sub-tile coordinate.
|
||||||
@@ -1733,7 +1745,7 @@ declare global {
|
|||||||
readonly windows: number;
|
readonly windows: number;
|
||||||
readonly mainViewport: Viewport;
|
readonly mainViewport: Viewport;
|
||||||
readonly tileSelection: TileSelection;
|
readonly tileSelection: TileSelection;
|
||||||
readonly tool: Tool;
|
readonly tool: Tool | null;
|
||||||
|
|
||||||
getWindow(id: number): Window;
|
getWindow(id: number): Window;
|
||||||
getWindow(classification: string): Window;
|
getWindow(classification: string): Window;
|
||||||
@@ -1754,6 +1766,19 @@ declare global {
|
|||||||
*/
|
*/
|
||||||
showTextInput(desc: TextInputDesc): void;
|
showTextInput(desc: TextInputDesc): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the window for loading or saving a file and calls the given callback when a file
|
||||||
|
* is selected.
|
||||||
|
* @param desc The parameters for the file browse window.
|
||||||
|
*/
|
||||||
|
showFileBrowse(desc: FileBrowseDesc): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the scenario select window and calls the given callback when a scenario is
|
||||||
|
* selected.
|
||||||
|
*/
|
||||||
|
showScenarioSelect(desc: ScenarioSelectDesc): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begins a new tool session. The cursor will change to the style specified by the
|
* Begins a new tool session. The cursor will change to the style specified by the
|
||||||
* given tool descriptor and cursor events will be provided.
|
* given tool descriptor and cursor events will be provided.
|
||||||
@@ -1794,6 +1819,59 @@ declare global {
|
|||||||
callback: (value: string) => void;
|
callback: (value: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters for the file browse window.
|
||||||
|
*/
|
||||||
|
interface FileBrowseDesc {
|
||||||
|
/**
|
||||||
|
* Whether to browse a file for loading or saving. Saving will prompt the user
|
||||||
|
* before overwriting a file.
|
||||||
|
*/
|
||||||
|
type: 'load';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of file to browse for.
|
||||||
|
*/
|
||||||
|
fileType: 'game' | 'heightmap';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pre-selected file to load by default if the user clicks OK.
|
||||||
|
*/
|
||||||
|
defaultPath?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function to call when the user has selected a file.
|
||||||
|
*/
|
||||||
|
callback: (path: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters for the scenario select window.
|
||||||
|
*/
|
||||||
|
interface ScenarioSelectDesc {
|
||||||
|
/**
|
||||||
|
* The function to call when the user has selected a scenario.
|
||||||
|
*/
|
||||||
|
callback: (scenario: ScenarioFile) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an installed scenario's path and metadata.
|
||||||
|
*/
|
||||||
|
interface ScenarioFile {
|
||||||
|
id: number;
|
||||||
|
category: 'beginner' | 'challenging' | 'expert' | 'real' | 'other' | 'dlc' | 'build_your_own';
|
||||||
|
sourceGame: 'rct1' | 'rct1_aa' | 'rct1_ll' | 'rct2' | 'rct2_ww' | 'rct2_tt' | 'real' | 'other';
|
||||||
|
path: string;
|
||||||
|
internalName: string;
|
||||||
|
name: string;
|
||||||
|
details: string;
|
||||||
|
highscore: {
|
||||||
|
name: string;
|
||||||
|
companyValue: number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface TileSelection {
|
interface TileSelection {
|
||||||
range: MapRange;
|
range: MapRange;
|
||||||
tiles: CoordsXY[];
|
tiles: CoordsXY[];
|
||||||
@@ -1821,11 +1899,11 @@ declare global {
|
|||||||
id: string;
|
id: string;
|
||||||
cursor?: CursorType;
|
cursor?: CursorType;
|
||||||
|
|
||||||
onStart: () => void;
|
onStart?: () => void;
|
||||||
onDown: (e: ToolEventArgs) => void;
|
onDown?: (e: ToolEventArgs) => void;
|
||||||
onMove: (e: ToolEventArgs) => void;
|
onMove?: (e: ToolEventArgs) => void;
|
||||||
onUp: (e: ToolEventArgs) => void;
|
onUp?: (e: ToolEventArgs) => void;
|
||||||
onFinish: () => void;
|
onFinish?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
type CursorType =
|
type CursorType =
|
||||||
@@ -1861,10 +1939,14 @@ declare global {
|
|||||||
* Represents the type of a widget, e.g. button or label.
|
* Represents the type of a widget, e.g. button or label.
|
||||||
*/
|
*/
|
||||||
type WidgetType =
|
type WidgetType =
|
||||||
"button" | "checkbox" | "colourpicker" | "dropdown" | "groupbox" | "label" | "listview" | "spinner" | "viewport";
|
"button" | "checkbox" | "colourpicker" | "dropdown" | "groupbox" |
|
||||||
|
"label" | "listview" | "spinner" | "textbox" | "viewport";
|
||||||
|
|
||||||
interface Widget {
|
type Widget =
|
||||||
type: WidgetType;
|
ButtonWidget | CheckboxWidget | ColourPickerWidget | DropdownWidget | GroupBoxWidget |
|
||||||
|
LabelWidget | ListView | SpinnerWidget | TextBoxWidget | ViewportWidget;
|
||||||
|
|
||||||
|
interface WidgetBase {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
width: number;
|
width: number;
|
||||||
@@ -1872,42 +1954,55 @@ declare global {
|
|||||||
name?: string;
|
name?: string;
|
||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
isDisabled?: boolean;
|
isDisabled?: boolean;
|
||||||
|
isVisible?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ButtonWidget extends Widget {
|
interface ButtonWidget extends WidgetBase {
|
||||||
|
type: 'button';
|
||||||
/**
|
/**
|
||||||
* Whether the button has a 3D border.
|
* Whether the button has a 3D border.
|
||||||
* By default, text buttons have borders and image buttons do not but it can be overridden.
|
* By default, text buttons have borders and image buttons do not but it can be overridden.
|
||||||
*/
|
*/
|
||||||
border?: boolean;
|
border?: boolean;
|
||||||
image: number;
|
image?: number;
|
||||||
isPressed: boolean;
|
isPressed?: boolean;
|
||||||
text: string;
|
text?: string;
|
||||||
onClick: () => void;
|
onClick?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CheckboxWidget extends Widget {
|
interface CheckboxWidget extends WidgetBase {
|
||||||
text: string;
|
type: 'checkbox';
|
||||||
isChecked: boolean;
|
text?: string;
|
||||||
onChange: (isChecked: boolean) => void;
|
isChecked?: boolean;
|
||||||
|
onChange?: (isChecked: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ColourPickerWidget extends Widget {
|
interface ColourPickerWidget extends WidgetBase {
|
||||||
colour: number;
|
type: 'colourpicker';
|
||||||
onChange: (colour: number) => void;
|
colour?: number;
|
||||||
|
onChange?: (colour: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DropdownWidget extends Widget {
|
interface DropdownWidget extends WidgetBase {
|
||||||
items: string[];
|
type: 'dropdown';
|
||||||
selectedIndex: number;
|
items?: string[];
|
||||||
onChange: (index: number) => void;
|
selectedIndex?: number;
|
||||||
|
onChange?: (index: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LabelWidget extends Widget {
|
interface GroupBoxWidget extends WidgetBase {
|
||||||
text: string;
|
type: 'groupbox';
|
||||||
onChange: (index: number) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface LabelWidget extends WidgetBase {
|
||||||
|
type: 'label';
|
||||||
|
text?: string;
|
||||||
|
textAlign?: TextAlignment;
|
||||||
|
onChange?: (index: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
type TextAlignment = "left" | "centred";
|
||||||
|
|
||||||
type SortOrder = "none" | "ascending" | "descending";
|
type SortOrder = "none" | "ascending" | "descending";
|
||||||
|
|
||||||
type ScrollbarType = "none" | "horizontal" | "vertical" | "both";
|
type ScrollbarType = "none" | "horizontal" | "vertical" | "both";
|
||||||
@@ -1935,7 +2030,8 @@ declare global {
|
|||||||
column: number;
|
column: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ListView extends Widget {
|
interface ListView extends WidgetBase {
|
||||||
|
type: 'listview';
|
||||||
scrollbars?: ScrollbarType;
|
scrollbars?: ScrollbarType;
|
||||||
isStriped?: boolean;
|
isStriped?: boolean;
|
||||||
showColumnHeaders?: boolean;
|
showColumnHeaders?: boolean;
|
||||||
@@ -1945,18 +2041,27 @@ declare global {
|
|||||||
readonly highlightedCell?: RowColumn;
|
readonly highlightedCell?: RowColumn;
|
||||||
canSelect?: boolean;
|
canSelect?: boolean;
|
||||||
|
|
||||||
onHighlight: (item: number, column: number) => void;
|
onHighlight?: (item: number, column: number) => void;
|
||||||
onClick: (item: number, column: number) => void;
|
onClick?: (item: number, column: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SpinnerWidget extends Widget {
|
interface SpinnerWidget extends WidgetBase {
|
||||||
text: string;
|
type: 'spinner';
|
||||||
onDecrement: () => void;
|
text?: string;
|
||||||
onIncrement: () => void;
|
onDecrement?: () => void;
|
||||||
|
onIncrement?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ViewportWidget extends Widget {
|
interface TextBoxWidget extends WidgetBase {
|
||||||
viewport: Viewport
|
type: 'textbox';
|
||||||
|
text?: string;
|
||||||
|
maxLength?: number;
|
||||||
|
onChange?: (text: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ViewportWidget extends WidgetBase {
|
||||||
|
type: 'viewport';
|
||||||
|
viewport?: Viewport
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Window {
|
interface Window {
|
||||||
|
|||||||
@@ -1442,7 +1442,7 @@ static void InputUpdateTooltip(rct_window* w, rct_widgetindex widgetIndex, const
|
|||||||
if (gTooltipCursor == screenCoords)
|
if (gTooltipCursor == screenCoords)
|
||||||
{
|
{
|
||||||
_tooltipNotShownTicks++;
|
_tooltipNotShownTicks++;
|
||||||
if (_tooltipNotShownTicks > 50)
|
if (_tooltipNotShownTicks > 50 && WidgetIsVisible(w, widgetIndex))
|
||||||
{
|
{
|
||||||
gTooltipTimeout = 0;
|
gTooltipTimeout = 0;
|
||||||
window_tooltip_open(w, widgetIndex, screenCoords);
|
window_tooltip_open(w, widgetIndex, screenCoords);
|
||||||
@@ -1457,7 +1457,8 @@ static void InputUpdateTooltip(rct_window* w, rct_widgetindex widgetIndex, const
|
|||||||
reset_tooltip_not_shown();
|
reset_tooltip_not_shown();
|
||||||
|
|
||||||
if (w == nullptr || gTooltipWidget.window_classification != w->classification
|
if (w == nullptr || gTooltipWidget.window_classification != w->classification
|
||||||
|| gTooltipWidget.window_number != w->number || gTooltipWidget.widget_index != widgetIndex)
|
|| gTooltipWidget.window_number != w->number || gTooltipWidget.widget_index != widgetIndex
|
||||||
|
|| !WidgetIsVisible(w, widgetIndex))
|
||||||
{
|
{
|
||||||
window_tooltip_close();
|
window_tooltip_close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -357,8 +357,16 @@ static void WidgetTextCentred(rct_drawpixelinfo* dpi, rct_window* w, rct_widgeti
|
|||||||
stringId = STR_STRING;
|
stringId = STR_STRING;
|
||||||
ft.Add<utf8*>(widget->string);
|
ft.Add<utf8*>(widget->string);
|
||||||
}
|
}
|
||||||
DrawTextEllipsised(
|
|
||||||
dpi, { (topLeft.x + r + 1) / 2 - 1, topLeft.y }, widget->width() - 2, stringId, ft, colour, TextAlignment::CENTRE);
|
ScreenCoordsXY coords = { (topLeft.x + r + 1) / 2 - 1, topLeft.y };
|
||||||
|
if (widget->type == WindowWidgetType::LabelCentred)
|
||||||
|
{
|
||||||
|
gfx_draw_string_centred_wrapped(dpi, ft.Data(), coords, widget->width() - 2, stringId, colour);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawTextEllipsised(dpi, coords, widget->width() - 2, stringId, ft, colour, TextAlignment::CENTRE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -398,7 +406,16 @@ static void WidgetText(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex wi
|
|||||||
stringId = STR_STRING;
|
stringId = STR_STRING;
|
||||||
ft.Add<utf8*>(widget->string);
|
ft.Add<utf8*>(widget->string);
|
||||||
}
|
}
|
||||||
DrawTextEllipsised(dpi, { l + 1, t }, r - l, stringId, ft, colour);
|
|
||||||
|
ScreenCoordsXY coords = { l + 1, t };
|
||||||
|
if (widget->type == WindowWidgetType::LabelCentred)
|
||||||
|
{
|
||||||
|
gfx_draw_string_centred_wrapped(dpi, ft.Data(), coords, r - l, stringId, colour);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawTextEllipsised(dpi, coords, r - l, stringId, ft, colour);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -829,6 +846,8 @@ static void WidgetDrawImage(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetind
|
|||||||
|
|
||||||
bool WidgetIsEnabled(rct_window* w, rct_widgetindex widgetIndex)
|
bool WidgetIsEnabled(rct_window* w, rct_widgetindex widgetIndex)
|
||||||
{
|
{
|
||||||
|
if (!WidgetIsVisible(w, widgetIndex))
|
||||||
|
return false;
|
||||||
return (w->enabled_widgets & (1LL << widgetIndex)) != 0;
|
return (w->enabled_widgets & (1LL << widgetIndex)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -837,6 +856,11 @@ bool WidgetIsDisabled(rct_window* w, rct_widgetindex widgetIndex)
|
|||||||
return (w->disabled_widgets & (1LL << widgetIndex)) != 0;
|
return (w->disabled_widgets & (1LL << widgetIndex)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WidgetIsVisible(rct_window* w, rct_widgetindex widgetIndex)
|
||||||
|
{
|
||||||
|
return w->widgets[widgetIndex].IsVisible();
|
||||||
|
}
|
||||||
|
|
||||||
bool WidgetIsPressed(rct_window* w, rct_widgetindex widgetIndex)
|
bool WidgetIsPressed(rct_window* w, rct_widgetindex widgetIndex)
|
||||||
{
|
{
|
||||||
if (w->pressed_widgets & (1LL << widgetIndex))
|
if (w->pressed_widgets & (1LL << widgetIndex))
|
||||||
@@ -1026,6 +1050,18 @@ void WidgetSetDisabled(rct_window* w, rct_widgetindex widgetIndex, bool value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WidgetSetVisible(rct_window* w, rct_widgetindex widgetIndex, bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
w->widgets[widgetIndex].flags &= ~WIDGET_FLAGS::IS_HIDDEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
w->widgets[widgetIndex].flags |= WIDGET_FLAGS::IS_HIDDEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WidgetSetCheckboxValue(rct_window* w, rct_widgetindex widgetIndex, int32_t value)
|
void WidgetSetCheckboxValue(rct_window* w, rct_widgetindex widgetIndex, int32_t value)
|
||||||
{
|
{
|
||||||
if (value)
|
if (value)
|
||||||
|
|||||||
@@ -628,11 +628,13 @@ void WindowDrawWidgets(rct_window* w, rct_drawpixelinfo* dpi)
|
|||||||
widgetIndex = 0;
|
widgetIndex = 0;
|
||||||
for (widget = w->widgets; widget->type != WindowWidgetType::Last; widget++)
|
for (widget = w->widgets; widget->type != WindowWidgetType::Last; widget++)
|
||||||
{
|
{
|
||||||
// Check if widget is outside the draw region
|
if (widget->IsVisible())
|
||||||
if (w->windowPos.x + widget->left < dpi->x + dpi->width && w->windowPos.x + widget->right >= dpi->x)
|
{
|
||||||
if (w->windowPos.y + widget->top < dpi->y + dpi->height && w->windowPos.y + widget->bottom >= dpi->y)
|
// Check if widget is outside the draw region
|
||||||
WidgetDraw(dpi, w, widgetIndex);
|
if (w->windowPos.x + widget->left < dpi->x + dpi->width && w->windowPos.x + widget->right >= dpi->x)
|
||||||
|
if (w->windowPos.y + widget->top < dpi->y + dpi->height && w->windowPos.y + widget->bottom >= dpi->y)
|
||||||
|
WidgetDraw(dpi, w, widgetIndex);
|
||||||
|
}
|
||||||
widgetIndex++;
|
widgetIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -497,7 +497,7 @@ void CustomListView::MouseDown(const ScreenCoordsXY& pos)
|
|||||||
auto hitResult = GetItemIndexAt(pos);
|
auto hitResult = GetItemIndexAt(pos);
|
||||||
if (hitResult)
|
if (hitResult)
|
||||||
{
|
{
|
||||||
if (hitResult->Row != HEADER_ROW && OnClick.context() != nullptr && OnClick.is_function())
|
if (hitResult->Row != HEADER_ROW)
|
||||||
{
|
{
|
||||||
if (CanSelect)
|
if (CanSelect)
|
||||||
{
|
{
|
||||||
@@ -506,12 +506,15 @@ void CustomListView::MouseDown(const ScreenCoordsXY& pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto ctx = OnClick.context();
|
auto ctx = OnClick.context();
|
||||||
duk_push_int(ctx, static_cast<int32_t>(hitResult->Row));
|
if (ctx != nullptr && OnClick.is_function())
|
||||||
auto dukRow = DukValue::take_from_stack(ctx, -1);
|
{
|
||||||
duk_push_int(ctx, static_cast<int32_t>(hitResult->Column));
|
duk_push_int(ctx, static_cast<int32_t>(hitResult->Row));
|
||||||
auto dukColumn = DukValue::take_from_stack(ctx, -1);
|
auto dukRow = DukValue::take_from_stack(ctx, -1);
|
||||||
auto& scriptEngine = GetContext()->GetScriptEngine();
|
duk_push_int(ctx, static_cast<int32_t>(hitResult->Column));
|
||||||
scriptEngine.ExecutePluginCall(Owner, OnClick, { dukRow, dukColumn }, false);
|
auto dukColumn = DukValue::take_from_stack(ctx, -1);
|
||||||
|
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||||
|
scriptEngine.ExecutePluginCall(Owner, OnClick, { dukRow, dukColumn }, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hitResult && hitResult->Row == HEADER_ROW)
|
if (hitResult && hitResult->Row == HEADER_ROW)
|
||||||
@@ -597,11 +600,14 @@ void CustomListView::Paint(rct_window* w, rct_drawpixelinfo* dpi, const rct_scro
|
|||||||
// Columns
|
// Columns
|
||||||
if (Columns.size() == 0)
|
if (Columns.size() == 0)
|
||||||
{
|
{
|
||||||
const auto& text = item.Cells[0];
|
if (item.Cells.size() != 0)
|
||||||
if (!text.empty())
|
|
||||||
{
|
{
|
||||||
ScreenSize cellSize = { std::numeric_limits<int32_t>::max(), LIST_ROW_HEIGHT };
|
const auto& text = item.Cells[0];
|
||||||
PaintCell(dpi, { 0, y }, cellSize, text.c_str(), isHighlighted);
|
if (!text.empty())
|
||||||
|
{
|
||||||
|
ScreenSize cellSize = { std::numeric_limits<int32_t>::max(), LIST_ROW_HEIGHT };
|
||||||
|
PaintCell(dpi, { 0, y }, cellSize, text.c_str(), isHighlighted);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -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_mousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget);
|
||||||
static void window_custom_resize(rct_window* w);
|
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_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_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_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);
|
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.resize = &window_custom_resize;
|
||||||
events.mouse_down = &window_custom_mousedown;
|
events.mouse_down = &window_custom_mousedown;
|
||||||
events.dropdown = &window_custom_dropdown;
|
events.dropdown = &window_custom_dropdown;
|
||||||
|
events.text_input = &window_custom_textinput;
|
||||||
events.update = &window_custom_update;
|
events.update = &window_custom_update;
|
||||||
events.get_scroll_size = &window_custom_scrollgetsize;
|
events.get_scroll_size = &window_custom_scrollgetsize;
|
||||||
events.scroll_mousedown = &window_custom_scrollmousedown;
|
events.scroll_mousedown = &window_custom_scrollmousedown;
|
||||||
@@ -91,6 +93,7 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
std::string Name;
|
std::string Name;
|
||||||
ImageId Image;
|
ImageId Image;
|
||||||
std::string Text;
|
std::string Text;
|
||||||
|
TextAlignment TextAlign;
|
||||||
colour_t Colour;
|
colour_t Colour;
|
||||||
std::string Tooltip;
|
std::string Tooltip;
|
||||||
std::vector<std::string> Items;
|
std::vector<std::string> Items;
|
||||||
@@ -98,9 +101,11 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
std::vector<ListViewColumn> ListViewColumns;
|
std::vector<ListViewColumn> ListViewColumns;
|
||||||
ScrollbarType Scrollbars{};
|
ScrollbarType Scrollbars{};
|
||||||
int32_t SelectedIndex{};
|
int32_t SelectedIndex{};
|
||||||
|
int32_t MaxLength{};
|
||||||
std::optional<RowColumn> SelectedCell;
|
std::optional<RowColumn> SelectedCell;
|
||||||
bool IsChecked{};
|
bool IsChecked{};
|
||||||
bool IsDisabled{};
|
bool IsDisabled{};
|
||||||
|
bool IsVisible{};
|
||||||
bool IsPressed{};
|
bool IsPressed{};
|
||||||
bool HasBorder{};
|
bool HasBorder{};
|
||||||
bool ShowColumnHeaders{};
|
bool ShowColumnHeaders{};
|
||||||
@@ -123,6 +128,7 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
result.Width = desc["width"].as_int();
|
result.Width = desc["width"].as_int();
|
||||||
result.Height = desc["height"].as_int();
|
result.Height = desc["height"].as_int();
|
||||||
result.IsDisabled = AsOrDefault(desc["isDisabled"], false);
|
result.IsDisabled = AsOrDefault(desc["isDisabled"], false);
|
||||||
|
result.IsVisible = AsOrDefault(desc["isVisible"], true);
|
||||||
result.Name = AsOrDefault(desc["name"], "");
|
result.Name = AsOrDefault(desc["name"], "");
|
||||||
result.Tooltip = AsOrDefault(desc["tooltip"], "");
|
result.Tooltip = AsOrDefault(desc["tooltip"], "");
|
||||||
if (result.Type == "button")
|
if (result.Type == "button")
|
||||||
@@ -159,18 +165,29 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
}
|
}
|
||||||
else if (result.Type == "dropdown")
|
else if (result.Type == "dropdown")
|
||||||
{
|
{
|
||||||
auto dukItems = desc["items"].as_array();
|
if (desc["items"].is_array())
|
||||||
for (const auto& dukItem : dukItems)
|
|
||||||
{
|
{
|
||||||
result.Items.push_back(ProcessString(dukItem));
|
auto dukItems = desc["items"].as_array();
|
||||||
|
for (const auto& dukItem : dukItems)
|
||||||
|
{
|
||||||
|
result.Items.push_back(ProcessString(dukItem));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result.SelectedIndex = desc["selectedIndex"].as_int();
|
result.SelectedIndex = AsOrDefault(desc["selectedIndex"], 0);
|
||||||
result.OnChange = desc["onChange"];
|
result.OnChange = desc["onChange"];
|
||||||
}
|
}
|
||||||
else if (result.Type == "groupbox" || result.Type == "label")
|
else if (result.Type == "groupbox")
|
||||||
{
|
{
|
||||||
result.Text = ProcessString(desc["text"]);
|
result.Text = ProcessString(desc["text"]);
|
||||||
}
|
}
|
||||||
|
else if (result.Type == "label")
|
||||||
|
{
|
||||||
|
result.Text = ProcessString(desc["text"]);
|
||||||
|
if (ProcessString(desc["textAlign"]) == "centred")
|
||||||
|
{
|
||||||
|
result.TextAlign = TextAlignment::CENTRE;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (result.Type == "listview")
|
else if (result.Type == "listview")
|
||||||
{
|
{
|
||||||
result.ListViewColumns = FromDuk<std::vector<ListViewColumn>>(desc["columns"]);
|
result.ListViewColumns = FromDuk<std::vector<ListViewColumn>>(desc["columns"]);
|
||||||
@@ -192,6 +209,12 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
result.OnIncrement = desc["onIncrement"];
|
result.OnIncrement = desc["onIncrement"];
|
||||||
result.OnDecrement = desc["onDecrement"];
|
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);
|
result.HasBorder = AsOrDefault(desc["border"], result.HasBorder);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -307,7 +330,11 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
colour_t c = COLOUR_BLACK;
|
colour_t c = COLOUR_BLACK;
|
||||||
if (w.type() == DukValue::Type::NUMBER)
|
if (w.type() == DukValue::Type::NUMBER)
|
||||||
{
|
{
|
||||||
c = static_cast<colour_t>(std::clamp<int32_t>(w.as_int(), COLOUR_BLACK, COLOUR_COUNT - 1));
|
c = std::clamp<int32_t>(BASE_COLOUR(w.as_int()), COLOUR_BLACK, COLOUR_COUNT - 1);
|
||||||
|
if (w.as_int() & COLOUR_FLAG_TRANSLUCENT)
|
||||||
|
{
|
||||||
|
c = TRANSLUCENT(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
});
|
});
|
||||||
@@ -388,7 +415,7 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
{
|
{
|
||||||
auto desc = CustomWindowDesc::FromDukValue(dukDesc);
|
auto desc = CustomWindowDesc::FromDukValue(dukDesc);
|
||||||
|
|
||||||
uint16_t windowFlags = WF_RESIZABLE;
|
uint16_t windowFlags = WF_RESIZABLE | WF_TRANSPARENT;
|
||||||
|
|
||||||
rct_window* window{};
|
rct_window* window{};
|
||||||
if (desc.X && desc.Y)
|
if (desc.X && desc.Y)
|
||||||
@@ -552,6 +579,11 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
InvokeEventHandler(info.Owner, widgetDesc->OnIncrement);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,6 +607,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)
|
static void window_custom_update(rct_window* w)
|
||||||
{
|
{
|
||||||
const auto& info = GetInfo(w);
|
const auto& info = GetInfo(w);
|
||||||
@@ -668,14 +722,28 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
w->widgets[WIDX_CLOSE].right = w->width - 3;
|
w->widgets[WIDX_CLOSE].right = w->width - 3;
|
||||||
w->widgets[WIDX_CONTENT_PANEL].right = w->width - 1;
|
w->widgets[WIDX_CONTENT_PANEL].right = w->width - 1;
|
||||||
w->widgets[WIDX_CONTENT_PANEL].bottom = w->height - 1;
|
w->widgets[WIDX_CONTENT_PANEL].bottom = w->height - 1;
|
||||||
|
w->widgets[WIDX_CLOSE].text = (w->colours[0] & COLOUR_FLAG_TRANSLUCENT) ? STR_CLOSE_X_WHITE : STR_CLOSE_X;
|
||||||
|
|
||||||
|
// Having the content panel visible for transparent windows makes the borders darker than they should be
|
||||||
|
// For now just hide it if there are no tabs and the window is not resizable
|
||||||
|
auto& info = GetInfo(w);
|
||||||
|
auto canResize = (w->flags & WF_RESIZABLE) != 0 && (w->min_width != w->max_width || w->min_height != w->max_height);
|
||||||
|
auto numTabs = info.Desc.Tabs.size();
|
||||||
|
if (canResize || numTabs != 0)
|
||||||
|
{
|
||||||
|
w->widgets[WIDX_CONTENT_PANEL].flags &= ~WIDGET_FLAGS::IS_HIDDEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
w->widgets[WIDX_CONTENT_PANEL].flags |= WIDGET_FLAGS::IS_HIDDEN;
|
||||||
|
}
|
||||||
|
|
||||||
window_custom_set_pressed_tab(w);
|
window_custom_set_pressed_tab(w);
|
||||||
|
|
||||||
const auto& desc = GetInfo(w).Desc;
|
const auto& desc = info.Desc;
|
||||||
auto ft = Formatter::Common();
|
auto ft = Formatter::Common();
|
||||||
ft.Add<const char*>(desc.Title.c_str());
|
ft.Add<const char*>(desc.Title.c_str());
|
||||||
|
|
||||||
auto& info = GetInfo(w);
|
|
||||||
size_t scrollIndex = 0;
|
size_t scrollIndex = 0;
|
||||||
for (auto widget = w->widgets; widget->type != WindowWidgetType::Last; widget++)
|
for (auto widget = w->widgets; widget->type != WindowWidgetType::Last; widget++)
|
||||||
{
|
{
|
||||||
@@ -723,25 +791,6 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void window_custom_paint(rct_window* w, rct_drawpixelinfo* dpi)
|
|
||||||
{
|
|
||||||
WindowDrawWidgets(w, dpi);
|
|
||||||
window_custom_draw_tab_images(w, dpi);
|
|
||||||
if (w->viewport != nullptr)
|
|
||||||
{
|
|
||||||
window_draw_viewport(dpi, w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void window_custom_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex)
|
|
||||||
{
|
|
||||||
const auto& info = GetInfo(w);
|
|
||||||
if (scrollIndex < static_cast<int32_t>(info.ListViews.size()))
|
|
||||||
{
|
|
||||||
info.ListViews[scrollIndex].Paint(w, dpi, &w->scrolls[scrollIndex]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::optional<rct_widgetindex> GetViewportWidgetIndex(rct_window* w)
|
static std::optional<rct_widgetindex> GetViewportWidgetIndex(rct_window* w)
|
||||||
{
|
{
|
||||||
rct_widgetindex widgetIndex = 0;
|
rct_widgetindex widgetIndex = 0;
|
||||||
@@ -756,6 +805,29 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void window_custom_paint(rct_window* w, rct_drawpixelinfo* dpi)
|
||||||
|
{
|
||||||
|
WindowDrawWidgets(w, dpi);
|
||||||
|
window_custom_draw_tab_images(w, dpi);
|
||||||
|
if (w->viewport != nullptr)
|
||||||
|
{
|
||||||
|
auto widgetIndex = GetViewportWidgetIndex(w);
|
||||||
|
if (WidgetIsVisible(w, widgetIndex.value_or(false)))
|
||||||
|
{
|
||||||
|
window_draw_viewport(dpi, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void window_custom_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex)
|
||||||
|
{
|
||||||
|
const auto& info = GetInfo(w);
|
||||||
|
if (scrollIndex < static_cast<int32_t>(info.ListViews.size()))
|
||||||
|
{
|
||||||
|
info.ListViews[scrollIndex].Paint(w, dpi, &w->scrolls[scrollIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void window_custom_update_viewport(rct_window* w)
|
static void window_custom_update_viewport(rct_window* w)
|
||||||
{
|
{
|
||||||
auto viewportWidgetIndex = GetViewportWidgetIndex(w);
|
auto viewportWidgetIndex = GetViewportWidgetIndex(w);
|
||||||
@@ -833,6 +905,8 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
widget.flags |= WIDGET_FLAGS::IS_ENABLED;
|
widget.flags |= WIDGET_FLAGS::IS_ENABLED;
|
||||||
if (desc.IsDisabled)
|
if (desc.IsDisabled)
|
||||||
widget.flags |= WIDGET_FLAGS::IS_DISABLED;
|
widget.flags |= WIDGET_FLAGS::IS_DISABLED;
|
||||||
|
if (!desc.IsVisible)
|
||||||
|
widget.flags |= WIDGET_FLAGS::IS_HIDDEN;
|
||||||
|
|
||||||
if (desc.Type == "button")
|
if (desc.Type == "button")
|
||||||
{
|
{
|
||||||
@@ -911,6 +985,10 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
widget.type = WindowWidgetType::Label;
|
widget.type = WindowWidgetType::Label;
|
||||||
widget.string = const_cast<utf8*>(desc.Text.c_str());
|
widget.string = const_cast<utf8*>(desc.Text.c_str());
|
||||||
widget.flags |= WIDGET_FLAGS::TEXT_IS_STRING;
|
widget.flags |= WIDGET_FLAGS::TEXT_IS_STRING;
|
||||||
|
if (desc.TextAlign == TextAlignment::CENTRE)
|
||||||
|
{
|
||||||
|
widget.type = WindowWidgetType::LabelCentred;
|
||||||
|
}
|
||||||
widgetList.push_back(widget);
|
widgetList.push_back(widget);
|
||||||
}
|
}
|
||||||
else if (desc.Type == "listview")
|
else if (desc.Type == "listview")
|
||||||
@@ -953,6 +1031,13 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
widget.text = STR_NUMERIC_UP;
|
widget.text = STR_NUMERIC_UP;
|
||||||
widgetList.push_back(widget);
|
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")
|
else if (desc.Type == "viewport")
|
||||||
{
|
{
|
||||||
widget.type = WindowWidgetType::Viewport;
|
widget.type = WindowWidgetType::Viewport;
|
||||||
@@ -1319,6 +1404,33 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
return nullptr;
|
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
|
} // namespace OpenRCT2::Ui::Windows
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
std::string GetWidgetName(rct_window* w, rct_widgetindex widgetIndex);
|
std::string GetWidgetName(rct_window* w, rct_widgetindex widgetIndex);
|
||||||
void SetWidgetName(rct_window* w, rct_widgetindex widgetIndex, std::string_view name);
|
void SetWidgetName(rct_window* w, rct_widgetindex widgetIndex, std::string_view name);
|
||||||
CustomListView* GetCustomListView(rct_window* w, rct_widgetindex widgetIndex);
|
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
|
} // namespace OpenRCT2::Ui::Windows
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ namespace OpenRCT2::Scripting
|
|||||||
auto plugin = _scriptEngine.GetExecInfo().GetCurrentPlugin();
|
auto plugin = _scriptEngine.GetExecInfo().GetCurrentPlugin();
|
||||||
auto title = desc["title"].as_string();
|
auto title = desc["title"].as_string();
|
||||||
auto description = desc["description"].as_string();
|
auto description = desc["description"].as_string();
|
||||||
auto initialValue = AsOrDefault(desc["maxLength"], "");
|
auto initialValue = AsOrDefault(desc["initialValue"], "");
|
||||||
auto maxLength = AsOrDefault(desc["maxLength"], std::numeric_limits<int32_t>::max());
|
auto maxLength = AsOrDefault(desc["maxLength"], std::numeric_limits<int32_t>::max());
|
||||||
auto callback = desc["callback"];
|
auto callback = desc["callback"];
|
||||||
window_text_input_open(
|
window_text_input_open(
|
||||||
|
|||||||
@@ -318,6 +318,39 @@ namespace OpenRCT2::Scripting
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isVisible_get() const
|
||||||
|
{
|
||||||
|
auto w = GetWindow();
|
||||||
|
if (w != nullptr)
|
||||||
|
{
|
||||||
|
return WidgetIsVisible(w, _widgetIndex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void isVisible_set(bool value)
|
||||||
|
{
|
||||||
|
auto w = GetWindow();
|
||||||
|
if (w != nullptr)
|
||||||
|
{
|
||||||
|
WidgetSetVisible(w, _widgetIndex, value);
|
||||||
|
|
||||||
|
auto widget = GetWidget();
|
||||||
|
if (widget != nullptr)
|
||||||
|
{
|
||||||
|
if (widget->type == WindowWidgetType::DropdownMenu)
|
||||||
|
{
|
||||||
|
WidgetSetVisible(w, _widgetIndex + 1, value);
|
||||||
|
}
|
||||||
|
else if (widget->type == WindowWidgetType::Spinner)
|
||||||
|
{
|
||||||
|
WidgetSetVisible(w, _widgetIndex + 1, value);
|
||||||
|
WidgetSetVisible(w, _widgetIndex + 2, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
std::string text_get() const
|
std::string text_get() const
|
||||||
{
|
{
|
||||||
if (IsCustomWindow())
|
if (IsCustomWindow())
|
||||||
@@ -330,6 +363,7 @@ namespace OpenRCT2::Scripting
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_set(std::string value)
|
void text_set(std::string value)
|
||||||
{
|
{
|
||||||
auto w = GetWindow();
|
auto w = GetWindow();
|
||||||
@@ -339,20 +373,6 @@ namespace OpenRCT2::Scripting
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ScViewport> viewport_get() const
|
|
||||||
{
|
|
||||||
auto w = GetWindow();
|
|
||||||
if (w != nullptr && IsCustomWindow())
|
|
||||||
{
|
|
||||||
auto widget = GetWidget();
|
|
||||||
if (widget != nullptr && widget->type == WindowWidgetType::Viewport)
|
|
||||||
{
|
|
||||||
return std::make_shared<ScViewport>(w->classification, w->number);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Register(duk_context* ctx)
|
static void Register(duk_context* ctx)
|
||||||
{
|
{
|
||||||
@@ -364,10 +384,7 @@ namespace OpenRCT2::Scripting
|
|||||||
dukglue_register_property(ctx, &ScWidget::width_get, &ScWidget::width_set, "width");
|
dukglue_register_property(ctx, &ScWidget::width_get, &ScWidget::width_set, "width");
|
||||||
dukglue_register_property(ctx, &ScWidget::height_get, &ScWidget::height_set, "height");
|
dukglue_register_property(ctx, &ScWidget::height_get, &ScWidget::height_set, "height");
|
||||||
dukglue_register_property(ctx, &ScWidget::isDisabled_get, &ScWidget::isDisabled_set, "isDisabled");
|
dukglue_register_property(ctx, &ScWidget::isDisabled_get, &ScWidget::isDisabled_set, "isDisabled");
|
||||||
|
dukglue_register_property(ctx, &ScWidget::isVisible_get, &ScWidget::isVisible_set, "isVisible");
|
||||||
// No so common
|
|
||||||
dukglue_register_property(ctx, &ScWidget::text_get, &ScWidget::text_set, "text");
|
|
||||||
dukglue_register_property(ctx, &ScWidget::viewport_get, nullptr, "viewport");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -608,6 +625,63 @@ namespace OpenRCT2::Scripting
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ScGroupBoxWidget : public ScWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScGroupBoxWidget(rct_windowclass c, rct_windownumber n, rct_widgetindex widgetIndex)
|
||||||
|
: ScWidget(c, n, widgetIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Register(duk_context* ctx)
|
||||||
|
{
|
||||||
|
dukglue_set_base_class<ScWidget, ScGroupBoxWidget>(ctx);
|
||||||
|
dukglue_register_property(ctx, &ScGroupBoxWidget::text_get, &ScGroupBoxWidget::text_set, "text");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScLabelWidget : public ScWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScLabelWidget(rct_windowclass c, rct_windownumber n, rct_widgetindex widgetIndex)
|
||||||
|
: ScWidget(c, n, widgetIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Register(duk_context* ctx)
|
||||||
|
{
|
||||||
|
dukglue_set_base_class<ScWidget, ScLabelWidget>(ctx);
|
||||||
|
dukglue_register_property(ctx, &ScLabelWidget::text_get, &ScLabelWidget::text_set, "text");
|
||||||
|
dukglue_register_property(ctx, &ScLabelWidget::textAlign_get, &ScLabelWidget::textAlign_set, "textAlign");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string textAlign_get() const
|
||||||
|
{
|
||||||
|
auto* widget = GetWidget();
|
||||||
|
if (widget != nullptr)
|
||||||
|
{
|
||||||
|
if (widget->type == WindowWidgetType::LabelCentred)
|
||||||
|
{
|
||||||
|
return "centred";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "left";
|
||||||
|
}
|
||||||
|
|
||||||
|
void textAlign_set(const std::string& value)
|
||||||
|
{
|
||||||
|
auto* widget = GetWidget();
|
||||||
|
if (widget != nullptr)
|
||||||
|
{
|
||||||
|
if (value == "centred")
|
||||||
|
widget->type = WindowWidgetType::LabelCentred;
|
||||||
|
else
|
||||||
|
widget->type = WindowWidgetType::Label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class ScListViewWidget : public ScWidget
|
class ScListViewWidget : public ScWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -799,6 +873,86 @@ namespace OpenRCT2::Scripting
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ScSpinnerWidget : public ScWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScSpinnerWidget(rct_windowclass c, rct_windownumber n, rct_widgetindex widgetIndex)
|
||||||
|
: ScWidget(c, n, widgetIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Register(duk_context* ctx)
|
||||||
|
{
|
||||||
|
dukglue_set_base_class<ScWidget, ScSpinnerWidget>(ctx);
|
||||||
|
dukglue_register_property(ctx, &ScSpinnerWidget::text_get, &ScSpinnerWidget::text_set, "text");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScViewportWidget : public ScWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScViewportWidget(rct_windowclass c, rct_windownumber n, rct_widgetindex widgetIndex)
|
||||||
|
: ScWidget(c, n, widgetIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Register(duk_context* ctx)
|
||||||
|
{
|
||||||
|
dukglue_set_base_class<ScWidget, ScViewportWidget>(ctx);
|
||||||
|
dukglue_register_property(ctx, &ScViewportWidget::viewport_get, nullptr, "viewport");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<ScViewport> viewport_get() const
|
||||||
|
{
|
||||||
|
auto w = GetWindow();
|
||||||
|
if (w != nullptr && IsCustomWindow())
|
||||||
|
{
|
||||||
|
auto widget = GetWidget();
|
||||||
|
if (widget != nullptr && widget->type == WindowWidgetType::Viewport)
|
||||||
|
{
|
||||||
|
return std::make_shared<ScViewport>(w->classification, w->number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
inline DukValue ScWidget::ToDukValue(duk_context* ctx, rct_window* w, rct_widgetindex widgetIndex)
|
inline DukValue ScWidget::ToDukValue(duk_context* ctx, rct_window* w, rct_widgetindex widgetIndex)
|
||||||
{
|
{
|
||||||
const auto& widget = w->widgets[widgetIndex];
|
const auto& widget = w->widgets[widgetIndex];
|
||||||
@@ -816,8 +970,19 @@ namespace OpenRCT2::Scripting
|
|||||||
return GetObjectAsDukValue(ctx, std::make_shared<ScColourPickerWidget>(c, n, widgetIndex));
|
return GetObjectAsDukValue(ctx, std::make_shared<ScColourPickerWidget>(c, n, widgetIndex));
|
||||||
case WindowWidgetType::DropdownMenu:
|
case WindowWidgetType::DropdownMenu:
|
||||||
return GetObjectAsDukValue(ctx, std::make_shared<ScDropdownWidget>(c, n, widgetIndex));
|
return GetObjectAsDukValue(ctx, std::make_shared<ScDropdownWidget>(c, n, widgetIndex));
|
||||||
|
case WindowWidgetType::Groupbox:
|
||||||
|
return GetObjectAsDukValue(ctx, std::make_shared<ScGroupBoxWidget>(c, n, widgetIndex));
|
||||||
|
case WindowWidgetType::Label:
|
||||||
|
case WindowWidgetType::LabelCentred:
|
||||||
|
return GetObjectAsDukValue(ctx, std::make_shared<ScLabelWidget>(c, n, widgetIndex));
|
||||||
case WindowWidgetType::Scroll:
|
case WindowWidgetType::Scroll:
|
||||||
return GetObjectAsDukValue(ctx, std::make_shared<ScListViewWidget>(c, n, widgetIndex));
|
return GetObjectAsDukValue(ctx, std::make_shared<ScListViewWidget>(c, n, widgetIndex));
|
||||||
|
case WindowWidgetType::Spinner:
|
||||||
|
return GetObjectAsDukValue(ctx, std::make_shared<ScSpinnerWidget>(c, n, widgetIndex));
|
||||||
|
case WindowWidgetType::TextBox:
|
||||||
|
return GetObjectAsDukValue(ctx, std::make_shared<ScTextBoxWidget>(c, n, widgetIndex));
|
||||||
|
case WindowWidgetType::Viewport:
|
||||||
|
return GetObjectAsDukValue(ctx, std::make_shared<ScViewportWidget>(c, n, widgetIndex));
|
||||||
default:
|
default:
|
||||||
return GetObjectAsDukValue(ctx, std::make_shared<ScWidget>(c, n, widgetIndex));
|
return GetObjectAsDukValue(ctx, std::make_shared<ScWidget>(c, n, widgetIndex));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,8 +189,12 @@ namespace OpenRCT2::Scripting
|
|||||||
}
|
}
|
||||||
bool isSticky_get() const
|
bool isSticky_get() const
|
||||||
{
|
{
|
||||||
auto flags = GetWindow()->flags;
|
auto w = GetWindow();
|
||||||
return (flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)) != 0;
|
if (w != nullptr)
|
||||||
|
{
|
||||||
|
return (w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)) != 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<DukValue> widgets_get() const
|
std::vector<DukValue> widgets_get() const
|
||||||
@@ -232,8 +236,16 @@ namespace OpenRCT2::Scripting
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < std::size(w->colours); i++)
|
for (size_t i = 0; i < std::size(w->colours); i++)
|
||||||
{
|
{
|
||||||
w->colours[i] = i < colours.size() ? std::clamp<int32_t>(colours[i], COLOUR_BLACK, COLOUR_COUNT - 1)
|
int32_t c = COLOUR_BLACK;
|
||||||
: COLOUR_BLACK;
|
if (i < colours.size())
|
||||||
|
{
|
||||||
|
c = std::clamp<int32_t>(BASE_COLOUR(colours[i]), COLOUR_BLACK, COLOUR_COUNT - 1);
|
||||||
|
if (colours[i] & COLOUR_FLAG_TRANSLUCENT)
|
||||||
|
{
|
||||||
|
c = TRANSLUCENT(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w->colours[i] = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,12 +31,18 @@ void UiScriptExtensions::Extend(ScriptEngine& scriptEngine)
|
|||||||
ScTool::Register(ctx);
|
ScTool::Register(ctx);
|
||||||
ScUi::Register(ctx);
|
ScUi::Register(ctx);
|
||||||
ScViewport::Register(ctx);
|
ScViewport::Register(ctx);
|
||||||
|
|
||||||
ScWidget::Register(ctx);
|
ScWidget::Register(ctx);
|
||||||
ScButtonWidget::Register(ctx);
|
ScButtonWidget::Register(ctx);
|
||||||
ScColourPickerWidget::Register(ctx);
|
ScColourPickerWidget::Register(ctx);
|
||||||
ScCheckBoxWidget::Register(ctx);
|
ScCheckBoxWidget::Register(ctx);
|
||||||
ScDropdownWidget::Register(ctx);
|
ScDropdownWidget::Register(ctx);
|
||||||
|
ScGroupBoxWidget::Register(ctx);
|
||||||
|
ScLabelWidget::Register(ctx);
|
||||||
ScListViewWidget::Register(ctx);
|
ScListViewWidget::Register(ctx);
|
||||||
|
ScSpinnerWidget::Register(ctx);
|
||||||
|
ScTextBoxWidget::Register(ctx);
|
||||||
|
ScViewportWidget::Register(ctx);
|
||||||
ScWindow::Register(ctx);
|
ScWindow::Register(ctx);
|
||||||
|
|
||||||
InitialiseCustomMenuItems(scriptEngine);
|
InitialiseCustomMenuItems(scriptEngine);
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ void WidgetDraw(rct_drawpixelinfo* dpi, rct_window* w, rct_widgetindex widgetInd
|
|||||||
|
|
||||||
bool WidgetIsEnabled(rct_window* w, rct_widgetindex widgetIndex);
|
bool WidgetIsEnabled(rct_window* w, rct_widgetindex widgetIndex);
|
||||||
bool WidgetIsDisabled(rct_window* w, rct_widgetindex widgetIndex);
|
bool WidgetIsDisabled(rct_window* w, rct_widgetindex widgetIndex);
|
||||||
|
bool WidgetIsVisible(rct_window* w, rct_widgetindex widgetIndex);
|
||||||
bool WidgetIsPressed(rct_window* w, rct_widgetindex widgetIndex);
|
bool WidgetIsPressed(rct_window* w, rct_widgetindex widgetIndex);
|
||||||
bool WidgetIsHighlighted(rct_window* w, rct_widgetindex widgetIndex);
|
bool WidgetIsHighlighted(rct_window* w, rct_widgetindex widgetIndex);
|
||||||
bool WidgetIsActiveTool(rct_window* w, rct_widgetindex widgetIndex);
|
bool WidgetIsActiveTool(rct_window* w, rct_widgetindex widgetIndex);
|
||||||
@@ -146,6 +147,7 @@ void WidgetScrollGetPart(
|
|||||||
|
|
||||||
void WidgetSetEnabled(rct_window* w, rct_widgetindex widgetIndex, bool enabled);
|
void WidgetSetEnabled(rct_window* w, rct_widgetindex widgetIndex, bool enabled);
|
||||||
void WidgetSetDisabled(rct_window* w, rct_widgetindex widgetIndex, bool value);
|
void WidgetSetDisabled(rct_window* w, rct_widgetindex widgetIndex, bool value);
|
||||||
|
void WidgetSetVisible(rct_window* w, rct_widgetindex widgetIndex, bool value);
|
||||||
void WidgetSetCheckboxValue(rct_window* w, rct_widgetindex widgetIndex, int32_t value);
|
void WidgetSetCheckboxValue(rct_window* w, rct_widgetindex widgetIndex, int32_t value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ rct_widgetindex window_find_widget_from_point(rct_window* w, const ScreenCoordsX
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (widget->type != WindowWidgetType::Empty)
|
else if (widget->type != WindowWidgetType::Empty && widget->IsVisible())
|
||||||
{
|
{
|
||||||
if (screenCoords.x >= w->windowPos.x + widget->left && screenCoords.x <= w->windowPos.x + widget->right
|
if (screenCoords.x >= w->windowPos.x + widget->left && screenCoords.x <= w->windowPos.x + widget->right
|
||||||
&& screenCoords.y >= w->windowPos.y + widget->top && screenCoords.y <= w->windowPos.y + widget->bottom)
|
&& screenCoords.y >= w->windowPos.y + widget->top && screenCoords.y <= w->windowPos.y + widget->bottom)
|
||||||
@@ -2004,12 +2004,18 @@ void window_cancel_textbox()
|
|||||||
if (gUsingWidgetTextBox)
|
if (gUsingWidgetTextBox)
|
||||||
{
|
{
|
||||||
rct_window* w = window_find_by_number(gCurrentTextBox.window.classification, gCurrentTextBox.window.number);
|
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.classification = WC_NULL;
|
||||||
gCurrentTextBox.window.number = 0;
|
gCurrentTextBox.window.number = 0;
|
||||||
context_stop_text_input();
|
context_stop_text_input();
|
||||||
gUsingWidgetTextBox = false;
|
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);
|
gCurrentTextBox.widget_index = static_cast<uint16_t>(WindowWidgetType::Last);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ namespace WIDGET_FLAGS
|
|||||||
const WidgetFlags IS_PRESSED = 1 << 2;
|
const WidgetFlags IS_PRESSED = 1 << 2;
|
||||||
const WidgetFlags IS_DISABLED = 1 << 3;
|
const WidgetFlags IS_DISABLED = 1 << 3;
|
||||||
const WidgetFlags TOOLTIP_IS_STRING = 1 << 4;
|
const WidgetFlags TOOLTIP_IS_STRING = 1 << 4;
|
||||||
|
const WidgetFlags IS_HIDDEN = 1 << 5;
|
||||||
} // namespace WIDGET_FLAGS
|
} // namespace WIDGET_FLAGS
|
||||||
|
|
||||||
enum class WindowWidgetType : uint8_t;
|
enum class WindowWidgetType : uint8_t;
|
||||||
@@ -132,6 +133,11 @@ struct rct_widget
|
|||||||
else
|
else
|
||||||
return top - 1;
|
return top - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsVisible() const
|
||||||
|
{
|
||||||
|
return !(flags & WIDGET_FLAGS::IS_HIDDEN);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
using namespace OpenRCT2;
|
using namespace OpenRCT2;
|
||||||
using namespace OpenRCT2::Scripting;
|
using namespace OpenRCT2::Scripting;
|
||||||
|
|
||||||
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 18;
|
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 19;
|
||||||
|
|
||||||
struct ExpressionStringifier final
|
struct ExpressionStringifier final
|
||||||
{
|
{
|
||||||
@@ -718,8 +718,15 @@ DukValue ScriptEngine::ExecutePluginCall(
|
|||||||
|
|
||||||
void ScriptEngine::LogPluginInfo(const std::shared_ptr<Plugin>& plugin, std::string_view message)
|
void ScriptEngine::LogPluginInfo(const std::shared_ptr<Plugin>& plugin, std::string_view message)
|
||||||
{
|
{
|
||||||
const auto& pluginName = plugin->GetMetadata().Name;
|
if (plugin == nullptr)
|
||||||
_console.WriteLine("[" + pluginName + "] " + std::string(message));
|
{
|
||||||
|
_console.WriteLine(std::string(message));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto& pluginName = plugin->GetMetadata().Name;
|
||||||
|
_console.WriteLine("[" + pluginName + "] " + std::string(message));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::AddNetworkPlugin(std::string_view code)
|
void ScriptEngine::AddNetworkPlugin(std::string_view code)
|
||||||
|
|||||||
Reference in New Issue
Block a user