summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/labelwidget.c31
-rw-r--r--src/ui/widget.c27
-rw-r--r--src/ui/widget.h7
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
166static void draw_LabelWidget_(const iLabelWidget *d) { 166static 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
252static 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
246void init_LabelWidget(iLabelWidget *d, const char *label, int key, int kmods, const char *cmd) { 264void 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) {
312iBeginDefineSubclass(LabelWidget, Widget) 330iBeginDefineSubclass(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_,
315iEndDefineSubclass(LabelWidget) 334iEndDefineSubclass(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
68void releaseChildren_Widget(iWidget *d) {
69 iReleasePtr(&d->children);
70}
71
68iDefineObjectConstruction(Widget) 72iDefineObjectConstruction(Widget)
69 73
70void init_Widget(iWidget *d) { 74void init_Widget(iWidget *d) {
@@ -80,7 +84,7 @@ void init_Widget(iWidget *d) {
80} 84}
81 85
82void deinit_Widget(iWidget *d) { 86void 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) {
191static void setWidth_Widget_(iWidget *d, int width) { 195static 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
198static void setHeight_Widget_(iWidget *d, int height) { 212static 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)
41iBeginDeclareClass(Widget) 41iBeginDeclareClass(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 */
44iEndDeclareClass(Widget) 45iEndDeclareClass(Widget)
45 46
46enum iWidgetFlag { 47enum 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
89enum iWidgetAddPos { 91enum 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
134void destroy_Widget (iWidget *); /* widget removed and deleted later */ 136void destroy_Widget (iWidget *); /* widget removed and deleted later */
135void destroyPending_Widget(void); 137void destroyPending_Widget (void);
138void releaseChildren_Widget (iWidget *);
136 139
137const iString *id_Widget (const iWidget *); 140const iString *id_Widget (const iWidget *);
138int64_t flags_Widget (const iWidget *); 141int64_t flags_Widget (const iWidget *);