1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-20 14:23:08 +01:00

Move WindowCreate and WindowFocusOrCreate into WindowManager (#23643)

* Move WindowBringToFront into WindowManager

* Move WindowCreate and WindowFocusOrCreate into WindowManager

* Cut back on Context/UiContext includes
This commit is contained in:
Aaron van Geffen
2025-01-19 10:58:28 +01:00
committed by GitHub
parent 66ede938f8
commit bed4d5bdca
113 changed files with 895 additions and 767 deletions

View File

@@ -41,179 +41,6 @@ namespace OpenRCT2
static int32_t _previousAbsoluteWheel = 0;
static bool WindowFitsBetweenOthers(const ScreenCoordsXY& loc, int32_t width, int32_t height)
{
for (auto& w : g_window_list)
{
if (w->flags & WF_DEAD)
continue;
if (w->flags & WF_STICK_TO_BACK)
continue;
if (loc.x + width <= w->windowPos.x)
continue;
if (loc.x >= w->windowPos.x + w->width)
continue;
if (loc.y + height <= w->windowPos.y)
continue;
if (loc.y >= w->windowPos.y + w->height)
continue;
return false;
}
return true;
}
static bool WindowFitsWithinSpace(const ScreenCoordsXY& loc, int32_t width, int32_t height)
{
if (loc.x < 0)
return false;
if (loc.y <= kTopToolbarHeight && !(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO))
return false;
if (loc.x + width > ContextGetWidth())
return false;
if (loc.y + height > ContextGetHeight())
return false;
return WindowFitsBetweenOthers(loc, width, height);
}
static bool WindowFitsOnScreen(const ScreenCoordsXY& loc, int32_t width, int32_t height)
{
uint16_t screenWidth = ContextGetWidth();
uint16_t screenHeight = ContextGetHeight();
int32_t unk;
unk = -(width / 4);
if (loc.x < unk)
return false;
unk = screenWidth + (unk * 2);
if (loc.x > unk)
return false;
if (loc.y <= kTopToolbarHeight && !(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO))
return false;
unk = screenHeight - (height / 4);
if (loc.y > unk)
return false;
return WindowFitsBetweenOthers(loc, width, height);
}
static ScreenCoordsXY ClampWindowToScreen(
const ScreenCoordsXY& pos, const int32_t screenWidth, const int32_t screenHeight, const int32_t width,
const int32_t height)
{
auto screenPos = pos;
if (width > screenWidth || screenPos.x < 0)
screenPos.x = 0;
else if (screenPos.x + width > screenWidth)
screenPos.x = screenWidth - width;
auto toolbarAllowance = (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) ? 0 : (kTopToolbarHeight + 1);
if (height - toolbarAllowance > screenHeight || screenPos.y < toolbarAllowance)
screenPos.y = toolbarAllowance;
else if (screenPos.y + height - toolbarAllowance > screenHeight)
screenPos.y = screenHeight + toolbarAllowance - height;
return screenPos;
}
static ScreenCoordsXY GetAutoPositionForNewWindow(int32_t width, int32_t height)
{
auto uiContext = GetContext()->GetUiContext();
auto screenWidth = uiContext->GetWidth();
auto screenHeight = uiContext->GetHeight();
// Place window in an empty corner of the screen
const ScreenCoordsXY cornerPositions[] = {
{ 0, 30 }, // topLeft
{ screenWidth - width, 30 }, // topRight
{ 0, screenHeight - 34 - height }, // bottomLeft
{ screenWidth - width, screenHeight - 34 - height }, // bottomRight
};
for (const auto& cornerPos : cornerPositions)
{
if (WindowFitsWithinSpace(cornerPos, width, height))
{
return ClampWindowToScreen(cornerPos, screenWidth, screenHeight, width, height);
}
}
// Place window next to another
for (auto& w : g_window_list)
{
if (w->flags & WF_DEAD)
continue;
if (w->flags & WF_STICK_TO_BACK)
continue;
const ScreenCoordsXY offsets[] = {
{ w->width + 2, 0 },
{ -w->width - 2, 0 },
{ 0, w->height + 2 },
{ 0, -w->height - 2 },
{ w->width + 2, -w->height - 2 },
{ -w->width - 2, -w->height - 2 },
{ w->width + 2, w->height + 2 },
{ -w->width - 2, w->height + 2 },
};
for (const auto& offset : offsets)
{
auto screenPos = w->windowPos + offset;
if (WindowFitsWithinSpace(screenPos, width, height))
{
return ClampWindowToScreen(screenPos, screenWidth, screenHeight, width, height);
}
}
}
// Overlap
for (auto& w : g_window_list)
{
if (w->flags & WF_DEAD)
continue;
if (w->flags & WF_STICK_TO_BACK)
continue;
const ScreenCoordsXY offsets[] = {
{ w->width + 2, 0 },
{ -w->width - 2, 0 },
{ 0, w->height + 2 },
{ 0, -w->height - 2 },
};
for (const auto& offset : offsets)
{
auto screenPos = w->windowPos + offset;
if (WindowFitsOnScreen(screenPos, width, height))
{
return ClampWindowToScreen(screenPos, screenWidth, screenHeight, width, height);
}
}
}
// Cascade
auto screenPos = ScreenCoordsXY{ 0, 30 };
for (auto& w : g_window_list)
{
if (screenPos == w->windowPos)
{
screenPos.x += 5;
screenPos.y += 5;
}
}
return ClampWindowToScreen(screenPos, screenWidth, screenHeight, width, height);
}
static ScreenCoordsXY GetCentrePositionForNewWindow(int32_t width, int32_t height)
{
auto uiContext = GetContext()->GetUiContext();
auto screenWidth = uiContext->GetWidth();
auto screenHeight = uiContext->GetHeight();
return ScreenCoordsXY{ (screenWidth - width) / 2, std::max(kTopToolbarHeight + 1, (screenHeight - height) / 2) };
}
static int32_t WindowGetWidgetIndex(const WindowBase& w, Widget* widget)
{
const auto it = std::find_if(
@@ -441,7 +268,7 @@ namespace OpenRCT2
// Check window cursor is over
if (!(InputTestFlag(INPUT_FLAG_5)))
{
auto* windowMgr = GetContext()->GetUiContext()->GetWindowManager();
auto* windowMgr = GetWindowManager();
WindowBase* w = windowMgr->FindFromPoint(cursorState->position);
if (w != nullptr)
{
@@ -734,96 +561,6 @@ namespace OpenRCT2::Ui::Windows
static TextInputSession* _textInput;
static WidgetIdentifier _currentTextBox = { { WindowClass::Null, 0 }, 0 };
WindowBase* WindowCreate(
std::unique_ptr<WindowBase>&& wp, WindowClass cls, ScreenCoordsXY pos, int32_t width, int32_t height, uint32_t flags)
{
if (flags & WF_AUTO_POSITION)
{
if (flags & WF_CENTRE_SCREEN)
{
pos = GetCentrePositionForNewWindow(width, height);
}
else
{
pos = GetAutoPositionForNewWindow(width, height);
}
}
// Check if there are any window slots left
// include kWindowLimitReserved for items such as the main viewport and toolbars to not appear to be counted.
if (g_window_list.size() >= static_cast<size_t>(Config::Get().general.WindowLimit + kWindowLimitReserved))
{
// Close least recently used window
for (auto& w : g_window_list)
{
if (w->flags & WF_DEAD)
continue;
if (!(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT | WF_NO_AUTO_CLOSE)))
{
WindowClose(*w.get());
break;
}
}
}
// Find right position to insert new window
auto itDestPos = g_window_list.end();
if (flags & WF_STICK_TO_BACK)
{
for (auto it = g_window_list.begin(); it != g_window_list.end(); it++)
{
if ((*it)->flags & WF_DEAD)
continue;
if (!((*it)->flags & WF_STICK_TO_BACK))
{
itDestPos = it;
}
}
}
else if (!(flags & WF_STICK_TO_FRONT))
{
for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++)
{
if ((*it)->flags & WF_DEAD)
continue;
if (!((*it)->flags & WF_STICK_TO_FRONT))
{
itDestPos = it.base();
break;
}
}
}
auto itNew = g_window_list.insert(itDestPos, std::move(wp));
auto w = itNew->get();
// Setup window
w->classification = cls;
w->flags = flags;
// Play sounds and flash the window
if (!(flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)))
{
w->flags |= WF_WHITE_BORDER_MASK;
OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::WindowOpen, 0, pos.x + (width / 2));
}
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->focus = std::nullopt;
ColourSchemeUpdate(w);
w->Invalidate();
w->OnOpen();
return w;
}
WindowBase* WindowGetListening()
{
for (auto it = g_window_list.rbegin(); it != g_window_list.rend(); it++)
@@ -871,7 +608,7 @@ namespace OpenRCT2::Ui::Windows
{
if (_usingWidgetTextBox)
{
auto* windowMgr = GetContext()->GetUiContext()->GetWindowManager();
auto* windowMgr = GetWindowManager();
WindowBase* w = windowMgr->FindByNumber(_currentTextBox.window.classification, _currentTextBox.window.number);
_currentTextBox.window.classification = WindowClass::Null;
_currentTextBox.window.number = 0;
@@ -897,7 +634,7 @@ namespace OpenRCT2::Ui::Windows
if (_usingWidgetTextBox)
{
_textBoxFrameNo = 0;
auto* windowMgr = GetContext()->GetUiContext()->GetWindowManager();
auto* windowMgr = GetWindowManager();
WindowBase* w = windowMgr->FindByNumber(_currentTextBox.window.classification, _currentTextBox.window.number);
WidgetInvalidate(*w, _currentTextBox.widget_index);
w->OnTextInput(_currentTextBox.widget_index, _textBoxInput);