summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/widget.cpp106
-rw-r--r--src/widget_type.h15
2 files changed, 72 insertions, 49 deletions
diff --git a/src/widget.cpp b/src/widget.cpp
index 2b8d11443..9238f8174 100644
--- a/src/widget.cpp
+++ b/src/widget.cpp
@@ -924,6 +924,35 @@ void NWidgetContainer::Add(NWidgetBase *wid)
}
/**
+ * Return the biggest possible size of a nested widget.
+ * @param base Base size of the widget.
+ * @param max_space Available space for the widget.
+ * @param step Stepsize of the widget.
+ * @return Biggest possible size of the widget, assuming that \a base may only be incremented by \a step size steps.
+ */
+static inline uint ComputeMaxSize(uint base, uint max_space, uint step)
+{
+ if (base >= max_space || step == 0) return base;
+ if (step == 1) return max_space;
+ int increment = max_space - base;
+ increment -= increment % step;
+ return base + increment;
+}
+
+/**
+ * Compute the offset of a widget due to not entirely using the available space.
+ * @param space Space used by the widget.
+ * @param max_space Available space for the widget.
+ * @return Offset for centering widget.
+ */
+static inline uint ComputeOffset(uint space, uint max_space)
+{
+ if (space >= max_space) return 0;
+ return (max_space - space) / 2;
+}
+
+
+/**
* Widgets stacked on top of each other.
* @param tp Kind of stacking, must be either #NWID_SELECTION or #NWID_LAYERED.
*/
@@ -967,27 +996,14 @@ void NWidgetStacked::AssignSizePosition(uint x, uint y, uint given_width, uint g
if (!allow_resize_y) this->resize_y = 0;
for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
- /* Decide about horizontal position and filling of the child. */
- uint child_width;
- int child_pos_x;
- if (child_wid->fill_x) {
- child_width = given_width - child_wid->padding_left - child_wid->padding_right;
- child_pos_x = (rtl ? child_wid->padding_right : child_wid->padding_left);
- } else {
- child_width = child_wid->smallest_x;
- child_pos_x = (given_width - child_wid->padding_left - child_wid->padding_right - child_width) / 2 + (rtl ? child_wid->padding_right : child_wid->padding_left);
- }
+ uint hor_step = child_wid->GetHorizontalStepSize();
+ uint child_width = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding_left - child_wid->padding_right, hor_step);
+ uint child_pos_x = (rtl ? child_wid->padding_right : child_wid->padding_left) + ComputeOffset(child_width, given_width - child_wid->padding_left - child_wid->padding_right);
+
+ uint vert_step = child_wid->GetVerticalStepSize();
+ uint child_height = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding_top - child_wid->padding_bottom, vert_step);
+ uint child_pos_y = child_wid->padding_top + ComputeOffset(child_height, given_height - child_wid->padding_top - child_wid->padding_bottom);
- /* Decide about vertical position and filling of the child. */
- uint child_height;
- int child_pos_y;
- if (child_wid->fill_y) {
- child_height = given_height - child_wid->padding_top - child_wid->padding_bottom;
- child_pos_y = 0;
- } else {
- child_height = child_wid->smallest_y;
- child_pos_y = (given_height - child_wid->padding_top - child_wid->padding_bottom - child_height) / 2;
- }
child_wid->AssignSizePosition(x + child_pos_x, y + child_pos_y, child_width, child_height, (this->resize_x > 0), (this->resize_y > 0), rtl);
}
}
@@ -1077,7 +1093,8 @@ void NWidgetHorizontal::AssignSizePosition(uint x, uint y, uint given_width, uin
int num_changing_childs = 0; // Number of childs that can change size.
NWidgetBase *child_wid;
for (child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
- if (child_wid->fill_x) num_changing_childs++;
+ uint hor_step = child_wid->GetHorizontalStepSize();
+ if (hor_step > 0) num_changing_childs++;
}
/* Fill and position the child widgets. */
@@ -1086,23 +1103,18 @@ void NWidgetHorizontal::AssignSizePosition(uint x, uint y, uint given_width, uin
child_wid = rtl ? this->tail : this->head;
while (child_wid != NULL) {
assert(given_height >= child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom);
- /* Decide about vertical filling of the child. */
- uint child_height; // Height of the child widget.
- uint child_pos_y; // Vertical position of child relative to the top of the container.
- if (child_wid->fill_y) {
- child_height = given_height - child_wid->padding_top - child_wid->padding_bottom;
- child_pos_y = child_wid->padding_top;
- } else {
- child_height = child_wid->smallest_y;
- child_pos_y = (given_height - child_wid->padding_top - child_wid->padding_bottom - child_height) / 2 + child_wid->padding_top;
- }
- /* Decide about horizontal filling of the child. */
- uint child_width;
- child_width = child_wid->smallest_x;
- if (child_wid->fill_x && num_changing_childs > 0) {
+ uint vert_step = child_wid->GetVerticalStepSize();
+ uint child_height = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding_top - child_wid->padding_bottom, vert_step);
+ uint child_pos_y = child_wid->padding_top + ComputeOffset(child_height, given_height - child_wid->padding_top - child_wid->padding_bottom);
+
+ /* Decide about horizontal sizing of the child. */
+ uint hor_step = child_wid->GetHorizontalStepSize();
+ uint child_width = child_wid->smallest_x;
+ if (hor_step > 0 && num_changing_childs > 0) {
/* Hand out a piece of the pie while compensating for rounding errors. */
uint increment = additional_length / num_changing_childs;
+ if (hor_step > 1) increment -= increment % hor_step;
additional_length -= increment;
num_changing_childs--;
@@ -1201,7 +1213,8 @@ void NWidgetVertical::AssignSizePosition(uint x, uint y, uint given_width, uint
/* count number of childs that would like a piece of the pie. */
int num_changing_childs = 0; // Number of childs that can change size.
for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
- if (child_wid->fill_y) num_changing_childs++;
+ uint vert_step = child_wid->GetVerticalStepSize();
+ if (vert_step > 0) num_changing_childs++;
}
/* Fill and position the child widgets. */
@@ -1209,23 +1222,18 @@ void NWidgetVertical::AssignSizePosition(uint x, uint y, uint given_width, uint
allow_resize_y = (this->resize_y > 0);
for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) {
assert(given_width >= child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right);
- /* Decide about horizontal filling of the child. */
- uint child_width; // Width of the child widget.
- uint child_pos_x; // Horizontal position of child relative to the left of the container.
- if (child_wid->fill_x) {
- child_width = given_width - child_wid->padding_left - child_wid->padding_right;
- child_pos_x = (rtl ? child_wid->padding_right : child_wid->padding_left);
- } else {
- child_width = child_wid->smallest_x;
- child_pos_x = (given_width - child_wid->padding_left - child_wid->padding_right - child_width) / 2 + (rtl ? child_wid->padding_right : child_wid->padding_left);
- }
+
+ uint hor_step = child_wid->GetHorizontalStepSize();
+ uint child_width = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding_left - child_wid->padding_right, hor_step);
+ uint child_pos_x = (rtl ? child_wid->padding_right : child_wid->padding_left) + ComputeOffset(child_width, given_width - child_wid->padding_left - child_wid->padding_right);
/* Decide about vertical filling of the child. */
- uint child_height;
- child_height = child_wid->smallest_y;
- if (child_wid->fill_y && num_changing_childs > 0) {
+ uint vert_step = child_wid->GetVerticalStepSize();
+ uint child_height = child_wid->smallest_y;
+ if (vert_step > 0 && num_changing_childs > 0) {
/* Hand out a piece of the pie while compensating for rounding errors. */
uint increment = additional_length / num_changing_childs;
+ if (vert_step > 1) increment -= increment % vert_step;
additional_length -= increment;
num_changing_childs--;
diff --git a/src/widget_type.h b/src/widget_type.h
index 4b49741bb..888d9052d 100644
--- a/src/widget_type.h
+++ b/src/widget_type.h
@@ -172,6 +172,9 @@ public:
this->padding_left = left;
};
+ inline uint GetHorizontalStepSize() const;
+ inline uint GetVerticalStepSize() const;
+
WidgetType type; ///< Type of the widget / nested widget.
bool fill_x; ///< Allow horizontal filling from initial size.
bool fill_y; ///< Allow vertical filling from initial size.
@@ -195,6 +198,18 @@ public:
uint8 padding_left; ///< Paddings added to the left of the widget. Managed by parent container widget.
};
+/** Get the horizontal sizing step. */
+inline uint NWidgetBase::GetHorizontalStepSize() const
+{
+ return this->fill_x ? 1 : 0;
+}
+
+/** Get the vertical sizing step. */
+inline uint NWidgetBase::GetVerticalStepSize() const
+{
+ return this->fill_y ? 1 : 0;
+}
+
/** Base class for a resizable nested widget.
* @ingroup NestedWidgets */
class NWidgetResizeBase : public NWidgetBase {