Implement Widget API

This commit is contained in:
Ted John 2020-02-14 23:36:24 +00:00
parent 7274e45c93
commit b1cf6fcf63
5 changed files with 293 additions and 0 deletions

View File

@ -234,6 +234,11 @@ namespace OpenRCT2::Ui::Windows
}
return nullptr;
}
CustomWidgetDesc* GetCustomWidgetDesc(size_t widgetIndex)
{
return const_cast<CustomWidgetDesc*>(std::as_const(*this).GetCustomWidgetDesc(widgetIndex));
}
};
static rct_windownumber _nextWindowNumber;
@ -529,4 +534,19 @@ namespace OpenRCT2::Ui::Windows
}
}
}
void UpdateWidgetText(rct_window* w, rct_widgetindex widgetIndex, const std::string& value)
{
if (w->custom_info != nullptr)
{
auto &customInfo = GetInfo(w);
auto customWidgetInfo = customInfo.GetCustomWidgetDesc(widgetIndex);
if (customWidgetInfo != nullptr)
{
customWidgetInfo->Text = CustomWidgetDesc::ProcessString(value);
w->widgets[widgetIndex].string = customWidgetInfo->Text.data();
}
}
}
} // namespace OpenRCT2::Ui::Windows

View File

@ -0,0 +1,17 @@
/*****************************************************************************
* Copyright (c) 2014-2018 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "../interface/Window.h"
#include <string>
namespace OpenRCT2::Ui::Windows
{
void UpdateWidgetText(rct_window* w, rct_widgetindex widget, const std::string& value);
}

View File

@ -0,0 +1,235 @@
/*****************************************************************************
* Copyright (c) 2014-2018 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include "../interface/Widget.h"
#include "../interface/Window.h"
#include "CustomWindow.h"
#include <memory>
#include <openrct2/Context.h>
#include <openrct2/common.h>
#include <openrct2/scripting/Duktape.hpp>
#include <openrct2/scripting/ScriptEngine.h>
namespace OpenRCT2::Scripting
{
class ScWidget
{
private:
rct_windowclass _class{};
rct_windownumber _number{};
rct_widgetindex _widgetIndex{};
public:
ScWidget(rct_windowclass c, rct_windownumber n, rct_widgetindex widgetIndex)
: _class(c)
, _number(n)
, _widgetIndex(widgetIndex)
{
}
private:
std::string type_get()
{
auto widget = GetWidget();
if (widget != nullptr)
{
switch (widget->type)
{
case WWT_FRAME:
return "frame";
case WWT_RESIZE:
return "resize";
case WWT_IMGBTN:
case WWT_COLOURBTN:
case WWT_TRNBTN:
case WWT_FLATBTN:
case WWT_BUTTON:
case WWT_CLOSEBOX:
return "button";
case WWT_TAB:
return "tab";
case WWT_LABEL_CENTRED:
case WWT_LABEL:
return "label";
case WWT_TABLE_HEADER:
return "table_header";
case WWT_SPINNER:
return "spinner";
case WWT_DROPDOWN:
return "dropdown";
case WWT_VIEWPORT:
return "viewport";
case WWT_GROUPBOX:
return "groupbox";
case WWT_CAPTION:
return "caption";
case WWT_SCROLL:
return "scroll_view";
case WWT_CHECKBOX:
return "checkbox";
case WWT_TEXT_BOX:
return "textbox";
}
}
return "unknown";
}
int32_t x_get()
{
auto widget = GetWidget();
if (widget != nullptr)
{
return widget->left;
}
return 0;
}
void x_set(int32_t value)
{
auto widget = GetWidget();
if (widget != nullptr)
{
Invalidate();
widget->left = value;
Invalidate();
}
}
int32_t y_get()
{
auto widget = GetWidget();
if (widget != nullptr)
{
return widget->top;
}
return 0;
}
void y_set(int32_t value)
{
auto widget = GetWidget();
if (widget != nullptr)
{
Invalidate();
widget->top = value;
Invalidate();
}
}
int32_t width_get()
{
auto widget = GetWidget();
if (widget != nullptr)
{
return widget->right - widget->left;
}
return 0;
}
void width_set(int32_t value)
{
auto widget = GetWidget();
if (widget != nullptr)
{
Invalidate();
widget->right = widget->left + value;
Invalidate();
}
}
int32_t height_get()
{
auto widget = GetWidget();
if (widget != nullptr)
{
return widget->bottom - widget->top;
}
return 0;
}
void height_set(int32_t value)
{
auto widget = GetWidget();
if (widget != nullptr)
{
Invalidate();
widget->bottom = widget->top + value;
Invalidate();
}
}
std::string text_get()
{
if (IsCustomWindow())
{
auto widget = GetWidget();
if (widget != nullptr && widget->string != nullptr)
{
return widget->string;
}
}
return "";
}
void text_set(std::string value)
{
auto w = GetWindow();
if (w != nullptr && IsCustomWindow())
{
OpenRCT2::Ui::Windows::UpdateWidgetText(w, _widgetIndex, value);
}
}
public:
static void Register(duk_context* ctx)
{
// Common
dukglue_register_property(ctx, &type_get, nullptr, "type");
dukglue_register_property(ctx, &x_get, &x_set, "x");
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");
// No so common
dukglue_register_property(ctx, &text_get, &text_set, "text");
}
private:
rct_window* GetWindow()
{
if (_class == WC_MAIN_WINDOW)
return window_get_main();
else
return window_find_by_number(_class, _number);
}
rct_widget* GetWidget()
{
auto w = GetWindow();
if (w != nullptr)
{
return &w->widgets[_widgetIndex];
}
return nullptr;
}
bool IsCustomWindow()
{
auto w = GetWindow();
if (w != nullptr)
{
return w->classification == WC_CUSTOM;
}
return false;
}
void Invalidate()
{
widget_invalidate_by_number(_class, _number, _widgetIndex);
}
};
} // namespace OpenRCT2::Scripting

View File

@ -9,6 +9,8 @@
#pragma once
#include "ScWidget.hpp"
#include <openrct2/common.h>
#include <openrct2/interface/Window.h>
#include <openrct2/interface/Window_internal.h>
@ -66,6 +68,22 @@ namespace OpenRCT2::Scripting
return (flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)) != 0;
}
std::vector<std::shared_ptr<ScWidget>> widgets_get()
{
std::vector<std::shared_ptr<ScWidget>> result;
auto w = GetWindow();
if (w != nullptr)
{
rct_widgetindex widgetIndex = 0;
for (auto widget = w->widgets; widget->type != WWT_LAST; widget++)
{
result.push_back(std::make_shared<ScWidget>(_class, _number, widgetIndex));
widgetIndex++;
}
}
return result;
}
static void Register(duk_context* ctx)
{
dukglue_register_property(ctx, &ScWindow::x_get, &ScWindow::x_set, "x");
@ -73,6 +91,7 @@ namespace OpenRCT2::Scripting
dukglue_register_property(ctx, &ScWindow::width_get, nullptr, "width");
dukglue_register_property(ctx, &ScWindow::height_get, nullptr, "height");
dukglue_register_property(ctx, &ScWindow::isSticky_get, nullptr, "isSticky");
dukglue_register_property(ctx, &ScWindow::widgets_get, nullptr, "widgets");
}
private:

View File

@ -11,6 +11,7 @@
#include "CustomMenu.h"
#include "ScUi.hpp"
#include "ScWidget.hpp"
#include "ScWindow.hpp"
#include <openrct2/scripting/ScriptEngine.h>
@ -25,6 +26,7 @@ void UiScriptExtensions::Extend(ScriptEngine& scriptEngine)
ScUi::Register(ctx);
ScViewport::Register(ctx);
ScWidget::Register(ctx);
ScWindow::Register(ctx);
InitialiseCustomMenuItems(scriptEngine);