diff options
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/labelwidget.c | 31 | ||||
-rw-r--r-- | src/ui/widget.c | 27 | ||||
-rw-r--r-- | src/ui/widget.h | 7 |
3 files changed, 53 insertions, 12 deletions
diff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c index f23091d8..0555bc4d 100644 --- a/src/ui/labelwidget.c +++ b/src/ui/labelwidget.c | |||
@@ -166,10 +166,10 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
166 | static void draw_LabelWidget_(const iLabelWidget *d) { | 166 | static void draw_LabelWidget_(const iLabelWidget *d) { |
167 | const iWidget *w = constAs_Widget(d); | 167 | const iWidget *w = constAs_Widget(d); |
168 | draw_Widget(w); | 168 | draw_Widget(w); |
169 | const iBool isButton = d->click.button != 0; | 169 | const iBool isButton = d->click.button != 0; |
170 | const int flags = flags_Widget(w); | 170 | const int64_t flags = flags_Widget(w); |
171 | const iRect bounds = bounds_Widget(w); | 171 | const iRect bounds = bounds_Widget(w); |
172 | iRect rect = bounds; | 172 | iRect rect = bounds; |
173 | if (isButton) { | 173 | if (isButton) { |
174 | shrink_Rect(&rect, divi_I2(gap2_UI, 4)); | 174 | shrink_Rect(&rect, divi_I2(gap2_UI, 4)); |
175 | adjustEdges_Rect(&rect, gap_UI / 8, 0, -gap_UI / 8, 0); | 175 | adjustEdges_Rect(&rect, gap_UI / 8, 0, -gap_UI / 8, 0); |
@@ -196,7 +196,12 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
196 | } | 196 | } |
197 | } | 197 | } |
198 | setClip_Paint(&p, rect); | 198 | setClip_Paint(&p, rect); |
199 | if (flags & alignLeft_WidgetFlag) { | 199 | if (flags & wrapText_WidgetFlag) { |
200 | const iRect inner = innerBounds_Widget(w); | ||
201 | const int wrap = inner.size.x; | ||
202 | drawWrapRange_Text(d->font, topLeft_Rect(inner), wrap, fg, range_String(&d->label)); | ||
203 | } | ||
204 | else if (flags & alignLeft_WidgetFlag) { | ||
200 | draw_Text(d->font, add_I2(bounds.pos, padding_(flags)), fg, cstr_String(&d->label)); | 205 | draw_Text(d->font, add_I2(bounds.pos, padding_(flags)), fg, cstr_String(&d->label)); |
201 | if ((flags & drawKey_WidgetFlag) && d->key) { | 206 | if ((flags & drawKey_WidgetFlag) && d->key) { |
202 | iString str; | 207 | iString str; |
@@ -235,7 +240,8 @@ void updateSize_LabelWidget(iLabelWidget *d) { | |||
235 | size.x += 2 * gap_UI + measure_Text(uiShortcuts_FontId, cstr_String(&str)).x; | 240 | size.x += 2 * gap_UI + measure_Text(uiShortcuts_FontId, cstr_String(&str)).x; |
236 | deinit_String(&str); | 241 | deinit_String(&str); |
237 | } | 242 | } |
238 | if (~flags & fixedWidth_WidgetFlag) { | 243 | /* Wrapped text implies that width must be defined by arrangement. */ |
244 | if (!(flags & (fixedWidth_WidgetFlag | wrapText_WidgetFlag))) { | ||
239 | w->rect.size.x = size.x; | 245 | w->rect.size.x = size.x; |
240 | } | 246 | } |
241 | if (~flags & fixedHeight_WidgetFlag) { | 247 | if (~flags & fixedHeight_WidgetFlag) { |
@@ -243,6 +249,18 @@ void updateSize_LabelWidget(iLabelWidget *d) { | |||
243 | } | 249 | } |
244 | } | 250 | } |
245 | 251 | ||
252 | static void sizeChanged_LabelWidget_(iLabelWidget *d) { | ||
253 | iWidget *w = as_Widget(d); | ||
254 | if (flags_Widget(w) & wrapText_WidgetFlag) { | ||
255 | if (flags_Widget(w) & fixedHeight_WidgetFlag) { | ||
256 | /* Calculate a new height based on the wrapping. */ | ||
257 | w->rect.size.y = advanceWrapRange_Text( | ||
258 | d->font, innerBounds_Widget(w).size.x, range_String(&d->label)) | ||
259 | .y; | ||
260 | } | ||
261 | } | ||
262 | } | ||
263 | |||
246 | void init_LabelWidget(iLabelWidget *d, const char *label, int key, int kmods, const char *cmd) { | 264 | void init_LabelWidget(iLabelWidget *d, const char *label, int key, int kmods, const char *cmd) { |
247 | init_Widget(&d->widget); | 265 | init_Widget(&d->widget); |
248 | d->font = uiLabel_FontId; | 266 | d->font = uiLabel_FontId; |
@@ -312,4 +330,5 @@ iLabelWidget *newColor_LabelWidget(const char *text, int color) { | |||
312 | iBeginDefineSubclass(LabelWidget, Widget) | 330 | iBeginDefineSubclass(LabelWidget, Widget) |
313 | .processEvent = (iAny *) processEvent_LabelWidget_, | 331 | .processEvent = (iAny *) processEvent_LabelWidget_, |
314 | .draw = (iAny *) draw_LabelWidget_, | 332 | .draw = (iAny *) draw_LabelWidget_, |
333 | .sizeChanged = (iAny *) sizeChanged_LabelWidget_, | ||
315 | iEndDefineSubclass(LabelWidget) | 334 | iEndDefineSubclass(LabelWidget) |
diff --git a/src/ui/widget.c b/src/ui/widget.c index ea2e3fe2..d10d73e1 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -65,6 +65,10 @@ void destroyPending_Widget(void) { | |||
65 | } | 65 | } |
66 | } | 66 | } |
67 | 67 | ||
68 | void releaseChildren_Widget(iWidget *d) { | ||
69 | iReleasePtr(&d->children); | ||
70 | } | ||
71 | |||
68 | iDefineObjectConstruction(Widget) | 72 | iDefineObjectConstruction(Widget) |
69 | 73 | ||
70 | void init_Widget(iWidget *d) { | 74 | void init_Widget(iWidget *d) { |
@@ -80,7 +84,7 @@ void init_Widget(iWidget *d) { | |||
80 | } | 84 | } |
81 | 85 | ||
82 | void deinit_Widget(iWidget *d) { | 86 | void deinit_Widget(iWidget *d) { |
83 | iReleasePtr(&d->children); | 87 | releaseChildren_Widget(d); |
84 | deinit_String(&d->id); | 88 | deinit_String(&d->id); |
85 | } | 89 | } |
86 | 90 | ||
@@ -191,14 +195,29 @@ static int widestChild_Widget_(const iWidget *d) { | |||
191 | static void setWidth_Widget_(iWidget *d, int width) { | 195 | static void setWidth_Widget_(iWidget *d, int width) { |
192 | iAssert(width >= 0); | 196 | iAssert(width >= 0); |
193 | if (~d->flags & fixedWidth_WidgetFlag || d->flags & collapse_WidgetFlag) { | 197 | if (~d->flags & fixedWidth_WidgetFlag || d->flags & collapse_WidgetFlag) { |
194 | d->rect.size.x = width; | 198 | if (d->rect.size.x != width) { |
199 | d->rect.size.x = width; | ||
200 | if (class_Widget(d)->sizeChanged) { | ||
201 | const int oldHeight = d->rect.size.y; | ||
202 | class_Widget(d)->sizeChanged(d); | ||
203 | if (d->rect.size.y != oldHeight) { | ||
204 | /* Widget updated its height. */ | ||
205 | arrange_Widget(d->parent); | ||
206 | } | ||
207 | } | ||
208 | } | ||
195 | } | 209 | } |
196 | } | 210 | } |
197 | 211 | ||
198 | static void setHeight_Widget_(iWidget *d, int height) { | 212 | static void setHeight_Widget_(iWidget *d, int height) { |
199 | iAssert(height >= 0); | 213 | iAssert(height >= 0); |
200 | if (~d->flags & fixedHeight_WidgetFlag || d->flags & collapse_WidgetFlag) { | 214 | if (~d->flags & fixedHeight_WidgetFlag || d->flags & collapse_WidgetFlag) { |
201 | d->rect.size.y = height; | 215 | if (d->rect.size.y != height) { |
216 | d->rect.size.y = height; | ||
217 | if (class_Widget(d)->sizeChanged) { | ||
218 | class_Widget(d)->sizeChanged(d); | ||
219 | } | ||
220 | } | ||
202 | } | 221 | } |
203 | } | 222 | } |
204 | 223 | ||
@@ -274,7 +293,7 @@ void arrange_Widget(iWidget *d) { | |||
274 | iWidget *child = as_Widget(c.object); | 293 | iWidget *child = as_Widget(c.object); |
275 | if (isCollapsed_Widget_(child)) { | 294 | if (isCollapsed_Widget_(child)) { |
276 | if (d->flags & arrangeHorizontal_WidgetFlag) { | 295 | if (d->flags & arrangeHorizontal_WidgetFlag) { |
277 | setWidth_Widget_(child, 0); | 296 | setWidth_Widget_(child, 0); |
278 | } | 297 | } |
279 | if (d->flags & arrangeVertical_WidgetFlag) { | 298 | if (d->flags & arrangeVertical_WidgetFlag) { |
280 | setHeight_Widget_(child, 0); | 299 | setHeight_Widget_(child, 0); |
diff --git a/src/ui/widget.h b/src/ui/widget.h index a1a38f28..fd7ee316 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h | |||
@@ -41,6 +41,7 @@ iDeclareType(Widget) | |||
41 | iBeginDeclareClass(Widget) | 41 | iBeginDeclareClass(Widget) |
42 | iBool (*processEvent) (iWidget *, const SDL_Event *); | 42 | iBool (*processEvent) (iWidget *, const SDL_Event *); |
43 | void (*draw) (const iWidget *); | 43 | void (*draw) (const iWidget *); |
44 | void (*sizeChanged) (iWidget *); /* optional, defaults to NULL */ | ||
44 | iEndDeclareClass(Widget) | 45 | iEndDeclareClass(Widget) |
45 | 46 | ||
46 | enum iWidgetFlag { | 47 | enum iWidgetFlag { |
@@ -85,6 +86,7 @@ enum iWidgetFlag { | |||
85 | #define wasCollapsed_WidgetFlag iBit64(32) | 86 | #define wasCollapsed_WidgetFlag iBit64(32) |
86 | #define centerHorizontal_WidgetFlag iBit64(33) | 87 | #define centerHorizontal_WidgetFlag iBit64(33) |
87 | #define moveToParentRightEdge_WidgetFlag iBit64(34) | 88 | #define moveToParentRightEdge_WidgetFlag iBit64(34) |
89 | #define wrapText_WidgetFlag iBit64(35) | ||
88 | 90 | ||
89 | enum iWidgetAddPos { | 91 | enum iWidgetAddPos { |
90 | back_WidgetAddPos, | 92 | back_WidgetAddPos, |
@@ -131,8 +133,9 @@ iLocalDef const iWidget *constAs_Widget(const iAnyObject *d) { | |||
131 | return (const iWidget *) d; | 133 | return (const iWidget *) d; |
132 | } | 134 | } |
133 | 135 | ||
134 | void destroy_Widget (iWidget *); /* widget removed and deleted later */ | 136 | void destroy_Widget (iWidget *); /* widget removed and deleted later */ |
135 | void destroyPending_Widget(void); | 137 | void destroyPending_Widget (void); |
138 | void releaseChildren_Widget (iWidget *); | ||
136 | 139 | ||
137 | const iString *id_Widget (const iWidget *); | 140 | const iString *id_Widget (const iWidget *); |
138 | int64_t flags_Widget (const iWidget *); | 141 | int64_t flags_Widget (const iWidget *); |