diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-04 22:24:26 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-04 22:24:43 +0200 |
commit | 35f60fa0da324ee79923d8a730cf4f10dbb6ccdb (patch) | |
tree | 3de80c1a65333a62e3cebedce339a9386f4ce8dc /src/ui/labelwidget.c | |
parent | 900b449a5dbe8cbf08c7ad54662b1c3067093356 (diff) |
LabelWidget: Added an optional icon
Label icons are intended for context menus.
Diffstat (limited to 'src/ui/labelwidget.c')
-rw-r--r-- | src/ui/labelwidget.c | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c index 87c33562..83deafe2 100644 --- a/src/ui/labelwidget.c +++ b/src/ui/labelwidget.c | |||
@@ -30,7 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
30 | 30 | ||
31 | iLocalDef iInt2 padding_(int64_t flags) { | 31 | iLocalDef iInt2 padding_(int64_t flags) { |
32 | #if defined (iPlatformAppleMobile) | 32 | #if defined (iPlatformAppleMobile) |
33 | return init_I2(flags & tight_WidgetFlag ? 4 * gap_UI / 2 : (4 * gap_UI), 3 * gap_UI / 2); | 33 | return init_I2(flags & tight_WidgetFlag ? 2 * gap_UI : (4 * gap_UI), |
34 | (flags & extraPadding_WidgetFlag ? 1.5f : 1) * 3 * gap_UI / 2); | ||
34 | #else | 35 | #else |
35 | return init_I2(flags & tight_WidgetFlag ? 3 * gap_UI / 2 : (3 * gap_UI), gap_UI); | 36 | return init_I2(flags & tight_WidgetFlag ? 3 * gap_UI / 2 : (3 * gap_UI), gap_UI); |
36 | #endif | 37 | #endif |
@@ -42,6 +43,7 @@ struct Impl_LabelWidget { | |||
42 | int font; | 43 | int font; |
43 | int key; | 44 | int key; |
44 | int kmods; | 45 | int kmods; |
46 | iChar icon; | ||
45 | int forceFg; | 47 | int forceFg; |
46 | iString command; | 48 | iString command; |
47 | iBool alignVisual; /* align according to visible bounds, not typography */ | 49 | iBool alignVisual; /* align according to visible bounds, not typography */ |
@@ -201,6 +203,10 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
201 | } | 203 | } |
202 | } | 204 | } |
203 | 205 | ||
206 | iLocalDef int iconPadding_LabelWidget_(const iLabelWidget *d) { | ||
207 | return d->icon ? iRound(lineHeight_Text(d->font) * 1.5f) : 0; | ||
208 | } | ||
209 | |||
204 | static void draw_LabelWidget_(const iLabelWidget *d) { | 210 | static void draw_LabelWidget_(const iLabelWidget *d) { |
205 | const iWidget *w = constAs_Widget(d); | 211 | const iWidget *w = constAs_Widget(d); |
206 | draw_Widget(w); | 212 | draw_Widget(w); |
@@ -208,6 +214,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
208 | const int64_t flags = flags_Widget(w); | 214 | const int64_t flags = flags_Widget(w); |
209 | const iRect bounds = bounds_Widget(w); | 215 | const iRect bounds = bounds_Widget(w); |
210 | iRect rect = bounds; | 216 | iRect rect = bounds; |
217 | const iBool isHover = isHover_Widget(w); | ||
211 | if (isButton) { | 218 | if (isButton) { |
212 | shrink_Rect(&rect, divi_I2(gap2_UI, 4)); | 219 | shrink_Rect(&rect, divi_I2(gap2_UI, 4)); |
213 | adjustEdges_Rect(&rect, gap_UI / 8, 0, -gap_UI / 8, 0); | 220 | adjustEdges_Rect(&rect, gap_UI / 8, 0, -gap_UI / 8, 0); |
@@ -228,17 +235,32 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
228 | }; | 235 | }; |
229 | drawLines_Paint(&p, points + 2, 3, frame2); | 236 | drawLines_Paint(&p, points + 2, 3, frame2); |
230 | drawLines_Paint( | 237 | drawLines_Paint( |
231 | &p, points, !isHover_Widget(w) && flags & noTopFrame_WidgetFlag ? 2 : 3, frame); | 238 | &p, points, !isHover && flags & noTopFrame_WidgetFlag ? 2 : 3, frame); |
232 | } | 239 | } |
233 | } | 240 | } |
234 | setClip_Paint(&p, rect); | 241 | setClip_Paint(&p, rect); |
242 | const int iconPad = iconPadding_LabelWidget_(d); | ||
243 | if (d->icon && d->icon != 0x20) { /* no need to draw an empty icon */ | ||
244 | iString str; | ||
245 | initUnicodeN_String(&str, &d->icon, 1); | ||
246 | drawCentered_Text(d->font, | ||
247 | (iRect){ addX_I2(add_I2(bounds.pos, padding_(flags)), -2 * gap_UI), | ||
248 | init_I2(iconPad, lineHeight_Text(d->font)) }, | ||
249 | iTrue, | ||
250 | flags & pressed_WidgetFlag ? fg | ||
251 | : isHover ? uiIconHover_ColorId | ||
252 | : uiIcon_ColorId, | ||
253 | "%s", | ||
254 | cstr_String(&str)); | ||
255 | deinit_String(&str); | ||
256 | } | ||
235 | if (flags & wrapText_WidgetFlag) { | 257 | if (flags & wrapText_WidgetFlag) { |
236 | const iRect inner = innerBounds_Widget(w); | 258 | const iRect inner = adjusted_Rect(innerBounds_Widget(w), init_I2(iconPad, 0), zero_I2()); |
237 | const int wrap = inner.size.x; | 259 | const int wrap = inner.size.x; |
238 | drawWrapRange_Text(d->font, topLeft_Rect(inner), wrap, fg, range_String(&d->label)); | 260 | drawWrapRange_Text(d->font, topLeft_Rect(inner), wrap, fg, range_String(&d->label)); |
239 | } | 261 | } |
240 | else if (flags & alignLeft_WidgetFlag) { | 262 | else if (flags & alignLeft_WidgetFlag) { |
241 | draw_Text(d->font, add_I2(bounds.pos, padding_(flags)), fg, cstr_String(&d->label)); | 263 | draw_Text(d->font, add_I2(bounds.pos, addX_I2(padding_(flags), iconPad)), fg, cstr_String(&d->label)); |
242 | if ((flags & drawKey_WidgetFlag) && d->key) { | 264 | if ((flags & drawKey_WidgetFlag) && d->key) { |
243 | iString str; | 265 | iString str; |
244 | init_String(&str); | 266 | init_String(&str); |
@@ -260,7 +282,11 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
260 | cstr_String(&d->label)); | 282 | cstr_String(&d->label)); |
261 | } | 283 | } |
262 | else { | 284 | else { |
263 | drawCentered_Text(d->font, bounds, d->alignVisual, fg, cstr_String(&d->label)); | 285 | drawCentered_Text(d->font, |
286 | adjusted_Rect(bounds, init_I2(iconPad, 0), zero_I2()), | ||
287 | d->alignVisual, | ||
288 | fg, | ||
289 | cstr_String(&d->label)); | ||
264 | } | 290 | } |
265 | unsetClip_Paint(&p); | 291 | unsetClip_Paint(&p); |
266 | } | 292 | } |
@@ -288,6 +314,7 @@ iInt2 defaultSize_LabelWidget(const iLabelWidget *d) { | |||
288 | size.x += 2 * gap_UI + measure_Text(uiShortcuts_FontId, cstr_String(&str)).x; | 314 | size.x += 2 * gap_UI + measure_Text(uiShortcuts_FontId, cstr_String(&str)).x; |
289 | deinit_String(&str); | 315 | deinit_String(&str); |
290 | } | 316 | } |
317 | size.x += iconPadding_LabelWidget_(d); | ||
291 | return size; | 318 | return size; |
292 | } | 319 | } |
293 | 320 | ||
@@ -312,6 +339,7 @@ void init_LabelWidget(iLabelWidget *d, const char *label, const char *cmd) { | |||
312 | init_Widget(&d->widget); | 339 | init_Widget(&d->widget); |
313 | d->font = uiLabel_FontId; | 340 | d->font = uiLabel_FontId; |
314 | d->forceFg = none_ColorId; | 341 | d->forceFg = none_ColorId; |
342 | d->icon = 0; | ||
315 | initCStr_String(&d->label, label); | 343 | initCStr_String(&d->label, label); |
316 | if (cmd) { | 344 | if (cmd) { |
317 | initCStr_String(&d->command, cmd); | 345 | initCStr_String(&d->command, cmd); |
@@ -374,6 +402,32 @@ void setCommand_LabelWidget(iLabelWidget *d, const iString *command) { | |||
374 | set_String(&d->command, command); | 402 | set_String(&d->command, command); |
375 | } | 403 | } |
376 | 404 | ||
405 | void setIcon_LabelWidget(iLabelWidget *d, iChar icon) { | ||
406 | if (d->icon != icon) { | ||
407 | d->icon = icon; | ||
408 | updateSize_LabelWidget(d); | ||
409 | } | ||
410 | } | ||
411 | |||
412 | iBool checkIcon_LabelWidget(iLabelWidget *d) { | ||
413 | if (!d->icon) { | ||
414 | iStringConstIterator iter; | ||
415 | init_StringConstIterator(&iter, &d->label); | ||
416 | const iChar icon = iter.value; | ||
417 | next_StringConstIterator(&iter); | ||
418 | if (iter.value == ' ' && icon >= 0x100) { | ||
419 | d->icon = icon; | ||
420 | remove_Block(&d->label.chars, 0, iter.next - constBegin_String(&d->label)); | ||
421 | return iTrue; | ||
422 | } | ||
423 | } | ||
424 | return iFalse; | ||
425 | } | ||
426 | |||
427 | iChar icon_LabelWidget(const iLabelWidget *d) { | ||
428 | return d->icon; | ||
429 | } | ||
430 | |||
377 | const iString *text_LabelWidget(const iLabelWidget *d) { | 431 | const iString *text_LabelWidget(const iLabelWidget *d) { |
378 | return &d->label; | 432 | return &d->label; |
379 | } | 433 | } |