mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 19:13:07 +01:00
Add API for toolbox menu items
This commit is contained in:
8
distribution/openrct2.d.ts
vendored
8
distribution/openrct2.d.ts
vendored
@@ -2124,6 +2124,14 @@ declare global {
|
||||
|
||||
registerMenuItem(text: string, callback: () => void): void;
|
||||
|
||||
/**
|
||||
* Registers a new item in the toolbox menu on the title screen.
|
||||
* Only available to intransient plugins.
|
||||
* @param text The menu item text.
|
||||
* @param callback The function to call when the menu item is clicked.
|
||||
*/
|
||||
registerToolboxMenuItem(text: string, callback: () => void): void;
|
||||
|
||||
registerShortcut(desc: ShortcutDesc): void;
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +279,6 @@ namespace OpenRCT2::Scripting
|
||||
duk_error(scriptEngine.GetContext(), DUK_ERR_ERROR, "Invalid parameters.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenRCT2::Scripting
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,15 +23,24 @@ enum class CursorID : uint8_t;
|
||||
|
||||
namespace OpenRCT2::Scripting
|
||||
{
|
||||
enum class CustomToolbarMenuItemKind
|
||||
{
|
||||
Standard,
|
||||
Toolbox,
|
||||
};
|
||||
|
||||
class CustomToolbarMenuItem
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<Plugin> Owner;
|
||||
CustomToolbarMenuItemKind Kind;
|
||||
std::string Text;
|
||||
DukValue Callback;
|
||||
|
||||
CustomToolbarMenuItem(std::shared_ptr<Plugin> owner, const std::string& text, DukValue callback)
|
||||
CustomToolbarMenuItem(
|
||||
std::shared_ptr<Plugin> owner, CustomToolbarMenuItemKind kind, const std::string& text, DukValue callback)
|
||||
: Owner(owner)
|
||||
, Kind(kind)
|
||||
, Text(text)
|
||||
, Callback(callback)
|
||||
{
|
||||
|
||||
@@ -313,7 +313,21 @@ namespace OpenRCT2::Scripting
|
||||
{
|
||||
auto& execInfo = _scriptEngine.GetExecInfo();
|
||||
auto owner = execInfo.GetCurrentPlugin();
|
||||
CustomMenuItems.emplace_back(owner, text, callback);
|
||||
CustomMenuItems.emplace_back(owner, CustomToolbarMenuItemKind::Standard, text, callback);
|
||||
}
|
||||
|
||||
void registerToolboxMenuItem(const std::string& text, DukValue callback)
|
||||
{
|
||||
auto& execInfo = _scriptEngine.GetExecInfo();
|
||||
auto owner = execInfo.GetCurrentPlugin();
|
||||
if (owner->GetMetadata().Type == PluginType::Intransient)
|
||||
{
|
||||
CustomMenuItems.emplace_back(owner, CustomToolbarMenuItemKind::Toolbox, text, callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_error(_scriptEngine.GetContext(), DUK_ERR_ERROR, "Plugin must be intransient.");
|
||||
}
|
||||
}
|
||||
|
||||
void registerShortcut(DukValue desc)
|
||||
@@ -364,6 +378,7 @@ namespace OpenRCT2::Scripting
|
||||
dukglue_register_method(ctx, &ScUi::showScenarioSelect, "showScenarioSelect");
|
||||
dukglue_register_method(ctx, &ScUi::activateTool, "activateTool");
|
||||
dukglue_register_method(ctx, &ScUi::registerMenuItem, "registerMenuItem");
|
||||
dukglue_register_method(ctx, &ScUi::registerToolboxMenuItem, "registerToolboxMenuItem");
|
||||
dukglue_register_method(ctx, &ScUi::registerShortcut, "registerShortcut");
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <openrct2-ui/interface/Dropdown.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/scripting/CustomMenu.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/Editor.h>
|
||||
@@ -31,6 +32,16 @@ enum {
|
||||
WIDX_NEW_VERSION,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DDIDX_SCENARIO_EDITOR,
|
||||
DDIDX_CONVERT_SAVED_GAME,
|
||||
DDIDX_TRACK_DESIGNER,
|
||||
DDIDX_TRACK_MANAGER,
|
||||
DDIDX_OPEN_CONTENT_FOLDER,
|
||||
DDIDX_CUSTOM_BEGIN = 6,
|
||||
};
|
||||
|
||||
static ScreenRect _filterRect;
|
||||
static constexpr ScreenSize MenuButtonDims = { 82, 82 };
|
||||
static constexpr ScreenSize UpdateButtonDims = { MenuButtonDims.width * 4, 28 };
|
||||
@@ -167,36 +178,89 @@ static void WindowTitleMenuMousedown(rct_window* w, rct_widgetindex widgetIndex,
|
||||
{
|
||||
if (widgetIndex == WIDX_GAME_TOOLS)
|
||||
{
|
||||
gDropdownItems[0].Format = STR_SCENARIO_EDITOR;
|
||||
gDropdownItems[1].Format = STR_CONVERT_SAVED_GAME_TO_SCENARIO;
|
||||
gDropdownItems[2].Format = STR_ROLLER_COASTER_DESIGNER;
|
||||
gDropdownItems[3].Format = STR_TRACK_DESIGNS_MANAGER;
|
||||
gDropdownItems[4].Format = STR_OPEN_USER_CONTENT_FOLDER;
|
||||
int32_t i = 0;
|
||||
gDropdownItems[i++].Format = STR_SCENARIO_EDITOR;
|
||||
gDropdownItems[i++].Format = STR_CONVERT_SAVED_GAME_TO_SCENARIO;
|
||||
gDropdownItems[i++].Format = STR_ROLLER_COASTER_DESIGNER;
|
||||
gDropdownItems[i++].Format = STR_TRACK_DESIGNS_MANAGER;
|
||||
gDropdownItems[i++].Format = STR_OPEN_USER_CONTENT_FOLDER;
|
||||
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
auto hasCustomItems = false;
|
||||
const auto& customMenuItems = OpenRCT2::Scripting::CustomMenuItems;
|
||||
if (!customMenuItems.empty())
|
||||
{
|
||||
for (const auto& item : customMenuItems)
|
||||
{
|
||||
if (item.Kind == OpenRCT2::Scripting::CustomToolbarMenuItemKind::Toolbox)
|
||||
{
|
||||
// Add seperator
|
||||
if (!hasCustomItems)
|
||||
{
|
||||
hasCustomItems = true;
|
||||
gDropdownItems[i++].Format = STR_EMPTY;
|
||||
}
|
||||
|
||||
gDropdownItems[i].Format = STR_STRING;
|
||||
auto sz = item.Text.c_str();
|
||||
std::memcpy(&gDropdownItems[i].Args, &sz, sizeof(const char*));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t yOffset = 0;
|
||||
if (i > 5)
|
||||
{
|
||||
yOffset = -(widget->height() + 5 + (i * 12));
|
||||
}
|
||||
|
||||
WindowDropdownShowText(
|
||||
{ w->windowPos.x + widget->left, w->windowPos.y + widget->top }, widget->height() + 1, TRANSLUCENT(w->colours[0]),
|
||||
Dropdown::Flag::StayOpen, 5);
|
||||
{ w->windowPos.x + widget->left, w->windowPos.y + widget->top + yOffset }, widget->height() + 1,
|
||||
TRANSLUCENT(w->colours[0]), Dropdown::Flag::StayOpen, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void InvokeCustomToolboxMenuItem(size_t index)
|
||||
{
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
const auto& customMenuItems = OpenRCT2::Scripting::CustomMenuItems;
|
||||
size_t i = 0;
|
||||
for (const auto& item : customMenuItems)
|
||||
{
|
||||
if (item.Kind == OpenRCT2::Scripting::CustomToolbarMenuItemKind::Toolbox)
|
||||
{
|
||||
if (i == index)
|
||||
{
|
||||
item.Invoke();
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void WindowTitleMenuDropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex)
|
||||
{
|
||||
if (widgetIndex == WIDX_GAME_TOOLS)
|
||||
{
|
||||
switch (dropdownIndex)
|
||||
{
|
||||
case 0:
|
||||
case DDIDX_SCENARIO_EDITOR:
|
||||
Editor::Load();
|
||||
break;
|
||||
case 1:
|
||||
case DDIDX_CONVERT_SAVED_GAME:
|
||||
Editor::ConvertSaveToScenario();
|
||||
break;
|
||||
case 2:
|
||||
case DDIDX_TRACK_DESIGNER:
|
||||
Editor::LoadTrackDesigner();
|
||||
break;
|
||||
case 3:
|
||||
case DDIDX_TRACK_MANAGER:
|
||||
Editor::LoadTrackManager();
|
||||
break;
|
||||
case 4:
|
||||
case DDIDX_OPEN_CONTENT_FOLDER:
|
||||
{
|
||||
auto context = OpenRCT2::GetContext();
|
||||
auto env = context->GetPlatformEnvironment();
|
||||
@@ -204,6 +268,9 @@ static void WindowTitleMenuDropdown(rct_window* w, rct_widgetindex widgetIndex,
|
||||
uiContext->OpenFolder(env->GetDirectoryPath(OpenRCT2::DIRBASE::USER));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
InvokeCustomToolboxMenuItem(dropdownIndex - DDIDX_CUSTOM_BEGIN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3315,10 +3315,13 @@ static void TopToolbarInitMapMenu(rct_window* w, rct_widget* widget)
|
||||
gDropdownItems[i++].Format = STR_EMPTY;
|
||||
for (const auto& item : customMenuItems)
|
||||
{
|
||||
gDropdownItems[i].Format = STR_STRING;
|
||||
auto sz = item.Text.c_str();
|
||||
std::memcpy(&gDropdownItems[i].Args, &sz, sizeof(const char*));
|
||||
i++;
|
||||
if (item.Kind == OpenRCT2::Scripting::CustomToolbarMenuItemKind::Standard)
|
||||
{
|
||||
gDropdownItems[i].Format = STR_STRING;
|
||||
auto sz = item.Text.c_str();
|
||||
std::memcpy(&gDropdownItems[i].Args, &sz, sizeof(const char*));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -3356,9 +3359,18 @@ static void TopToolbarMapMenuDropdown(int16_t dropdownIndex)
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
const auto& customMenuItems = OpenRCT2::Scripting::CustomMenuItems;
|
||||
auto customIndex = static_cast<size_t>(dropdownIndex - customStartIndex);
|
||||
if (customMenuItems.size() > customIndex)
|
||||
size_t i = 0;
|
||||
for (const auto& item : customMenuItems)
|
||||
{
|
||||
customMenuItems[customIndex].Invoke();
|
||||
if (item.Kind == OpenRCT2::Scripting::CustomToolbarMenuItemKind::Standard)
|
||||
{
|
||||
if (i == customIndex)
|
||||
{
|
||||
item.Invoke();
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user