1
0
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:
Hielke Morsink
2022-04-09 18:36:16 +02:00
committed by GitHub
2 changed files with 41 additions and 40 deletions

View File

@@ -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()

View File

@@ -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));
}