mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-16 03:23:15 +01:00
Merge pull request #16950 from Broxzier/bugfix/16829-scenery-window-crash
Fix #16050: Scenery window positioning
This commit is contained in:
@@ -28,10 +28,12 @@
|
||||
#include <openrct2/world/SmallScenery.h>
|
||||
|
||||
static constexpr const rct_string_id WINDOW_TITLE = STR_NONE;
|
||||
constexpr int32_t WINDOW_SCENERY_WIDTH = 634;
|
||||
constexpr int32_t WINDOW_SCENERY_HEIGHT = 180;
|
||||
constexpr int32_t WINDOW_SCENERY_MIN_WIDTH = 634;
|
||||
constexpr int32_t WINDOW_SCENERY_MIN_HEIGHT = 180;
|
||||
constexpr int32_t SCENERY_BUTTON_WIDTH = 66;
|
||||
constexpr int32_t SCENERY_BUTTON_HEIGHT = 80;
|
||||
constexpr int32_t TabWidth = 31;
|
||||
constexpr int32_t MaxTabs = 32;
|
||||
|
||||
constexpr uint8_t SceneryContentScrollIndex = 0;
|
||||
|
||||
@@ -58,7 +60,7 @@ validate_global_widx(WC_SCENERY, WIDX_SCENERY_EYEDROPPER_BUTTON);
|
||||
|
||||
// clang-format off
|
||||
static rct_widget WindowSceneryBaseWidgets[] = {
|
||||
WINDOW_SHIM(WINDOW_TITLE, WINDOW_SCENERY_WIDTH, WINDOW_SCENERY_HEIGHT),
|
||||
WINDOW_SHIM(WINDOW_TITLE, WINDOW_SCENERY_MIN_WIDTH, WINDOW_SCENERY_MIN_HEIGHT),
|
||||
MakeWidget ({ 0, 43}, {634, 99}, WindowWidgetType::Resize, WindowColour::Secondary ), // 8 0x009DE2C8
|
||||
MakeWidget ({ 2, 47}, {607, 80}, WindowWidgetType::Scroll, WindowColour::Secondary, SCROLL_VERTICAL ), // 1000000 0x009DE418
|
||||
MakeWidget ({609, 44}, { 24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_ROTATE_ARROW, STR_ROTATE_OBJECTS_90 ), // 2000000 0x009DE428
|
||||
@@ -122,6 +124,7 @@ private:
|
||||
|
||||
std::vector<SceneryTabInfo> _tabEntries;
|
||||
std::vector<rct_widget> _widgets;
|
||||
int32_t _requiredWidth;
|
||||
ScenerySelection _selectedScenery;
|
||||
int16_t _hoverCounter;
|
||||
|
||||
@@ -145,10 +148,12 @@ public:
|
||||
gWindowSceneryPaintEnabled = 0; // repaint coloured scenery tool state
|
||||
gWindowSceneryEyedropperEnabled = false;
|
||||
|
||||
min_width = WINDOW_SCENERY_WIDTH;
|
||||
max_width = WINDOW_SCENERY_WIDTH;
|
||||
min_height = WINDOW_SCENERY_HEIGHT;
|
||||
max_height = WINDOW_SCENERY_HEIGHT;
|
||||
width = GetRequiredWidth();
|
||||
min_width = width;
|
||||
max_width = width;
|
||||
height = WINDOW_SCENERY_MIN_HEIGHT;
|
||||
min_height = height;
|
||||
max_height = height;
|
||||
}
|
||||
|
||||
void OnClose() override
|
||||
@@ -345,10 +350,8 @@ public:
|
||||
{
|
||||
if (input_get_state() != InputState::ScrollLeft)
|
||||
{
|
||||
min_width = WINDOW_SCENERY_WIDTH;
|
||||
max_width = WINDOW_SCENERY_WIDTH;
|
||||
min_height = WINDOW_SCENERY_HEIGHT;
|
||||
max_height = WINDOW_SCENERY_HEIGHT;
|
||||
min_height = WINDOW_SCENERY_MIN_HEIGHT;
|
||||
max_height = WINDOW_SCENERY_MIN_HEIGHT;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -359,10 +362,8 @@ public:
|
||||
const auto numRows = static_cast<int32_t>(CountRows());
|
||||
const auto maxContentHeight = numRows * SCENERY_BUTTON_HEIGHT;
|
||||
const auto maxWindowHeight = maxContentHeight + nonListHeight;
|
||||
const auto windowHeight = std::clamp(maxWindowHeight, WINDOW_SCENERY_HEIGHT, 463);
|
||||
const auto windowHeight = std::clamp(maxWindowHeight, WINDOW_SCENERY_MIN_HEIGHT, 463);
|
||||
|
||||
min_width = WINDOW_SCENERY_WIDTH;
|
||||
max_width = WINDOW_SCENERY_WIDTH;
|
||||
min_height = windowHeight;
|
||||
max_height = windowHeight;
|
||||
}
|
||||
@@ -374,10 +375,8 @@ public:
|
||||
_hoverCounter = 0;
|
||||
if (input_get_state() != InputState::ScrollLeft)
|
||||
{
|
||||
min_width = WINDOW_SCENERY_WIDTH;
|
||||
max_width = WINDOW_SCENERY_WIDTH;
|
||||
min_height = WINDOW_SCENERY_HEIGHT;
|
||||
max_height = WINDOW_SCENERY_HEIGHT;
|
||||
min_height = WINDOW_SCENERY_MIN_HEIGHT;
|
||||
max_height = WINDOW_SCENERY_MIN_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,8 +614,6 @@ public:
|
||||
const auto lastTabWidget = &widgets[WIDX_SCENERY_TAB_1 + lastTabIndex];
|
||||
windowWidth = std::max<int32_t>(windowWidth, lastTabWidget->right + 3);
|
||||
}
|
||||
min_width = windowWidth;
|
||||
max_width = windowWidth;
|
||||
|
||||
widgets[WIDX_SCENERY_BACKGROUND].right = windowWidth - 1;
|
||||
widgets[WIDX_SCENERY_BACKGROUND].bottom = height - 1;
|
||||
@@ -734,18 +731,11 @@ public:
|
||||
OnMouseDown(WIDX_SCENERY_TAB_1 + tabId);
|
||||
}
|
||||
|
||||
// Used after removing objects, in order to avoid crashes.
|
||||
void ResetSelectedSceneryItems()
|
||||
{
|
||||
gWindowSceneryTabSelections.clear();
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
_tabEntries.clear();
|
||||
|
||||
auto maxTabs = 32;
|
||||
for (ObjectEntryIndex scenerySetIndex = 0; scenerySetIndex < maxTabs - 1; scenerySetIndex++)
|
||||
for (ObjectEntryIndex scenerySetIndex = 0; scenerySetIndex < MaxTabs - 1; scenerySetIndex++)
|
||||
{
|
||||
const auto* sceneryGroupEntry = get_scenery_group_entry(scenerySetIndex);
|
||||
if (sceneryGroupEntry != nullptr && scenery_group_is_invented(scenerySetIndex))
|
||||
@@ -825,11 +815,19 @@ public:
|
||||
_tabEntries.pop_back();
|
||||
}
|
||||
|
||||
// Set required width
|
||||
_requiredWidth = static_cast<int32_t>(_tabEntries.size()) * TabWidth + 5;
|
||||
|
||||
SortTabs();
|
||||
PrepareWidgets();
|
||||
window_invalidate_by_class(WC_SCENERY);
|
||||
}
|
||||
|
||||
int32_t GetRequiredWidth() const
|
||||
{
|
||||
return std::max(_requiredWidth, WINDOW_SCENERY_MIN_WIDTH);
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t GetNumColumns() const
|
||||
{
|
||||
@@ -1026,7 +1024,7 @@ private:
|
||||
for (const auto& tabInfo : _tabEntries)
|
||||
{
|
||||
auto widget = MakeTab(pos, STR_STRING_DEFINED_TOOLTIP);
|
||||
pos.x += 31;
|
||||
pos.x += TabWidth;
|
||||
|
||||
if (tabInfo.SceneryGroupIndex == OBJECT_ENTRY_INDEX_NULL)
|
||||
{
|
||||
@@ -1343,9 +1341,16 @@ private:
|
||||
|
||||
rct_window* WindowSceneryOpen()
|
||||
{
|
||||
return WindowFocusOrCreate<SceneryWindow>(
|
||||
WC_SCENERY, ScreenCoordsXY(context_get_width() - WINDOW_SCENERY_WIDTH, 0x1D), WINDOW_SCENERY_WIDTH,
|
||||
WINDOW_SCENERY_HEIGHT, WF_NO_SCROLLING);
|
||||
auto* w = static_cast<SceneryWindow*>(window_bring_to_front_by_class(WC_SCENERY));
|
||||
if (w == nullptr)
|
||||
{
|
||||
w = WindowCreate<SceneryWindow>(WC_SCENERY);
|
||||
|
||||
// Now the window is initialized, we know the width that it requires. Move it to the top-right edge
|
||||
window_move_position(w, { context_get_width() - w->GetRequiredWidth(), 0x1D });
|
||||
window_push_others_below(w);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
void WindowScenerySetSelectedItem(
|
||||
@@ -1372,11 +1377,8 @@ void WindowScenerySetSelectedTab(const ObjectEntryIndex sceneryGroupIndex)
|
||||
// Used after removing objects, in order to avoid crashes.
|
||||
void WindowSceneryResetSelectedSceneryItems()
|
||||
{
|
||||
auto* w = static_cast<SceneryWindow*>(window_find_by_class(WC_SCENERY));
|
||||
if (w != nullptr)
|
||||
{
|
||||
w->ResetSelectedSceneryItems();
|
||||
}
|
||||
gWindowSceneryTabSelections.clear();
|
||||
gWindowSceneryActiveTabIndex = 0;
|
||||
}
|
||||
|
||||
void WindowScenerySetDefaultPlacementConfiguration()
|
||||
@@ -1386,8 +1388,7 @@ void WindowScenerySetDefaultPlacementConfiguration()
|
||||
gWindowScenerySecondaryColour = COLOUR_YELLOW;
|
||||
gWindowSceneryTertiaryColour = COLOUR_DARK_BROWN;
|
||||
|
||||
gWindowSceneryTabSelections.clear();
|
||||
gWindowSceneryActiveTabIndex = 0;
|
||||
WindowSceneryResetSelectedSceneryItems();
|
||||
}
|
||||
|
||||
void WindowSceneryInit()
|
||||
|
||||
@@ -675,7 +675,7 @@ rct_window* window_bring_to_front_by_number(rct_windowclass cls, rct_windownumbe
|
||||
rct_window* WindowCreate(
|
||||
std::unique_ptr<rct_window>&& w, rct_windowclass cls, ScreenCoordsXY pos, int32_t width, int32_t height, uint32_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, uint32_t flags = 0)
|
||||
T* WindowCreate(rct_windowclass cls, const ScreenCoordsXY& pos = {}, int32_t width = 0, int32_t height = 0, uint32_t flags = 0)
|
||||
{
|
||||
return static_cast<T*>(WindowCreate(std::make_unique<T>(), cls, pos, width, height, flags));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user