From 657b6c84f04af788a42876dbd0173c2152f159f4 Mon Sep 17 00:00:00 2001 From: alberth Date: Fri, 26 Jun 2009 21:25:25 +0000 Subject: [PATCH] (svn r16670) -Codechange: Containers with equally sized children are useful to have. --- src/intro_gui.cpp | 12 ++++++------ src/widget.cpp | 45 ++++++++++++++++++++++++++++++++++----------- src/widget_type.h | 31 ++++++++++++++++++++++--------- 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/src/intro_gui.cpp b/src/intro_gui.cpp index 6b1ff57f7a..db5c560568 100644 --- a/src/intro_gui.cpp +++ b/src/intro_gui.cpp @@ -131,7 +131,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 8), /* 'generate game' and 'load game' buttons */ - NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(NWID_SPACER), SetMinimalSize(10, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_GENERATE_GAME), SetMinimalSize(158, 12), SetDataTip(STR_INTRO_NEW_GAME, STR_INTRO_TOOLTIP_NEW_GAME), @@ -143,7 +143,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 6), /* 'play scenario' and 'play heightmap' buttons */ - NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(NWID_SPACER), SetMinimalSize(10, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_PLAY_SCENARIO), SetMinimalSize(158, 12), SetDataTip(STR_INTRO_PLAY_SCENARIO, STR_INTRO_TOOLTIP_PLAY_SCENARIO), @@ -155,7 +155,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 6), /* 'edit scenario' and 'play multiplayer' buttons */ - NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(NWID_SPACER), SetMinimalSize(10, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_EDIT_SCENARIO), SetMinimalSize(158, 12), SetDataTip(STR_INTRO_SCENARIO_EDITOR, STR_INTRO_TOOLTIP_SCENARIO_EDITOR), @@ -185,7 +185,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 7), /* 'game options' and 'difficulty options' buttons */ - NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(NWID_SPACER), SetMinimalSize(10, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_OPTIONS), SetMinimalSize(158, 12), SetDataTip(STR_INTRO_GAME_OPTIONS, STR_INTRO_TOOLTIP_GAME_OPTIONS), @@ -197,7 +197,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 6), /* 'advanced settings' and 'newgrf settings' buttons */ - NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(NWID_SPACER), SetMinimalSize(10, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_SETTINGS_OPTIONS), SetMinimalSize(158, 12), SetDataTip(STR_CONFIG_SETTING, STR_CONFIG_SETTING_TIP), @@ -209,7 +209,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 6), /* 'online content' and 'ai settings' buttons */ - NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(NWID_SPACER), SetMinimalSize(10, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, SGI_CONTENT_DOWNLOAD), SetMinimalSize(158, 12), SetDataTip(STR_CONTENT_INTRO_BUTTON, STR_CONTENT_INTRO_BUTTON_TIP), diff --git a/src/widget.cpp b/src/widget.cpp index f937c401fb..dc8a3598e2 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -1340,8 +1340,9 @@ NWidgetCore *NWidgetStacked::GetWidgetFromPos(int x, int y) return NULL; } -NWidgetPIPContainer::NWidgetPIPContainer(WidgetType tp) : NWidgetContainer(tp) +NWidgetPIPContainer::NWidgetPIPContainer(WidgetType tp, NWidContainerFlags flags) : NWidgetContainer(tp) { + this->flags = flags; } /** @@ -1379,7 +1380,7 @@ NWidgetCore *NWidgetPIPContainer::GetWidgetFromPos(int x, int y) } /** Horizontal container widget. */ -NWidgetHorizontal::NWidgetHorizontal() : NWidgetPIPContainer(NWID_HORIZONTAL) +NWidgetHorizontal::NWidgetHorizontal(NWidContainerFlags flags) : NWidgetPIPContainer(NWID_HORIZONTAL, flags) { } @@ -1393,11 +1394,22 @@ int NWidgetHorizontal::SetupSmallestSize() this->resize_x = 0; // smallest non-zero child widget resize step. this->resize_y = 1; // smallest common child resize step - if (this->head != NULL) this->head->padding_left += this->pip_pre; + /* 1. Forward call, collect biggest nested array index, and longest child length. */ + uint longest = 0; // Longest child found. for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { int idx = child_wid->SetupSmallestSize(); biggest_index = max(biggest_index, idx); - + longest = max(longest, child_wid->smallest_x); + } + /* 2. For containers that must maintain equal width, extend child minimal size. */ + if (this->flags & NC_EQUALSIZE) { + for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + if (child_wid->fill_x) child_wid->smallest_x = longest; + } + } + /* 3. Move PIP space to the childs, compute smallest, fill, and resize values of the container. */ + if (this->head != NULL) this->head->padding_left += this->pip_pre; + for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { if (child_wid->next != NULL) { child_wid->padding_right += this->pip_inter; } else { @@ -1503,7 +1515,7 @@ void NWidgetHorizontal::StoreWidgets(Widget *widgets, int length, bool left_movi } /** Horizontal left-to-right container widget. */ -NWidgetHorizontalLTR::NWidgetHorizontalLTR() : NWidgetHorizontal() +NWidgetHorizontalLTR::NWidgetHorizontalLTR(NWidContainerFlags flags) : NWidgetHorizontal(flags) { this->type = NWID_HORIZONTAL_LTR; } @@ -1519,7 +1531,7 @@ void NWidgetHorizontalLTR::StoreWidgets(Widget *widgets, int length, bool left_m } /** Vertical container widget. */ -NWidgetVertical::NWidgetVertical() : NWidgetPIPContainer(NWID_VERTICAL) +NWidgetVertical::NWidgetVertical(NWidContainerFlags flags) : NWidgetPIPContainer(NWID_VERTICAL, flags) { } @@ -1533,11 +1545,22 @@ int NWidgetVertical::SetupSmallestSize() this->resize_x = 1; // smallest common child resize step this->resize_y = 0; // smallest non-zero child widget resize step. - if (this->head != NULL) this->head->padding_top += this->pip_pre; + /* 1. Forward call, collect biggest nested array index, and longest child length. */ + uint highest = 0; // Highest child found. for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { int idx = child_wid->SetupSmallestSize(); biggest_index = max(biggest_index, idx); - + highest = max(highest, child_wid->smallest_y); + } + /* 2. For containers that must maintain equal width, extend child minimal size. */ + if (this->flags & NC_EQUALSIZE) { + for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + if (child_wid->fill_y) child_wid->smallest_y = highest; + } + } + /* 3. Move PIP space to the childs, compute smallest, fill, and resize values of the container. */ + if (this->head != NULL) this->head->padding_top += this->pip_pre; + for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { if (child_wid->next != NULL) { child_wid->padding_bottom += this->pip_inter; } else { @@ -2173,13 +2196,13 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case NWID_HORIZONTAL: if (*dest != NULL) return num_used; - *dest = new NWidgetHorizontal(); + *dest = new NWidgetHorizontal(parts->u.cont_flags); *fill_dest = true; break; case NWID_HORIZONTAL_LTR: if (*dest != NULL) return num_used; - *dest = new NWidgetHorizontalLTR(); + *dest = new NWidgetHorizontalLTR(parts->u.cont_flags); *fill_dest = true; break; @@ -2193,7 +2216,7 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case NWID_VERTICAL: if (*dest != NULL) return num_used; - *dest = new NWidgetVertical(); + *dest = new NWidgetVertical(parts->u.cont_flags); *fill_dest = true; break; diff --git a/src/widget_type.h b/src/widget_type.h index b62e82d974..084f36be83 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -363,10 +363,19 @@ public: /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y); }; +/** Nested widget container flags, */ +enum NWidContainerFlags { + NCB_EQUALSIZE = 0, ///< Containers should keep all their (resizing) children equally large. + + NC_NONE = 0, ///< All flags cleared. + NC_EQUALSIZE = 1 << NCB_EQUALSIZE, ///< Value of the #NCB_EQUALSIZE flag. +}; +DECLARE_ENUM_AS_BIT_SET(NWidContainerFlags); + /** Container with pre/inter/post child space. */ class NWidgetPIPContainer : public NWidgetContainer { public: - NWidgetPIPContainer(WidgetType tp); + NWidgetPIPContainer(WidgetType tp, NWidContainerFlags flags = NC_NONE); void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post); @@ -374,16 +383,17 @@ public: /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y); protected: - uint8 pip_pre; ///< Amount of space before first widget. - uint8 pip_inter; ///< Amount of space between widgets. - uint8 pip_post; ///< Amount of space after last widget. + NWidContainerFlags flags; ///< Flags of the container. + uint8 pip_pre; ///< Amount of space before first widget. + uint8 pip_inter; ///< Amount of space between widgets. + uint8 pip_post; ///< Amount of space after last widget. }; /** Horizontal container. * @ingroup NestedWidgets */ class NWidgetHorizontal : public NWidgetPIPContainer { public: - NWidgetHorizontal(); + NWidgetHorizontal(NWidContainerFlags flags = NC_NONE); int SetupSmallestSize(); void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl); @@ -395,7 +405,7 @@ public: * @ingroup NestedWidgets */ class NWidgetHorizontalLTR : public NWidgetHorizontal { public: - NWidgetHorizontalLTR(); + NWidgetHorizontalLTR(NWidContainerFlags flags = NC_NONE); void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl); @@ -406,7 +416,7 @@ public: * @ingroup NestedWidgets */ class NWidgetVertical : public NWidgetPIPContainer { public: - NWidgetVertical(); + NWidgetVertical(NWidContainerFlags flags = NC_NONE); int SetupSmallestSize(); void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool allow_resize_x, bool allow_resize_y, bool rtl); @@ -561,6 +571,7 @@ struct NWidgetPart { NWidgetPartPaddings padding; ///< Part with paddings. NWidgetPartPIP pip; ///< Part with pre/inter/post spaces. NWidgetFunctionType *func_ptr; ///< Part with a function call. + NWidContainerFlags cont_flags; ///< Part with container flags. } u; }; @@ -763,14 +774,16 @@ static inline NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx) /** * Widget part function for starting a new horizontal container, vertical container, or spacer widget. - * @param tp Type of the new nested widget, #NWID_HORIZONTAL(_LTR), #NWID_VERTICAL, #NWID_SPACER, #NWID_SELECTION, or #NWID_LAYERED. + * @param tp Type of the new nested widget, #NWID_HORIZONTAL(_LTR), #NWID_VERTICAL, #NWID_SPACER, #NWID_SELECTION, or #NWID_LAYERED. + * @param cont_flags Flags for the containers (#NWID_HORIZONTAL(_LTR) and #NWID_VERTICAL). * @ingroup NestedWidgetParts */ -static inline NWidgetPart NWidget(WidgetType tp) +static inline NWidgetPart NWidget(WidgetType tp, NWidContainerFlags cont_flags = NC_NONE) { NWidgetPart part; part.type = tp; + part.u.cont_flags = cont_flags; return part; }