1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-23 07:43:01 +01:00

Fix #9498: Only close the most recent window when using the hotkey (#9504)

This commit is contained in:
ζeh Matt
2019-07-01 22:59:31 +02:00
committed by Michael Steenbeek
parent e149722a15
commit a7f8960151

View File

@@ -51,7 +51,6 @@ TextInputSession* gTextInput;
uint16_t gWindowUpdateTicks; uint16_t gWindowUpdateTicks;
uint16_t gWindowMapFlashingFlags; uint16_t gWindowMapFlashingFlags;
colour_t gCurrentWindowColours[4]; colour_t gCurrentWindowColours[4];
// converted from uint16_t values at 0x009A41EC - 0x009A4230 // converted from uint16_t values at 0x009A41EC - 0x009A4230
@@ -78,6 +77,13 @@ static constexpr const float window_scroll_locations[][2] = {
}; };
// clang-format on // clang-format on
namespace WindowCloseFlags
{
static constexpr uint32_t None = 0;
static constexpr uint32_t IterateReverse = (1 << 0);
static constexpr uint32_t CloseSingle = (1 << 1);
} // namespace WindowCloseFlags
static int32_t window_draw_split( static int32_t window_draw_split(
rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom); rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom);
static void window_draw_single(rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom); static void window_draw_single(rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom);
@@ -239,31 +245,53 @@ void window_close(rct_window* window)
} }
} }
template<typename _TPred> static void window_close_by_condition(_TPred pred) template<typename _TPred> static void window_close_by_condition(_TPred pred, uint32_t flags = WindowCloseFlags::None)
{ {
bool listUpdated; bool listUpdated;
do do
{ {
listUpdated = false; listUpdated = false;
auto windowList = g_window_list; auto closeSingle = [&](std::shared_ptr<rct_window> window) -> bool {
for (auto& w : windowList) if (!pred(window.get()))
{
if (pred(w.get()))
{ {
return false;
}
// Keep track of current amount, if a new window is created upon closing // Keep track of current amount, if a new window is created upon closing
// we need to break this current iteration and restart. // we need to break this current iteration and restart.
size_t previousCount = g_window_list.size(); size_t previousCount = g_window_list.size();
window_close(w.get()); window_close(window.get());
if ((flags & WindowCloseFlags::CloseSingle) != 0)
{
// Only close a single one.
return true;
}
if (previousCount >= g_window_list.size()) if (previousCount >= g_window_list.size())
{ {
listUpdated = true; // A new window was created during the close event.
return true;
}
// Keep closing windows.
return false;
};
// The closest to something like for_each_if is using find_if in order to avoid duplicate code
// to change the loop direction.
auto windowList = g_window_list;
if ((flags & WindowCloseFlags::IterateReverse) != 0)
listUpdated = std::find_if(windowList.rbegin(), windowList.rend(), closeSingle) != windowList.rend();
else
listUpdated = std::find_if(windowList.begin(), windowList.end(), closeSingle) != windowList.end();
// If requested to close only a single window and a new window was created during close
// we ignore it.
if ((flags & WindowCloseFlags::CloseSingle) != 0)
break; break;
}
}
}
} while (listUpdated); } while (listUpdated);
} }
@@ -341,7 +369,8 @@ void window_close_top()
return; return;
} }
window_close_by_condition([](rct_window* w) -> bool { return !(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)); }); auto pred = [](rct_window* w) -> bool { return !(w->flags & (WF_STICK_TO_BACK | WF_STICK_TO_FRONT)); };
window_close_by_condition(pred, WindowCloseFlags::CloseSingle | WindowCloseFlags::IterateReverse);
} }
/** /**