summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglx22 <glx@openttd.org>2021-04-28 21:24:24 +0200
committerLoïc Guilloux <glx22@users.noreply.github.com>2021-04-29 21:08:24 +0200
commit14e92bd8e241998ced263ee542965a71bbdd77a5 (patch)
tree08490feac7c2c15c97daee67dc3c1329fc703a95
parenta61696d6c565ff92c6604b12eefe36198d094056 (diff)
downloadopenttd-14e92bd8e241998ced263ee542965a71bbdd77a5.tar.xz
Codechange: Replace window related FOR_ALL with range-based for loops
-rw-r--r--src/misc_gui.cpp3
-rw-r--r--src/sound.cpp3
-rw-r--r--src/viewport.cpp11
-rw-r--r--src/widgets/dropdown.cpp3
-rw-r--r--src/window.cpp131
-rw-r--r--src/window_gui.h68
6 files changed, 113 insertions, 106 deletions
diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp
index 9be207ac6..b2de45140 100644
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -1284,8 +1284,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/sound.cpp b/src/sound.cpp
index 7d70fa760..d91476729 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -238,8 +238,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/viewport.cpp b/src/viewport.cpp
index aae659d53..303e02760 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -268,7 +268,7 @@ static Point _vp_move_offs;
static void DoSetViewportPosition(const Window *w, int left, int top, int width, int height)
{
- 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 &&
@@ -1475,8 +1475,7 @@ void ViewportSign::MarkDirty(ZoomLevel maxzoom) const
zoomlevels[zoom].bottom = this->top + ScaleByZoom(VPSM_TOP + FONT_HEIGHT_NORMAL + VPSM_BOTTOM + 1, zoom);
}
- Window *w;
- FOR_ALL_WINDOWS_FROM_BACK(w) {
+ for (const Window *w : Window::IterateFromBack()) {
Viewport *vp = w->viewport;
if (vp != nullptr && vp->zoom <= maxzoom) {
assert(vp->width != 0);
@@ -1949,8 +1948,7 @@ bool MarkAllViewportsDirty(int left, int top, int right, int bottom)
{
bool dirty = false;
- Window *w;
- FOR_ALL_WINDOWS_FROM_BACK(w) {
+ for (const Window *w : Window::IterateFromBack()) {
Viewport *vp = w->viewport;
if (vp != nullptr) {
assert(vp->width != 0);
@@ -1963,8 +1961,7 @@ bool MarkAllViewportsDirty(int left, int top, int right, int bottom)
void ConstrainAllViewportsZoom()
{
- Window *w;
- FOR_ALL_WINDOWS_FROM_FRONT(w) {
+ for (Window *w : Window::IterateFromFront()) {
if (w->viewport == nullptr) continue;
ZoomLevel zoom = static_cast<ZoomLevel>(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 6b1debb9d..f5536f52f 100644
--- a/src/widgets/dropdown.cpp
+++ b/src/widgets/dropdown.cpp
@@ -505,8 +505,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<DropdownWindow*>(w);
diff --git a/src/window.cpp b/src/window.cpp
index 2216fb241..a82afc7cd 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -898,8 +898,7 @@ static bool MayBeShown(const Window *w)
*/
static void DrawOverlappedWindow(Window *w, int left, int top, int right, int bottom)
{
- 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 &&
@@ -958,13 +957,11 @@ static void DrawOverlappedWindow(Window *w, int left, int top, int right, int bo
*/
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 &&
@@ -1057,8 +1054,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;
}
@@ -1132,8 +1128,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;
}
@@ -1148,8 +1143,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;
}
@@ -1176,13 +1170,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;
@@ -1198,13 +1190,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;
@@ -1224,8 +1214,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) {
@@ -1594,8 +1583,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 &&
@@ -1640,8 +1628,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 &&
@@ -1678,8 +1665,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;
@@ -1696,7 +1682,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;
@@ -1713,7 +1699,7 @@ static Point GetAutoPlacePosition(int width, int height)
int offset_y = std::max<int>(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;
@@ -1880,8 +1866,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;
}
@@ -1918,10 +1903,9 @@ void UnInitWindowSystem()
{
UnshowCriticalError();
- Window *w;
- FOR_ALL_WINDOWS_FROM_FRONT(w) delete w;
+ for (Window *w : Window::IterateFromFront()) delete w;
- for (w = _z_front_window; w != nullptr; /* nothing */) {
+ for (Window *w = _z_front_window; w != nullptr; /* nothing */) {
Window *to_del = w;
w = w->z_back;
free(to_del);
@@ -1948,8 +1932,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) {
@@ -1975,7 +1958,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);
@@ -2217,8 +2200,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) {
@@ -2234,13 +2216,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) {
@@ -2454,8 +2434,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) {
@@ -2565,8 +2544,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();
@@ -2708,8 +2686,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);
@@ -2718,7 +2695,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) {
@@ -2737,8 +2714,7 @@ void HandleKeypress(uint keycode, WChar key)
void HandleCtrlChanged()
{
/* Call the event, start with the uppermost window. */
- Window *w;
- FOR_ALL_WINDOWS_FROM_FRONT(w) {
+ for (Window *w : Window::IterateFromFront()) {
if (w->OnCTRLStateChange() == ES_HANDLED) return;
}
}
@@ -3073,8 +3049,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;
@@ -3127,8 +3103,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);
}
}
@@ -3156,10 +3131,8 @@ void UpdateWindows()
NetworkChatMessageLoop();
}
- Window *w;
-
/* Process invalidations before anything else. */
- FOR_ALL_WINDOWS_FROM_FRONT(w) {
+ for (Window *w : Window::IterateFromFront()) {
w->ProcessScheduledInvalidations();
w->ProcessHighlightedInvalidations();
}
@@ -3192,7 +3165,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();
@@ -3202,7 +3175,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);
}
@@ -3218,8 +3191,7 @@ void UpdateWindows()
*/
void SetWindowDirty(WindowClass cls, WindowNumber number)
{
- const Window *w;
- FOR_ALL_WINDOWS_FROM_BACK(w) {
+ for (const Window *w : Window::IterateFromBack()) {
if (w->window_class == cls && w->window_number == number) w->SetDirty();
}
}
@@ -3232,8 +3204,7 @@ void SetWindowDirty(WindowClass cls, WindowNumber number)
*/
void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, byte widget_index)
{
- const Window *w;
- FOR_ALL_WINDOWS_FROM_BACK(w) {
+ for (const Window *w : Window::IterateFromBack()) {
if (w->window_class == cls && w->window_number == number) {
w->SetWidgetDirty(widget_index);
}
@@ -3246,8 +3217,7 @@ void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, byte widget_inde
*/
void SetWindowClassesDirty(WindowClass cls)
{
- Window *w;
- FOR_ALL_WINDOWS_FROM_BACK(w) {
+ for (const Window *w : Window::IterateFromBack()) {
if (w->window_class == cls) w->SetDirty();
}
}
@@ -3319,8 +3289,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);
}
@@ -3337,9 +3306,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);
}
@@ -3351,8 +3318,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();
}
}
@@ -3365,13 +3331,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 &&
@@ -3394,8 +3358,6 @@ restart_search:
*/
void DeleteAllNonVitalWindows()
{
- Window *w;
-
/* Delete every window except for stickied ones, then sticky ones as well */
DeleteNonVitalWindows();
@@ -3403,7 +3365,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;
@@ -3428,20 +3390,18 @@ 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;
}
}
- FOR_ALL_WINDOWS_FROM_BACK(w) w->SetDirty();
+ for (const Window *w : Window::IterateFromBack()) w->SetDirty();
}
/** Delete all always on-top windows to get an empty screen */
@@ -3460,8 +3420,7 @@ void ReInitAllWindows()
extern void InitDepotWindowBlockSizes();
InitDepotWindowBlockSizes();
- Window *w;
- FOR_ALL_WINDOWS_FROM_BACK(w) {
+ for (Window *w : Window::IterateFromBack()) {
w->ReInit();
}
@@ -3550,8 +3509,7 @@ int PositionNetworkChatWindow(Window *w)
*/
void ChangeVehicleViewports(VehicleID from_index, VehicleID to_index)
{
- Window *w;
- FOR_ALL_WINDOWS_FROM_BACK(w) {
+ for (const Window *w : Window::IterateFromBack()) {
if (w->viewport != nullptr && w->viewport->follow_vehicle == from_index) {
w->viewport->follow_vehicle = to_index;
w->SetDirty();
@@ -3569,8 +3527,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 67a799c3d..66c867a54 100644
--- a/src/window_gui.h
+++ b/src/window_gui.h
@@ -810,6 +810,68 @@ public:
* @pre this->IsNewGRFInspectable()
*/
virtual void ShowNewGRFInspectWindow() const { NOT_REACHED(); }
+
+ /**
+ * 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 <class T, bool Tfront>
+ 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(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 this->w; }
+ WindowIterator & operator++() { this->Next(); this->Validate(); return *this; }
+
+ private:
+ 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 <class T, bool Tfront>
+ struct Iterate {
+ Iterate(T *from) : from(from) {}
+ WindowIterator<T, Tfront> begin() { return WindowIterator<T, Tfront>(this->from); }
+ WindowIterator<T, Tfront> end() { return WindowIterator<T, Tfront>(nullptr); }
+ bool empty() { return this->begin() == this->end(); }
+ private:
+ 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 <class T = Window>
+ static Iterate<T, false> IterateFromBack(T *from = _z_back_window) { return Iterate<T, false>(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 <class T = Window>
+ static Iterate<T, true> IterateFromFront(T *from = _z_front_window) { return Iterate<T, true>(from); }
};
/**
@@ -888,12 +950,6 @@ void GuiShowTooltips(Window *parent, StringID str, uint paramcount = 0, const ui
/* widget.cpp */
int GetWidgetFromPos(const Window *w, int x, int y);
-/** Iterate over all windows */
-#define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = start; w != nullptr; w = w->z_front) if (w->window_class != WC_INVALID)
-#define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != nullptr; w = w->z_back) if (w->window_class != WC_INVALID)
-#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;