diff options
-rw-r--r-- | src/widget.cpp | 40 | ||||
-rw-r--r-- | src/widget_type.h | 2 | ||||
-rw-r--r-- | src/window.cpp | 23 |
3 files changed, 44 insertions, 21 deletions
diff --git a/src/widget.cpp b/src/widget.cpp index 5701cf434..b76008775 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -1724,3 +1724,43 @@ NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count) MakeWidgetTree(parts, count, cont); return cont; } + +/** + * Construct a #Widget array from a nested widget parts array, taking care of all the steps and checks. + * Also cache the result and use the cache if possible. + * @param[in] parts Array with parts of the widgets. + * @param parts_length Length of the \a parts array. + * @param[in] orig_wid Pointer to original widget array. + * @param wid_cache Pointer to the cache for storing the generated widget array (use \c NULL to prevent caching). + * @return Cached value if available, otherwise the generated widget array. If \a wid_cache is \c NULL, the caller should free the returned array. + * + * @pre Before the first call, \c *wid_cache should be \c NULL. + * @post The widget array stored in the \c *wid_cache should be free-ed by the caller. + */ +const Widget *InitializeWidgetArrayFromNestedWidgets(const NWidgetPart *parts, int parts_length, const Widget *orig_wid, Widget **wid_cache) +{ + const bool rtl = false; // Direction of the language is left-to-right + + if (wid_cache != NULL && *wid_cache != NULL) return *wid_cache; + + assert(parts != NULL && parts_length > 0); + NWidgetContainer *nwid = MakeNWidgets(parts, parts_length); + Widget *gen_wid = InitializeNWidgets(nwid, rtl); + + if (!rtl && orig_wid) { + /* There are two descriptions, compare them. + * Comparing only makes sense when using a left-to-right language. + */ + bool ok = CompareWidgetArrays(orig_wid, gen_wid, false); + if (ok) { + DEBUG(misc, 1, "Nested widgets are equal, min-size(%u, %u)", nwid->min_x, nwid->min_y); + } else { + DEBUG(misc, 0, "Nested widgets give different results"); + CompareWidgetArrays(orig_wid, gen_wid, true); + } + } + delete nwid; + + if (wid_cache != NULL) *wid_cache = gen_wid; + return gen_wid; +} diff --git a/src/widget_type.h b/src/widget_type.h index 1e4b657a1..af15e2bef 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -659,4 +659,6 @@ static inline NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr) NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count); +const Widget *InitializeWidgetArrayFromNestedWidgets(const NWidgetPart *parts, int parts_length, const Widget *orig_wid, Widget **wid_cache); + #endif /* WIDGET_TYPE_H */ diff --git a/src/window.cpp b/src/window.cpp index 22cae5e84..fa56189a5 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -75,28 +75,9 @@ WindowDesc::WindowDesc(int16 left, int16 top, int16 min_width, int16 min_height, /** Get widget array of the window description. */ const Widget *WindowDesc::GetWidgets() const { - const bool rtl = false; // Direction of the language is left-to-right - - /* If nested widgets are present, convert them to a widget array. */ - if (this->nwid_parts != NULL && nwid_length > 0 && this->new_widgets == NULL) { - NWidgetContainer *nwid = MakeNWidgets(this->nwid_parts, this->nwid_length); - this->new_widgets = InitializeNWidgets(nwid, rtl); - - if (!rtl && this->widgets != NULL) { - /* There are two descriptions, compare them. - * Comparing only makes sense when using a left-to-right language. - */ - bool ok = CompareWidgetArrays(this->widgets, this->new_widgets, false); - if (ok) { - DEBUG(misc, 1, "Nested widgets are equal, min-size(%u, %u)", nwid->min_x, nwid->min_y); - } else { - DEBUG(misc, 0, "Nested widgets give different results"); - CompareWidgetArrays(this->widgets, this->new_widgets, true); - } - } - delete nwid; + if (this->nwid_parts != NULL) { + InitializeWidgetArrayFromNestedWidgets(this->nwid_parts, this->nwid_length, this->widgets, &this->new_widgets); } - const Widget *wids = (this->new_widgets != NULL) ? this->new_widgets : this->widgets; assert(wids != NULL); return wids; |