diff --git a/src/widget.cpp b/src/widget.cpp index b3c53aeffa..613ce6a2cc 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -838,6 +838,13 @@ NWidgetBase::NWidgetBase(WidgetType tp) : ZeroedMemoryAllocator() * the smallest size such that all widgets of the window are consistent, and \e current_x and \e current_y contain the current size. */ +/** + * @fn void FillNestedArray(NWidgetCore **array, uint length) + * Fill the Window::nested_array array with pointers to nested widgets in the tree. + * @param array Base pointer of the array. + * @param length Length of the array. + */ + /** * Store size and position. * @param sizing Type of resizing to perform. @@ -971,6 +978,11 @@ int NWidgetCore::SetupSmallestSize() return this->index; } +void NWidgetCore::FillNestedArray(NWidgetCore **array, uint length) +{ + if (this->index >= 0 && (uint)(this->index) < length) array[this->index] = this; +} + void NWidgetCore::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl) { if (this->index < 0) return; @@ -1046,6 +1058,13 @@ void NWidgetContainer::Add(NWidgetBase *wid) } } +void NWidgetContainer::FillNestedArray(NWidgetCore **array, uint length) +{ + for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + child_wid->FillNestedArray(array, length); + } +} + /** * Return the biggest possible size of a nested widget. * @param base Base size of the widget. @@ -1419,6 +1438,10 @@ int NWidgetSpacer::SetupSmallestSize() return -1; } +void NWidgetSpacer::FillNestedArray(NWidgetCore **array, uint length) +{ +} + void NWidgetSpacer::StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl) { /* Spacer widgets are never stored in the widget array. */ @@ -1518,6 +1541,12 @@ void NWidgetBackground::StoreWidgets(Widget *widgets, int length, bool left_movi if (this->child != NULL) this->child->StoreWidgets(widgets, length, left_moving, top_moving, rtl); } +void NWidgetBackground::FillNestedArray(NWidgetCore **array, uint length) +{ + if (this->index >= 0 && (uint)(this->index) < length) array[this->index] = this; + if (this->child != NULL) this->child->FillNestedArray(array, length); +} + /** * Nested leaf widget. * @param tp Type of leaf widget. diff --git a/src/widget_type.h b/src/widget_type.h index 3ddc33de66..56fa5054f0 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -151,6 +151,9 @@ enum SizingType { ST_RESIZE, ///< Resize the nested widget tree. }; +/* Forward declarations. */ +class NWidgetCore; + /** * Baseclass for nested widgets. * @invariant After initialization, \f$current\_x = smallest\_x + n * resize\_x, for n \geq 0\f$. @@ -165,6 +168,7 @@ public: virtual void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl) = 0; virtual void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl) = 0; + virtual void FillNestedArray(NWidgetCore **array, uint length) = 0; /** * Set additional space (padding) around the widget. @@ -260,6 +264,7 @@ public: int SetupSmallestSize(); void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl); + /* virtual */ void FillNestedArray(NWidgetCore **array, uint length); Colours colour; ///< Colour of this widget. int index; ///< Index of the nested widget in the widget array of the window (\c -1 means 'not used'). @@ -275,6 +280,7 @@ public: ~NWidgetContainer(); void Add(NWidgetBase *wid); + /* virtual */ void FillNestedArray(NWidgetCore **array, uint length); /** Return whether the container is empty. */ inline bool IsEmpty() { return head == NULL; }; @@ -353,6 +359,7 @@ public: int SetupSmallestSize(); void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl); + /* virtual */ void FillNestedArray(NWidgetCore **array, uint length); }; /** Nested widget with a child. @@ -369,6 +376,8 @@ public: void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl); void StoreWidgets(Widget *widgets, int length, bool left_moving, bool top_moving, bool rtl); + /* virtual */ void FillNestedArray(NWidgetCore **array, uint length); + private: NWidgetPIPContainer *child; ///< Child widget. }; diff --git a/src/window.cpp b/src/window.cpp index 5fbaac72e8..d2a493fe21 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -563,6 +563,8 @@ Window::~Window() this->SetDirty(); free(this->widget); + free(this->nested_array); // Contents is released through deletion of #nested_root. + delete this->nested_root; this->window_class = WC_INVALID; } @@ -789,6 +791,8 @@ static void AssignWidgetToWindow(Window *w, const Widget *widget) void Window::Initialize(int x, int y, int min_width, int min_height, WindowClass cls, const Widget *widget, int window_number) { + /* All data members of nested widgets have been set to 0 by the #ZeroedMemoryAllocator base class. */ + /* Set up window properties */ this->window_class = cls; this->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border diff --git a/src/window_gui.h b/src/window_gui.h index 6f819cf286..5ff7bbaa4d 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -169,11 +169,14 @@ public: Owner owner; ///< The owner of the content shown in this window. Company colour is acquired from this variable. - ViewportData *viewport;///< Pointer to viewport data, if present - Widget *widget; ///< Widgets of the window - uint widget_count; ///< Number of widgets of the window - uint32 desc_flags; ///< Window/widgets default flags setting, @see WindowDefaultFlag - const Widget *focused_widget; ///< Currently focused widget or NULL, if no widget has focus + ViewportData *viewport; ///< Pointer to viewport data, if present. + Widget *widget; ///< Widgets of the window. + uint widget_count; ///< Number of widgets of the window. + uint32 desc_flags; ///< Window/widgets default flags setting. @see WindowDefaultFlag + const Widget *focused_widget; ///< Currently focused widget, or \c NULL if no widget has focus. + NWidgetBase *nested_root; ///< Root of the nested tree. + NWidgetCore **nested_array; ///< Array of pointers into the tree. + uint nested_array_size; ///< Size of the nested array. Window *parent; ///< Parent window Window *z_front; ///< The window in front of us in z-order