diff --git a/src/gfx.cpp b/src/gfx.cpp index 5f398b6d12..a313e83db7 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -1561,8 +1561,7 @@ void DrawDirtyBlocks() if (_whole_screen_dirty) { RedrawScreenRect(0, 0, _screen.width, _screen.height); - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { w->flags &= ~(WF_DIRTY | WF_WIDGETS_DIRTY | WF_DRAG_DIRTIED); } _whole_screen_dirty = false; @@ -1579,8 +1578,7 @@ void DrawDirtyBlocks() DrawPixelInfo bk; _cur_dpi = &bk; - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { w->flags &= ~WF_DRAG_DIRTIED; if (!MayBeShown(w)) continue; @@ -1640,8 +1638,7 @@ void DrawDirtyBlocks() int right = vp->left + vp->width; int bottom = vp->top + vp->height; _dirty_viewport_occlusions.clear(); - const Window *v; - FOR_ALL_WINDOWS_FROM_BACK_FROM(v, w->z_front) { + for (const Window *v : Window::IterateFromBack(w->z_front)) { if (MayBeShown(v) && right > v->left && bottom > v->top && diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 3ce2d6f321..1390a4cd99 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -2666,8 +2666,7 @@ struct IndustryCargoesWindow : public Window { InvalidateWindowClassesData(WC_SMALLMAP, 0); /* Notify viewports too. */ - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->viewport != nullptr) if (w->viewport->zoom >= ZOOM_LVL_DRAW_MAP && w->viewport->map_type == VPMT_INDUSTRY) w->InvalidateData(); diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 2194a77702..f023615c10 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -1365,8 +1365,7 @@ void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallback { if (parent == nullptr) parent = FindWindowById(WC_MAIN_WINDOW, 0); - const Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (const Window *w : Window::IterateFromBack()) { if (w->window_class != WC_CONFIRM_POPUP_QUERY) continue; const QueryWindow *qw = (const QueryWindow *)w; diff --git a/src/openttd.cpp b/src/openttd.cpp index c63db32d48..ac88410b8b 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -475,8 +475,9 @@ static void ShutdownGame() static void LoadIntroGame(bool load_newgrfs = true) { UnshowCriticalError(); - Window *v; - FOR_ALL_WINDOWS_FROM_FRONT(v) delete v; + for (Window *w : Window::IterateFromFront()) { + delete w; + } _game_mode = GM_MENU; diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 304fd251a8..a342c8f834 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -489,8 +489,7 @@ static inline uint32 GetSmallMapOwnerPixels(TileIndex tile, TileType t) static void NotifyAllViewports(ViewportMapType map_type) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->viewport != nullptr) if (w->viewport->zoom >= ZOOM_LVL_DRAW_MAP && w->viewport->map_type == map_type) { ClearViewportLandPixelCache(w->viewport); diff --git a/src/sound.cpp b/src/sound.cpp index 7bd865dead..d26aa2d8c2 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -251,8 +251,7 @@ static void SndPlayScreenCoordFx(SoundID sound, int left, int right, int top, in { if (_settings_client.music.effect_vol == 0) return; - const Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (const Window *w : Window::IterateFromBack()) { const Viewport *vp = w->viewport; if (vp != nullptr && diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index c213c5c557..e1c181075f 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2531,8 +2531,7 @@ void DirtyVehicleListWindowForVehicle(const Vehicle *v) { WindowClass cls = static_cast(WC_TRAINS_LIST + v->type); WindowClass cls2 = (v->type == VEH_TRAIN) ? WC_TRACE_RESTRICT_SLOTS : cls; - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->window_class == cls || w->window_class == cls2) { BaseVehicleListWindow *listwin = static_cast(w); uint max = std::min(listwin->vscroll->GetPosition() + listwin->vscroll->GetCapacity(), (uint)listwin->vehgroups.size()); diff --git a/src/viewport.cpp b/src/viewport.cpp index 49c2dee67b..d0198f20cc 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -453,7 +453,7 @@ static void DoViewportRedrawRegions(const Window *w, int left, int top, int widt { if (width <= 0 || height <= 0) return; - FOR_ALL_WINDOWS_FROM_BACK_FROM(w, w) { + for (const Window *w : Window::IterateFromBack(w)) { if (left + width > w->left && w->left + w->width > left && top + height > w->top && @@ -3641,8 +3641,7 @@ void MarkAllRouteStepsDirty(const Vehicle *veh) */ void MarkAllViewportMapsDirty(int left, int top, int right, int bottom) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { Viewport *vp = w->viewport; if (vp != nullptr && vp->zoom >= ZOOM_LVL_DRAW_MAP) { MarkViewportDirty(vp, left, top, right, bottom, VMDF_NOT_LANDSCAPE); @@ -3652,8 +3651,7 @@ void MarkAllViewportMapsDirty(int left, int top, int right, int bottom) void MarkAllViewportMapLandscapesDirty() { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { Viewport *vp = w->viewport; if (vp != nullptr && vp->zoom >= ZOOM_LVL_DRAW_MAP) { ClearViewportLandPixelCache(vp); @@ -3664,8 +3662,7 @@ void MarkAllViewportMapLandscapesDirty() void MarkWholeNonMapViewportsDirty() { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { Viewport *vp = w->viewport; if (vp != nullptr && vp->zoom < ZOOM_LVL_DRAW_MAP) { w->SetDirty(); @@ -3680,8 +3677,7 @@ void MarkWholeNonMapViewportsDirty() */ void MarkAllViewportOverlayStationLinksDirty(const Station *st) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { Viewport *vp = w->viewport; if (vp != nullptr && vp->overlay != nullptr) { vp->overlay->MarkStationViewportLinksDirty(st); @@ -3691,8 +3687,7 @@ void MarkAllViewportOverlayStationLinksDirty(const Station *st) void ConstrainAllViewportsZoom() { - Window *w; - FOR_ALL_WINDOWS_FROM_FRONT(w) { + for (Window *w : Window::IterateFromFront()) { if (w->viewport == nullptr) continue; ZoomLevel zoom = static_cast(Clamp(w->viewport->zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max)); diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index 56837c8798..a6d506b414 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -532,8 +532,7 @@ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int butt */ int HideDropDownMenu(Window *pw) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->window_class != WC_DROPDOWN_MENU) continue; DropdownWindow *dw = dynamic_cast(w); diff --git a/src/window.cpp b/src/window.cpp index 186b13dd47..f39c3e31a4 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -891,8 +891,7 @@ static void DispatchMouseWheelEvent(Window *w, NWidgetCore *nwid, int wheel) */ void DrawOverlappedWindow(Window *w, int left, int top, int right, int bottom, DrawOverlappedWindowFlags flags) { - const Window *v; - FOR_ALL_WINDOWS_FROM_BACK_FROM(v, w->z_front) { + for (const Window *v : Window::IterateFromBack(w->z_front)) { if (MayBeShown(v) && right > v->left && bottom > v->top && @@ -959,13 +958,11 @@ void DrawOverlappedWindow(Window *w, int left, int top, int right, int bottom, D */ void DrawOverlappedWindowForAll(int left, int top, int right, int bottom) { - Window *w; - DrawPixelInfo *old_dpi = _cur_dpi; DrawPixelInfo bk; _cur_dpi = &bk; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (MayBeShown(w) && right > w->left && bottom > w->top && @@ -1077,8 +1074,7 @@ void Window::SetShaded(bool make_shaded) */ static Window *FindChildWindow(const Window *w, WindowClass wc) { - Window *v; - FOR_ALL_WINDOWS_FROM_BACK(v) { + for (Window *v : Window::IterateFromBack()) { if ((wc == WC_INVALID || wc == v->window_class) && v->parent == w) return v; } @@ -1152,8 +1148,7 @@ Window::~Window() */ Window *FindWindowById(WindowClass cls, WindowNumber number) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->window_class == cls && w->window_number == number) return w; } @@ -1168,8 +1163,7 @@ Window *FindWindowById(WindowClass cls, WindowNumber number) */ Window *FindWindowByClass(WindowClass cls) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->window_class == cls) return w; } @@ -1196,13 +1190,11 @@ void DeleteWindowById(WindowClass cls, WindowNumber number, bool force) */ void DeleteWindowByClass(WindowClass cls) { - Window *w; - restart_search: /* When we find the window to delete, we need to restart the search * as deleting this window could cascade in deleting (many) others * anywhere in the z-array */ - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->window_class == cls) { delete w; goto restart_search; @@ -1218,13 +1210,11 @@ restart_search: */ void DeleteCompanyWindows(CompanyID id) { - Window *w; - restart_search: /* When we find the window to delete, we need to restart the search * as deleting this window could cascade in deleting (many) others * anywhere in the z-array */ - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->owner == id) { delete w; goto restart_search; @@ -1244,8 +1234,7 @@ restart_search: */ void ChangeWindowOwner(Owner old_owner, Owner new_owner) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->owner != old_owner) continue; switch (w->window_class) { @@ -1617,8 +1606,7 @@ static bool IsGoodAutoPlace1(int left, int top, int width, int height, int toolb if (left < 0 || top < toolbar_y || right > _screen.width || bottom > _screen.height) return false; /* Make sure it is not obscured by any window. */ - const Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (const Window *w : Window::IterateFromBack()) { if (w->window_class == WC_MAIN_WINDOW) continue; if (right > w->left && @@ -1663,8 +1651,7 @@ static bool IsGoodAutoPlace2(int left, int top, int width, int height, int toolb if (top < toolbar_y || top > _screen.height - (height >> 2)) return false; /* Make sure it is not obscured by any window. */ - const Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (const Window *w : Window::IterateFromBack()) { if (w->window_class == WC_MAIN_WINDOW) continue; if (left + width > w->left && @@ -1701,8 +1688,7 @@ static Point GetAutoPlacePosition(int width, int height) * The new window must be entirely on-screen, and not overlap with an existing window. * Eight starting points are tried, two at each corner. */ - const Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (const Window *w : Window::IterateFromBack()) { if (w->window_class == WC_MAIN_WINDOW) continue; if (IsGoodAutoPlace1(w->left + w->width, w->top, width, height, toolbar_y, pt)) return pt; @@ -1719,7 +1705,7 @@ static Point GetAutoPlacePosition(int width, int height) * The new window may be partly off-screen, and must not overlap with an existing window. * Only four starting points are tried. */ - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (const Window *w : Window::IterateFromBack()) { if (w->window_class == WC_MAIN_WINDOW) continue; if (IsGoodAutoPlace2(w->left + w->width, w->top, width, height, toolbar_y, pt)) return pt; @@ -1736,7 +1722,7 @@ static Point GetAutoPlacePosition(int width, int height) int offset_y = std::max(NWidgetLeaf::closebox_dimension.height, FONT_HEIGHT_NORMAL + WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM); restart: - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (const Window *w : Window::IterateFromBack()) { if (w->left == left && w->top == top) { left += offset_x; top += offset_y; @@ -1903,8 +1889,7 @@ Window::Window(WindowDesc *desc) : window_desc(desc), mouse_capture_widget(-1) */ Window *FindWindowFromPt(int x, int y) { - Window *w; - FOR_ALL_WINDOWS_FROM_FRONT(w) { + for (Window *w : Window::IterateFromFront()) { if (MayBeShown(w) && IsInsideBS(x, w->left, w->width) && IsInsideBS(y, w->top, w->height)) { return w; } @@ -1942,8 +1927,7 @@ void UnInitWindowSystem() { UnshowCriticalError(); - Window *v; - FOR_ALL_WINDOWS_FROM_FRONT(v) delete v; + for (Window *w : Window::IterateFromFront()) delete w; for (WindowBase *w = _z_front_window; w != nullptr; /* nothing */) { WindowBase *to_del = w; @@ -1972,8 +1956,7 @@ static void DecreaseWindowCounters() if (_scroller_click_timeout != 0) _scroller_click_timeout--; if (hundredth_tick_timeout != 0) hundredth_tick_timeout--; - Window *w; - FOR_ALL_WINDOWS_FROM_FRONT(w) { + for (Window *w : Window::IterateFromFront()) { if (!_network_dedicated && hundredth_tick_timeout == 0) w->OnHundredthTick(); if (_scroller_click_timeout == 0) { @@ -1999,7 +1982,7 @@ static void DecreaseWindowCounters() w->OnMouseLoop(); } - FOR_ALL_WINDOWS_FROM_FRONT(w) { + for (Window *w : Window::IterateFromFront()) { if ((w->flags & WF_TIMEOUT) && --w->timeout_timer == 0) { CLRBITS(w->flags, WF_TIMEOUT); @@ -2246,8 +2229,7 @@ static EventState HandleWindowDragging() if (_left_button_down && _cursor.delta.x == 0 && _cursor.delta.y == 0) return ES_HANDLED; /* Otherwise find the window... */ - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->flags & WF_DRAGGING) { /* Stop the dragging if the left mouse button was released */ if (!_left_button_down) { @@ -2266,13 +2248,11 @@ static EventState HandleWindowDragging() int ny = y; if (_settings_client.gui.window_snap_radius != 0) { - const Window *v; - int hsnap = _settings_client.gui.window_snap_radius; int vsnap = _settings_client.gui.window_snap_radius; int delta; - FOR_ALL_WINDOWS_FROM_BACK(v) { + for (const Window *v : Window::IterateFromBack()) { if (v == w) continue; // Don't snap at yourself if (y + w->height > v->top && y < v->top + v->height) { @@ -2486,8 +2466,7 @@ static void HandleScrollbarScrolling(Window *w) */ static EventState HandleActiveWidget() { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->mouse_capture_widget >= 0) { /* Abort if no button is clicked any more. */ if (!_left_button_down) { @@ -2598,8 +2577,7 @@ static bool MaybeBringWindowToFront(Window *w) w_height = w->unshaded_size.height; } - Window *u; - FOR_ALL_WINDOWS_FROM_BACK_FROM(u, w->z_front) { + for (Window *u : Window::IterateFromBack(w->z_front)) { /* A modal child will prevent the activation of the parent window */ if (u->parent == w && (u->window_desc->flags & WDF_MODAL)) { u->SetWhiteBorder(); @@ -2757,8 +2735,7 @@ void HandleKeypress(uint keycode, WChar key) } /* Call the event, start with the uppermost window, but ignore the toolbar. */ - Window *w; - FOR_ALL_WINDOWS_FROM_FRONT(w) { + for (Window *w : Window::IterateFromFront()) { if (w->window_class == WC_MAIN_TOOLBAR) continue; if (w->window_desc->hotkeys != nullptr) { int hotkey = w->window_desc->hotkeys->CheckMatch(keycode); @@ -2767,7 +2744,7 @@ void HandleKeypress(uint keycode, WChar key) if (w->OnKeyPress(key, keycode) == ES_HANDLED) return; } - w = FindWindowById(WC_MAIN_TOOLBAR, 0); + Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0); /* When there is no toolbar w is null, check for that */ if (w != nullptr) { if (w->window_desc->hotkeys != nullptr) { @@ -2786,12 +2763,11 @@ void HandleKeypress(uint keycode, WChar key) void HandleCtrlChanged() { /* Call the event, start with the uppermost window. */ - Window *w; - FOR_ALL_WINDOWS_FROM_FRONT(w) { - if (w->OnCTRLStateChange() == ES_HANDLED) break; - w->OnCTRLStateChangeAlways(); - } - FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, w) { + bool handled = false; + for (Window *w : Window::IterateFromFront()) { + if (!handled && w->OnCTRLStateChange() == ES_HANDLED) { + handled = true; + } w->OnCTRLStateChangeAlways(); } } @@ -2801,8 +2777,7 @@ void HandleCtrlChanged() */ void HandleShiftChanged() { - Window *w; - FOR_ALL_WINDOWS_FROM_FRONT(w) { + for (Window *w : Window::IterateFromFront()) { w->OnShiftStateChange(); } } @@ -3144,8 +3119,8 @@ static void CheckSoftLimit() for (;;) { uint deletable_count = 0; - Window *w, *last_deletable = nullptr; - FOR_ALL_WINDOWS_FROM_FRONT(w) { + Window *last_deletable = nullptr; + for (Window *w : Window::IterateFromFront()) { if (w->window_class == WC_MAIN_WINDOW || IsVitalWindow(w) || (w->flags & WF_STICKY)) continue; last_deletable = w; @@ -3198,8 +3173,7 @@ void InputLoop() */ void CallWindowRealtimeTickEvent(uint delta_ms) { - Window *w; - FOR_ALL_WINDOWS_FROM_FRONT(w) { + for (Window *w : Window::IterateFromFront()) { w->OnRealtimeTick(delta_ms); } } @@ -3229,10 +3203,8 @@ void UpdateWindows() _window_update_number++; - Window *w; - /* Process invalidations before anything else. */ - FOR_ALL_WINDOWS_FROM_FRONT(w) { + for (Window *w : Window::IterateFromFront()) { w->ProcessScheduledInvalidations(); w->ProcessHighlightedInvalidations(); } @@ -3265,7 +3237,7 @@ void UpdateWindows() if (window_timer.HasElapsed()) { window_timer.SetInterval(MILLISECONDS_PER_TICK); - FOR_ALL_WINDOWS_FROM_FRONT(w) { + for (Window *w : Window::IterateFromFront()) { if ((w->flags & WF_WHITE_BORDER) && --w->white_border_timer == 0) { CLRBITS(w->flags, WF_WHITE_BORDER); w->SetDirty(); @@ -3275,7 +3247,7 @@ void UpdateWindows() DrawDirtyBlocks(); - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { /* Update viewport only if window is not shaded. */ if (w->viewport != nullptr && !w->IsShaded()) UpdateViewportPosition(w); } @@ -3293,8 +3265,7 @@ void UpdateWindows() */ void SetWindowDirty(WindowClass cls, WindowNumber number) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->window_class == cls && w->window_number == number) w->SetDirty(); } } @@ -3307,8 +3278,7 @@ void SetWindowDirty(WindowClass cls, WindowNumber number) */ void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, byte widget_index) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->window_class == cls && w->window_number == number) { w->SetWidgetDirty(widget_index); } @@ -3321,8 +3291,7 @@ void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, byte widget_inde */ void SetWindowClassesDirty(WindowClass cls) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->window_class == cls) w->SetDirty(); } } @@ -3396,8 +3365,7 @@ void Window::ProcessHighlightedInvalidations() */ void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->window_class == cls && w->window_number == number) { w->InvalidateData(data, gui_scope); } @@ -3414,9 +3382,7 @@ void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool g */ void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope) { - Window *w; - - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->window_class == cls) { w->InvalidateData(data, gui_scope); } @@ -3428,8 +3394,7 @@ void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope) */ void CallWindowGameTickEvent() { - Window *w; - FOR_ALL_WINDOWS_FROM_FRONT(w) { + for (Window *w : Window::IterateFromFront()) { w->OnGameTick(); } } @@ -3442,13 +3407,11 @@ void CallWindowGameTickEvent() */ void DeleteNonVitalWindows() { - Window *w; - restart_search: /* When we find the window to delete, we need to restart the search * as deleting this window could cascade in deleting (many) others * anywhere in the z-array */ - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (const Window *w : Window::IterateFromBack()) { if (w->window_class != WC_MAIN_WINDOW && w->window_class != WC_SELECT_GAME && w->window_class != WC_MAIN_TOOLBAR && @@ -3471,8 +3434,6 @@ restart_search: */ void DeleteAllNonVitalWindows() { - Window *w; - /* Delete every window except for stickied ones, then sticky ones as well */ DeleteNonVitalWindows(); @@ -3480,7 +3441,7 @@ restart_search: /* When we find the window to delete, we need to restart the search * as deleting this window could cascade in deleting (many) others * anywhere in the z-array */ - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (const Window *w : Window::IterateFromBack()) { if (w->flags & WF_STICKY) { delete w; goto restart_search; @@ -3505,13 +3466,11 @@ void DeleteAllMessages() */ void DeleteConstructionWindows() { - Window *w; - restart_search: /* When we find the window to delete, we need to restart the search * as deleting this window could cascade in deleting (many) others * anywhere in the z-array */ - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (const Window *w : Window::IterateFromBack()) { if (w->window_desc->flags & WDF_CONSTRUCTION) { delete w; goto restart_search; @@ -3535,8 +3494,7 @@ void ReInitAllWindows() extern void InitDepotWindowBlockSizes(); InitDepotWindowBlockSizes(); - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { w->ReInit(); } @@ -3625,8 +3583,7 @@ int PositionNetworkChatWindow(Window *w) */ void ChangeVehicleViewports(VehicleID from_index, VehicleID to_index) { - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { if (w->viewport != nullptr && w->viewport->follow_vehicle == from_index) { w->viewport->follow_vehicle = to_index; w->SetDirty(); @@ -3644,8 +3601,7 @@ void RelocateAllWindows(int neww, int newh) { DeleteWindowById(WC_DROPDOWN_MENU, 0); - Window *w; - FOR_ALL_WINDOWS_FROM_BACK(w) { + for (Window *w : Window::IterateFromBack()) { int left, top; /* XXX - this probably needs something more sane. For example specifying * in a 'backup'-desc that the window should always be centered. */ diff --git a/src/window_gui.h b/src/window_gui.h index c54a0f4c3b..a34bf0ff56 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -873,6 +873,71 @@ public: * @pre this->IsNewGRFInspectable() */ virtual void ShowNewGRFInspectWindow() const { NOT_REACHED(); } + + template + using window_base_t = std::conditional_t{}, WindowBase const, WindowBase>; + + /** + * Iterator to iterate all valid Windows + * @tparam T Type of the class/struct that is going to be iterated + * @tparam Tfront Wether we iterate from front + */ + template + struct WindowIterator { + typedef T value_type; + typedef T *pointer; + typedef T &reference; + typedef size_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + explicit WindowIterator(window_base_t *start) : w(start) + { + this->Validate(); + } + + bool operator==(const WindowIterator &other) const { return this->w == other.w; } + bool operator!=(const WindowIterator &other) const { return !(*this == other); } + T * operator*() const { return static_cast(this->w); } + WindowIterator & operator++() { this->Next(); this->Validate(); return *this; } + + private: + window_base_t *w; + void Validate() { while (this->w != nullptr && this->w->window_class == WC_INVALID) this->Next(); } + void Next() { if (this->w != nullptr) this->w = Tfront ? this->w->z_back : this->w->z_front; } + }; + + /** + * Iterable ensemble of all valid Windows + * @tparam T Type of the class/struct that is going to be iterated + * @tparam Tfront Wether we iterate from front + */ + template + struct Iterate { + Iterate(window_base_t *from) : from(from) {} + WindowIterator begin() { return WindowIterator(this->from); } + WindowIterator end() { return WindowIterator(nullptr); } + bool empty() { return this->begin() == this->end(); } + private: + window_base_t *from; + }; + + /** + * Returns an iterable ensemble of all valid Window from back to front + * @tparam T Type of the class/struct that is going to be iterated + * @param from index of the first Window to consider + * @return an iterable ensemble of all valid Window + */ + template + static Iterate IterateFromBack(window_base_t *from = _z_back_window) { return Iterate(from); } + + /** + * Returns an iterable ensemble of all valid Window from front to back + * @tparam T Type of the class/struct that is going to be iterated + * @param from index of the first Window to consider + * @return an iterable ensemble of all valid Window + */ + template + static Iterate IterateFromFront(window_base_t *from = _z_front_window) { return Iterate(from); } }; /** @@ -951,40 +1016,6 @@ void GuiShowTooltips(Window *parent, StringID str, uint paramcount = 0, const ui /* widget.cpp */ int GetWidgetFromPos(const Window *w, int x, int y); -inline const Window *FromBaseWindowFront(const WindowBase *w) -{ - while (w) { - if (w->window_class != WC_INVALID) return (const Window *) w; - w = w->z_front; - } - return nullptr; -} - -inline Window *FromBaseWindowFront(WindowBase *w) -{ - return const_cast(FromBaseWindowFront(const_cast(w))); -} - -inline const Window *FromBaseWindowBack(const WindowBase *w) -{ - while (w) { - if (w->window_class != WC_INVALID) return (const Window *) w; - w = w->z_back; - } - return nullptr; -} - -inline Window *FromBaseWindowBack(WindowBase *w) -{ - return const_cast(FromBaseWindowBack(const_cast(w))); -} - -/** Iterate over all windows */ -#define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = FromBaseWindowFront(start); w != nullptr; w = FromBaseWindowFront(w->z_front)) -#define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = FromBaseWindowBack(start); w != nullptr; w = FromBaseWindowBack(w->z_back)) -#define FOR_ALL_WINDOWS_FROM_BACK(w) FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window) -#define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window) - extern Point _cursorpos_drag_start; extern int _scrollbar_start_pos;