summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/widget.cpp19
-rw-r--r--src/widget_type.h15
2 files changed, 31 insertions, 3 deletions
diff --git a/src/widget.cpp b/src/widget.cpp
index a811da9c8..ed11aaf57 100644
--- a/src/widget.cpp
+++ b/src/widget.cpp
@@ -1400,13 +1400,15 @@ bool CompareWidgetArrays(const Widget *orig, const Widget *gen, bool report)
* @param parts Array with parts of the nested widget.
* @param count Length of the \a parts array.
* @param dest Address of pointer to use for returning the composed widget.
+ * @param fill_dest Fill the composed widget with child widgets.
* @return Number of widget part elements used to compose the widget.
*/
-static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest)
+static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, bool *fill_dest)
{
int num_used = 0;
*dest = NULL;
+ *fill_dest = false;
while (count > num_used) {
switch (parts->type) {
@@ -1418,11 +1420,13 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest)
case NWID_HORIZONTAL:
if (*dest != NULL) return num_used;
*dest = new NWidgetHorizontal();
+ *fill_dest = true;
break;
case NWID_HORIZONTAL_LTR:
if (*dest != NULL) return num_used;
*dest = new NWidgetHorizontalLTR();
+ *fill_dest = true;
break;
case WWT_PANEL:
@@ -1430,11 +1434,19 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest)
case WWT_FRAME:
if (*dest != NULL) return num_used;
*dest = new NWidgetBackground(parts->type, parts->u.widget.colour, parts->u.widget.index);
+ *fill_dest = true;
break;
case NWID_VERTICAL:
if (*dest != NULL) return num_used;
*dest = new NWidgetVertical();
+ *fill_dest = true;
+ break;
+
+ case WPT_FUNCTION:
+ if (*dest != NULL) return num_used;
+ *dest = parts->u.func_ptr();
+ *fill_dest = false;
break;
case WPT_RESIZE: {
@@ -1550,7 +1562,8 @@ static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase *pare
int total_used = 0;
while (true) {
NWidgetBase *sub_widget = NULL;
- int num_used = MakeNWidget(parts, count - total_used, &sub_widget);
+ bool fill_sub = false;
+ int num_used = MakeNWidget(parts, count - total_used, &sub_widget, &fill_sub);
parts += num_used;
total_used += num_used;
@@ -1563,7 +1576,7 @@ static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase *pare
/* If sub-widget is a container, recursively fill that container. */
WidgetType tp = sub_widget->type;
- if (tp == NWID_HORIZONTAL || tp == NWID_HORIZONTAL_LTR || tp == NWID_VERTICAL || tp == WWT_PANEL || tp == WWT_FRAME || tp == WWT_INSET) {
+ if (fill_sub && (tp == NWID_HORIZONTAL || tp == NWID_HORIZONTAL_LTR || tp == NWID_VERTICAL || tp == WWT_PANEL || tp == WWT_FRAME || tp == WWT_INSET)) {
int num_used = MakeWidgetTree(parts, count - total_used, sub_widget);
parts += num_used;
total_used += num_used;
diff --git a/src/widget_type.h b/src/widget_type.h
index 87cf2c87d..39ed87c2b 100644
--- a/src/widget_type.h
+++ b/src/widget_type.h
@@ -112,6 +112,7 @@ enum WidgetType {
WPT_PADDING, ///< Widget part for specifying a padding.
WPT_PIPSPACE, ///< Widget part for specifying pre/inter/post space for containers.
WPT_ENDCONTAINER, ///< Widget part to denote end of a container.
+ WPT_FUNCTION, ///< Widget part for calling a user function.
/* Pushable window widget types. */
WWT_MASK = 0x7F,
@@ -312,6 +313,9 @@ struct NWidgetPartPIP {
uint8 pre, inter, post; ///< Amount of space before/between/after child widgets.
};
+/** Pointer to function returning a nested widget. */
+typedef NWidgetBase *NWidgetFunctionType();
+
/** Partial widget specification to allow NWidgets to be written nested. */
struct NWidgetPart {
WidgetType type; ///< Type of the part. @see NWidgetPartType.
@@ -323,6 +327,7 @@ struct NWidgetPart {
NWidgetPartWidget widget; ///< Part with a start of a widget.
NWidgetPartPaddings padding; ///< Part with paddings.
NWidgetPartPIP pip; ///< Part with pre/inter/post spaces.
+ NWidgetFunctionType *func_ptr; ///< Part with a function call.
} u;
};
@@ -523,6 +528,16 @@ static inline NWidgetPart NWidget(WidgetType tp)
return part;
}
+static inline NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
+{
+ NWidgetPart part;
+
+ part.type = WPT_FUNCTION;
+ part.u.func_ptr = func_ptr;
+
+ return part;
+}
+
NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count);
#endif /* WIDGET_TYPE_H */