1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-22 23:33:04 +01:00

Start window refactor framework

This commit is contained in:
Ted John
2021-01-10 11:41:55 +00:00
committed by GitHub
parent ef6a80982a
commit d907c58a13
6 changed files with 1033 additions and 921 deletions

View File

@@ -87,8 +87,8 @@ static bool WindowFitsOnScreen(const ScreenCoordsXY& loc, int32_t width, int32_t
}
rct_window* WindowCreate(
const ScreenCoordsXY& screenCoords, int32_t width, int32_t height, rct_window_event_list* event_handlers,
rct_windowclass cls, uint16_t flags)
std::unique_ptr<rct_window>&& wp, rct_windowclass cls, const ScreenCoordsXY& pos, int32_t width, int32_t height,
uint16_t flags)
{
// Check if there are any window slots left
// include WINDOW_LIMIT_RESERVED for items such as the main viewport and toolbars to not appear to be counted.
@@ -129,7 +129,7 @@ rct_window* WindowCreate(
}
}
auto itNew = g_window_list.insert(itDestPos, std::make_unique<rct_window>());
auto itNew = g_window_list.insert(itDestPos, std::move(wp));
auto w = itNew->get();
// Setup window
@@ -140,23 +140,17 @@ rct_window* WindowCreate(
if (!(flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)))
{
w->flags |= WF_WHITE_BORDER_MASK;
OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::WindowOpen, 0, screenCoords.x + (width / 2));
OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::WindowOpen, 0, pos.x + (width / 2));
}
w->number = 0;
w->windowPos = screenCoords;
w->windowPos = pos;
w->width = width;
w->height = height;
w->min_width = width;
w->max_width = width;
w->min_height = height;
w->max_height = height;
w->viewport = nullptr;
w->event_handlers = event_handlers;
w->enabled_widgets = 0;
w->disabled_widgets = 0;
w->pressed_widgets = 0;
w->hold_down_widgets = 0;
w->viewport_focus_coordinates.var_480 = 0;
w->viewport_focus_coordinates.x = 0;
w->viewport_focus_coordinates.y = 0;
@@ -164,18 +158,23 @@ rct_window* WindowCreate(
w->viewport_focus_coordinates.rotation = 0;
w->page = 0;
w->var_48C = 0;
w->frame_no = 0;
w->list_information_type = 0;
w->var_492 = 0;
w->selected_tab = 0;
w->var_4AE = 0;
w->viewport_smart_follow_sprite = SPRITE_INDEX_NULL;
ColourSchemeUpdate(w);
w->Invalidate();
w->OnOpen();
return w;
}
rct_window* WindowCreate(
const ScreenCoordsXY& pos, int32_t width, int32_t height, rct_window_event_list* event_handlers, rct_windowclass cls,
uint16_t flags)
{
auto w = std::make_unique<rct_window>();
w->event_handlers = event_handlers;
return WindowCreate(std::move(w), cls, pos, width, height, flags);
}
static ScreenCoordsXY ClampWindowToScreen(const ScreenCoordsXY& pos, const int32_t screenWidth, const int32_t width)
{
auto screenPos = pos;
@@ -654,3 +653,49 @@ void InvalidateAllWindowsAfterInput()
window_event_resize_call(w);
});
}
void Window::InvalidateWidget(rct_widgetindex widgetIndex)
{
widget_invalidate(this, widgetIndex);
}
bool Window::IsWidgetDisabled(rct_widgetindex widgetIndex) const
{
return (disabled_widgets & (1LL << widgetIndex)) != 0;
}
bool Window::IsWidgetPressed(rct_widgetindex widgetIndex) const
{
return (pressed_widgets & (1LL << widgetIndex)) != 0;
}
void Window::SetWidgetDisabled(rct_widgetindex widgetIndex, bool value)
{
if (value)
disabled_widgets |= (1ULL << widgetIndex);
else
disabled_widgets &= ~(1ULL << widgetIndex);
}
void Window::SetWidgetPressed(rct_widgetindex widgetIndex, bool value)
{
if (value)
pressed_widgets |= (1ULL << widgetIndex);
else
pressed_widgets &= ~(1ULL << widgetIndex);
}
void Window::SetCheckboxValue(rct_widgetindex widgetIndex, bool value)
{
SetWidgetPressed(widgetIndex, value);
}
void Window::DrawWidgets(rct_drawpixelinfo& dpi)
{
WindowDrawWidgets(this, &dpi);
}
void Window::Close()
{
window_close(this);
}

View File

@@ -12,5 +12,17 @@
#include <openrct2/interface/Window.h>
#include <openrct2/interface/Window_internal.h>
struct Window : rct_window
{
void InvalidateWidget(rct_widgetindex widgetIndex);
bool IsWidgetDisabled(rct_widgetindex widgetIndex) const;
bool IsWidgetPressed(rct_widgetindex widgetIndex) const;
void SetWidgetDisabled(rct_widgetindex widgetIndex, bool value);
void SetWidgetPressed(rct_widgetindex widgetIndex, bool value);
void SetCheckboxValue(rct_widgetindex widgetIndex, bool value);
void DrawWidgets(rct_drawpixelinfo& dpi);
void Close();
};
void WindowAllWheelInput();
void ApplyScreenSaverLockSetting();

File diff suppressed because it is too large Load Diff

View File

@@ -1387,141 +1387,178 @@ void tool_cancel()
void window_event_close_call(rct_window* w)
{
if (w->event_handlers->close != nullptr)
if (w->event_handlers == nullptr)
w->OnClose();
else if (w->event_handlers->close != nullptr)
w->event_handlers->close(w);
}
void window_event_mouse_up_call(rct_window* w, rct_widgetindex widgetIndex)
{
if (w->event_handlers->mouse_up != nullptr)
if (w->event_handlers == nullptr)
w->OnMouseUp(widgetIndex);
else if (w->event_handlers->mouse_up != nullptr)
w->event_handlers->mouse_up(w, widgetIndex);
}
void window_event_resize_call(rct_window* w)
{
if (w->event_handlers->resize != nullptr)
w->event_handlers->resize(w);
if (w->event_handlers != nullptr)
if (w->event_handlers->resize != nullptr)
w->event_handlers->resize(w);
}
void window_event_mouse_down_call(rct_window* w, rct_widgetindex widgetIndex)
{
if (w->event_handlers->mouse_down != nullptr)
if (w->event_handlers == nullptr)
w->OnMouseDown(widgetIndex);
else if (w->event_handlers->mouse_down != nullptr)
w->event_handlers->mouse_down(w, widgetIndex, &w->widgets[widgetIndex]);
}
void window_event_dropdown_call(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex)
{
if (w->event_handlers->dropdown != nullptr)
if (w->event_handlers == nullptr)
w->OnDropdown(widgetIndex, dropdownIndex);
else if (w->event_handlers->dropdown != nullptr)
w->event_handlers->dropdown(w, widgetIndex, dropdownIndex);
}
void window_event_unknown_05_call(rct_window* w)
{
if (w->event_handlers->unknown_05 != nullptr)
w->event_handlers->unknown_05(w);
if (w->event_handlers != nullptr)
if (w->event_handlers->unknown_05 != nullptr)
w->event_handlers->unknown_05(w);
}
void window_event_update_call(rct_window* w)
{
if (w->event_handlers->update != nullptr)
if (w->event_handlers == nullptr)
w->OnUpdate();
else if (w->event_handlers->update != nullptr)
w->event_handlers->update(w);
}
void window_event_periodic_update_call(rct_window* w)
{
if (w->event_handlers->periodic_update != nullptr)
w->event_handlers->periodic_update(w);
if (w->event_handlers != nullptr)
if (w->event_handlers->periodic_update != nullptr)
w->event_handlers->periodic_update(w);
}
void window_event_unknown_08_call(rct_window* w)
{
if (w->event_handlers->unknown_08 != nullptr)
w->event_handlers->unknown_08(w);
if (w->event_handlers != nullptr)
if (w->event_handlers->unknown_08 != nullptr)
w->event_handlers->unknown_08(w);
}
void window_event_tool_update_call(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords)
{
if (w->event_handlers->tool_update != nullptr)
w->event_handlers->tool_update(w, widgetIndex, screenCoords);
if (w->event_handlers != nullptr)
if (w->event_handlers->tool_update != nullptr)
w->event_handlers->tool_update(w, widgetIndex, screenCoords);
}
void window_event_tool_down_call(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords)
{
if (w->event_handlers->tool_down != nullptr)
w->event_handlers->tool_down(w, widgetIndex, screenCoords);
if (w->event_handlers != nullptr)
if (w->event_handlers->tool_down != nullptr)
w->event_handlers->tool_down(w, widgetIndex, screenCoords);
}
void window_event_tool_drag_call(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords)
{
if (w->event_handlers->tool_drag != nullptr)
w->event_handlers->tool_drag(w, widgetIndex, screenCoords);
if (w->event_handlers != nullptr)
if (w->event_handlers->tool_drag != nullptr)
w->event_handlers->tool_drag(w, widgetIndex, screenCoords);
}
void window_event_tool_up_call(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords)
{
if (w->event_handlers->tool_up != nullptr)
w->event_handlers->tool_up(w, widgetIndex, screenCoords);
if (w->event_handlers != nullptr)
if (w->event_handlers->tool_up != nullptr)
w->event_handlers->tool_up(w, widgetIndex, screenCoords);
}
void window_event_tool_abort_call(rct_window* w, rct_widgetindex widgetIndex)
{
if (w->event_handlers->tool_abort != nullptr)
w->event_handlers->tool_abort(w, widgetIndex);
if (w->event_handlers != nullptr)
if (w->event_handlers->tool_abort != nullptr)
w->event_handlers->tool_abort(w, widgetIndex);
}
void window_event_unknown_0E_call(rct_window* w)
{
if (w->event_handlers->unknown_0E != nullptr)
w->event_handlers->unknown_0E(w);
if (w->event_handlers != nullptr)
if (w->event_handlers->unknown_0E != nullptr)
w->event_handlers->unknown_0E(w);
}
void window_get_scroll_size(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height)
{
if (w->event_handlers->get_scroll_size != nullptr)
{
w->event_handlers->get_scroll_size(w, scrollIndex, width, height);
}
if (w->event_handlers != nullptr)
if (w->event_handlers->get_scroll_size != nullptr)
w->event_handlers->get_scroll_size(w, scrollIndex, width, height);
}
void window_event_scroll_mousedown_call(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords)
{
if (w->event_handlers->scroll_mousedown != nullptr)
w->event_handlers->scroll_mousedown(w, scrollIndex, screenCoords);
if (w->event_handlers != nullptr)
if (w->event_handlers->scroll_mousedown != nullptr)
w->event_handlers->scroll_mousedown(w, scrollIndex, screenCoords);
}
void window_event_scroll_mousedrag_call(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords)
{
if (w->event_handlers->scroll_mousedrag != nullptr)
w->event_handlers->scroll_mousedrag(w, scrollIndex, screenCoords);
if (w->event_handlers != nullptr)
if (w->event_handlers->scroll_mousedrag != nullptr)
w->event_handlers->scroll_mousedrag(w, scrollIndex, screenCoords);
}
void window_event_scroll_mouseover_call(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords)
{
if (w->event_handlers->scroll_mouseover != nullptr)
w->event_handlers->scroll_mouseover(w, scrollIndex, screenCoords);
if (w->event_handlers != nullptr)
if (w->event_handlers->scroll_mouseover != nullptr)
w->event_handlers->scroll_mouseover(w, scrollIndex, screenCoords);
}
void window_event_textinput_call(rct_window* w, rct_widgetindex widgetIndex, char* text)
{
if (w->event_handlers->text_input != nullptr)
if (w->event_handlers == nullptr)
{
if (text != nullptr)
{
w->OnTextInput(widgetIndex, text);
}
}
else if (w->event_handlers->text_input != nullptr)
{
w->event_handlers->text_input(w, widgetIndex, text);
}
}
void window_event_viewport_rotate_call(rct_window* w)
{
if (w->event_handlers->viewport_rotate != nullptr)
w->event_handlers->viewport_rotate(w);
if (w->event_handlers != nullptr)
if (w->event_handlers->viewport_rotate != nullptr)
w->event_handlers->viewport_rotate(w);
}
void window_event_unknown_15_call(rct_window* w, int32_t scrollIndex, int32_t scrollAreaType)
{
if (w->event_handlers->unknown_15 != nullptr)
w->event_handlers->unknown_15(w, scrollIndex, scrollAreaType);
if (w->event_handlers != nullptr)
if (w->event_handlers->unknown_15 != nullptr)
w->event_handlers->unknown_15(w, scrollIndex, scrollAreaType);
}
OpenRCT2String window_event_tooltip_call(rct_window* w, const rct_widgetindex widgetIndex, const rct_string_id fallback)
{
if (w->event_handlers->tooltip != nullptr)
if (w->event_handlers == nullptr)
{
return w->OnTooltip(widgetIndex, fallback);
}
else if (w->event_handlers->tooltip != nullptr)
{
return w->event_handlers->tooltip(w, widgetIndex, fallback);
}
@@ -1534,33 +1571,40 @@ OpenRCT2String window_event_tooltip_call(rct_window* w, const rct_widgetindex wi
CursorID window_event_cursor_call(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords)
{
CursorID cursorId = CursorID::Arrow;
if (w->event_handlers->cursor != nullptr)
w->event_handlers->cursor(w, widgetIndex, screenCoords, &cursorId);
if (w->event_handlers != nullptr)
if (w->event_handlers->cursor != nullptr)
w->event_handlers->cursor(w, widgetIndex, screenCoords, &cursorId);
return cursorId;
}
void window_event_moved_call(rct_window* w, const ScreenCoordsXY& screenCoords)
{
if (w->event_handlers->moved != nullptr)
w->event_handlers->moved(w, screenCoords);
if (w->event_handlers != nullptr)
if (w->event_handlers->moved != nullptr)
w->event_handlers->moved(w, screenCoords);
}
void window_event_invalidate_call(rct_window* w)
{
if (w->event_handlers->invalidate != nullptr)
if (w->event_handlers == nullptr)
w->OnPrepareDraw();
else if (w->event_handlers->invalidate != nullptr)
w->event_handlers->invalidate(w);
}
void window_event_paint_call(rct_window* w, rct_drawpixelinfo* dpi)
{
if (w->event_handlers->paint != nullptr)
if (w->event_handlers == nullptr)
w->OnDraw(*dpi);
else if (w->event_handlers->paint != nullptr)
w->event_handlers->paint(w, dpi);
}
void window_event_scroll_paint_call(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex)
{
if (w->event_handlers->scroll_paint != nullptr)
w->event_handlers->scroll_paint(w, dpi, scrollIndex);
if (w->event_handlers != nullptr)
if (w->event_handlers->scroll_paint != nullptr)
w->event_handlers->scroll_paint(w, dpi, scrollIndex);
}
/**

View File

@@ -173,15 +173,15 @@ struct rct_viewport
*/
struct rct_scroll
{
uint16_t flags; // 0x00
uint16_t h_left; // 0x02
uint16_t h_right; // 0x04
uint16_t h_thumb_left; // 0x06
uint16_t h_thumb_right; // 0x08
uint16_t v_top; // 0x0A
uint16_t v_bottom; // 0x0C
uint16_t v_thumb_top; // 0x0E
uint16_t v_thumb_bottom; // 0x10
uint16_t flags{}; // 0x00
uint16_t h_left{}; // 0x02
uint16_t h_right{}; // 0x04
uint16_t h_thumb_left{}; // 0x06
uint16_t h_thumb_right{}; // 0x08
uint16_t v_top{}; // 0x0A
uint16_t v_bottom{}; // 0x0C
uint16_t v_thumb_top{}; // 0x0E
uint16_t v_thumb_bottom{}; // 0x10
};
constexpr auto WINDOW_SCROLL_UNDEFINED = std::numeric_limits<uint16_t>::max();
@@ -673,12 +673,22 @@ void window_update_all();
void window_set_window_limit(int32_t value);
rct_window* WindowCreate(
const ScreenCoordsXY& screenCoords, int32_t width, int32_t height, rct_window_event_list* event_handlers,
rct_windowclass cls, uint16_t flags);
std::unique_ptr<rct_window>&& w, rct_windowclass cls, const ScreenCoordsXY& pos, int32_t width, int32_t height,
uint16_t flags);
template<typename T, typename std::enable_if<std::is_base_of<rct_window, T>::value>::type* = nullptr>
T* WindowCreate(rct_windowclass cls, const ScreenCoordsXY& pos, int32_t width, int32_t height, uint16_t flags = 0)
{
return static_cast<T*>(WindowCreate(std::make_unique<T>(), cls, pos, width, height, flags));
}
rct_window* WindowCreate(
const ScreenCoordsXY& pos, int32_t width, int32_t height, rct_window_event_list* event_handlers, rct_windowclass cls,
uint16_t flags);
rct_window* WindowCreateAutoPos(
int32_t width, int32_t height, rct_window_event_list* event_handlers, rct_windowclass cls, uint16_t flags);
rct_window* WindowCreateCentred(
int32_t width, int32_t height, rct_window_event_list* event_handlers, rct_windowclass cls, uint16_t flags);
void window_close(rct_window* window);
void window_close_by_class(rct_windowclass cls);
void window_close_by_number(rct_windowclass cls, rct_windownumber number);

View File

@@ -9,6 +9,7 @@
#pragma once
#include "../world/Sprite.h"
#include "Window.h"
#include <list>
@@ -19,32 +20,38 @@ enum class TileInspectorPage : int16_t;
struct ResearchItem;
struct rct_object_entry;
#ifdef __WARN_SUGGEST_FINAL_METHODS__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wsuggest-final-methods"
# pragma GCC diagnostic ignored "-Wsuggest-final-types"
#endif
/**
* Window structure
* size: 0x4C0
*/
struct rct_window
{
rct_window_event_list* event_handlers;
rct_viewport* viewport;
uint64_t enabled_widgets;
uint64_t disabled_widgets;
uint64_t pressed_widgets;
uint64_t hold_down_widgets;
rct_widget* widgets;
rct_window_event_list* event_handlers{};
rct_viewport* viewport{};
uint64_t enabled_widgets{};
uint64_t disabled_widgets{};
uint64_t pressed_widgets{};
uint64_t hold_down_widgets{};
rct_widget* widgets{};
ScreenCoordsXY windowPos;
int16_t width;
int16_t height;
int16_t min_width;
int16_t max_width;
int16_t min_height;
int16_t max_height;
rct_windownumber number;
uint16_t flags;
int16_t width{};
int16_t height{};
int16_t min_width{};
int16_t max_width{};
int16_t min_height{};
int16_t max_height{};
rct_windownumber number{};
uint16_t flags{};
rct_scroll scrolls[3];
uint8_t list_item_positions[1024];
uint16_t no_list_items; // 0 for no items
int16_t selected_list_item; // -1 for none selected
uint8_t list_item_positions[1024]{};
uint16_t no_list_items{}; // 0 for no items
int16_t selected_list_item{}; // -1 for none selected
union
{
coordinate_focus viewport_focus_coordinates;
@@ -72,8 +79,8 @@ struct rct_window
int16_t SceneryEntry; // Used in sign window.
int16_t var_48C;
};
uint16_t frame_no; // updated every tic for motion in windows sprites
uint16_t list_information_type; // 0 for none, Used as current position of marquee in window_peep
uint16_t frame_no{}; // updated every tic for motion in windows sprites
uint16_t list_information_type{}; // 0 for none, Used as current position of marquee in window_peep
union
{
int16_t picked_peep_frame; // Animation frame of picked peep in staff window and guest window
@@ -88,20 +95,60 @@ struct rct_window
const scenario_index_entry* highlighted_scenario;
uint16_t var_496;
};
int16_t selected_tab;
int16_t var_4AE;
uint16_t viewport_target_sprite;
ScreenCoordsXY savedViewPos;
rct_windowclass classification;
colour_t colours[6];
VisibilityCache visibility;
uint16_t viewport_smart_follow_sprite; // Handles setting viewport target sprite etc
int16_t selected_tab{};
int16_t var_4AE{};
uint16_t viewport_target_sprite{};
ScreenCoordsXY savedViewPos{};
rct_windowclass classification{};
colour_t colours[6]{};
VisibilityCache visibility{};
uint16_t viewport_smart_follow_sprite = SPRITE_INDEX_NULL; // Handles setting viewport target sprite etc
void SetLocation(const CoordsXYZ& coords);
void ScrollToViewport();
void Invalidate();
void RemoveViewport();
rct_window() = default;
virtual ~rct_window() = default;
// Events
virtual void OnOpen()
{
}
virtual void OnClose()
{
}
virtual void OnUpdate()
{
}
virtual void OnPrepareDraw()
{
}
virtual void OnDraw(rct_drawpixelinfo& dpi)
{
}
virtual OpenRCT2String OnTooltip(rct_widgetindex widgetIndex, rct_string_id fallback)
{
return { fallback, {} };
}
virtual void OnMouseDown(rct_widgetindex widgetIndex)
{
}
virtual void OnMouseUp(rct_widgetindex widgetIndex)
{
}
virtual void OnDropdown(rct_widgetindex widgetIndex, int32_t selectedIndex)
{
}
virtual void OnTextInput(rct_widgetindex widgetIndex, std::string_view text)
{
}
};
#ifdef __WARN_SUGGEST_FINAL_METHODS__
# pragma GCC diagnostic pop
#endif
// rct2: 0x01420078
extern std::list<std::shared_ptr<rct_window>> g_window_list;