diff options
Diffstat (limited to 'src/ui/labelwidget.c')
-rw-r--r-- | src/ui/labelwidget.c | 101 |
1 files changed, 64 insertions, 37 deletions
diff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c index 1ff6d3b7..89e95c85 100644 --- a/src/ui/labelwidget.c +++ b/src/ui/labelwidget.c | |||
@@ -36,6 +36,7 @@ struct Impl_LabelWidget { | |||
36 | iWidget widget; | 36 | iWidget widget; |
37 | iString srcLabel; | 37 | iString srcLabel; |
38 | iString label; | 38 | iString label; |
39 | iInt2 labelOffset; | ||
39 | int font; | 40 | int font; |
40 | int key; | 41 | int key; |
41 | int kmods; | 42 | int kmods; |
@@ -44,14 +45,15 @@ struct Impl_LabelWidget { | |||
44 | iString command; | 45 | iString command; |
45 | iClick click; | 46 | iClick click; |
46 | struct { | 47 | struct { |
47 | uint8_t alignVisual : 1; /* align according to visible bounds, not font metrics */ | 48 | uint16_t alignVisual : 1; /* align according to visible bounds, not font metrics */ |
48 | uint8_t noAutoMinHeight : 1; /* minimum height is not set automatically */ | 49 | uint16_t noAutoMinHeight : 1; /* minimum height is not set automatically */ |
49 | uint8_t drawAsOutline : 1; /* draw as outline, filled with background color */ | 50 | uint16_t drawAsOutline : 1; /* draw as outline, filled with background color */ |
50 | uint8_t noTopFrame : 1; | 51 | uint16_t noTopFrame : 1; |
51 | uint8_t wrap : 1; | 52 | uint16_t wrap : 1; |
52 | uint8_t allCaps : 1; | 53 | uint16_t allCaps : 1; |
53 | uint8_t removeTrailingColon : 1; | 54 | uint16_t removeTrailingColon : 1; |
54 | uint8_t chevron : 1; | 55 | uint16_t chevron : 1; |
56 | uint16_t checkMark : 1; | ||
55 | } flags; | 57 | } flags; |
56 | }; | 58 | }; |
57 | 59 | ||
@@ -132,6 +134,10 @@ static iBool processEvent_LabelWidget_(iLabelWidget *d, const SDL_Event *ev) { | |||
132 | refresh_Widget(d); | 134 | refresh_Widget(d); |
133 | return iFalse; | 135 | return iFalse; |
134 | } | 136 | } |
137 | else if (isCommand_Widget(w, ev, "trigger")) { | ||
138 | trigger_LabelWidget_(d); | ||
139 | return iTrue; | ||
140 | } | ||
135 | if (!isEmpty_String(&d->command)) { | 141 | if (!isEmpty_String(&d->command)) { |
136 | #if 0 && defined (iPlatformAppleMobile) | 142 | #if 0 && defined (iPlatformAppleMobile) |
137 | /* Touch allows activating any button on release. */ | 143 | /* Touch allows activating any button on release. */ |
@@ -193,6 +199,7 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
193 | int *icon, int *meta) { | 199 | int *icon, int *meta) { |
194 | const iWidget *w = constAs_Widget(d); | 200 | const iWidget *w = constAs_Widget(d); |
195 | const int64_t flags = flags_Widget(w); | 201 | const int64_t flags = flags_Widget(w); |
202 | const iBool isHover = isHover_LabelWidget_(d); | ||
196 | const iBool isFocus = (flags & focusable_WidgetFlag && isFocused_Widget(d)); | 203 | const iBool isFocus = (flags & focusable_WidgetFlag && isFocused_Widget(d)); |
197 | const iBool isPress = (flags & pressed_WidgetFlag) != 0; | 204 | const iBool isPress = (flags & pressed_WidgetFlag) != 0; |
198 | const iBool isSel = (flags & selected_WidgetFlag) != 0; | 205 | const iBool isSel = (flags & selected_WidgetFlag) != 0; |
@@ -205,6 +212,9 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
205 | *bg = isButton && ~flags & noBackground_WidgetFlag ? (d->widget.bgColor != none_ColorId ? | 212 | *bg = isButton && ~flags & noBackground_WidgetFlag ? (d->widget.bgColor != none_ColorId ? |
206 | d->widget.bgColor : uiBackground_ColorId) | 213 | d->widget.bgColor : uiBackground_ColorId) |
207 | : none_ColorId; | 214 | : none_ColorId; |
215 | if (d->flags.checkMark) { | ||
216 | *bg = none_ColorId; | ||
217 | } | ||
208 | *fg = uiText_ColorId; | 218 | *fg = uiText_ColorId; |
209 | *frame1 = isButton ? uiEmboss1_ColorId : d->widget.frameColor; | 219 | *frame1 = isButton ? uiEmboss1_ColorId : d->widget.frameColor; |
210 | *frame2 = isButton ? uiEmboss2_ColorId : *frame1; | 220 | *frame2 = isButton ? uiEmboss2_ColorId : *frame1; |
@@ -216,18 +226,12 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
216 | *meta = uiTextDisabled_ColorId; | 226 | *meta = uiTextDisabled_ColorId; |
217 | } | 227 | } |
218 | if (isSel) { | 228 | if (isSel) { |
219 | if (isMenuItem) { | 229 | if (!d->flags.checkMark) { |
220 | *bg = uiBackgroundUnfocusedSelection_ColorId; | 230 | *bg = uiBackgroundSelected_ColorId; |
221 | } | 231 | if (!isKeyRoot) { |
222 | else { | 232 | *bg = isDark_ColorTheme(colorTheme_App()) ? uiBackgroundUnfocusedSelection_ColorId |
223 | *bg = uiBackgroundSelected_ColorId; | 233 | : uiMarked_ColorId; |
224 | } | 234 | } |
225 | // if (!isKeyRoot) { | ||
226 | // *bg = uiEmbossSelected1_ColorId; //uiBackgroundUnfocusedSelection_ColorId; | ||
227 | // } | ||
228 | if (!isKeyRoot) { | ||
229 | *bg = isDark_ColorTheme(colorTheme_App()) ? uiBackgroundUnfocusedSelection_ColorId | ||
230 | : uiMarked_ColorId ; | ||
231 | } | 235 | } |
232 | *fg = uiTextSelected_ColorId; | 236 | *fg = uiTextSelected_ColorId; |
233 | if (isButton) { | 237 | if (isButton) { |
@@ -248,7 +252,7 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
248 | if (colorEscape == uiTextCaution_ColorId) { | 252 | if (colorEscape == uiTextCaution_ColorId) { |
249 | *icon = *meta = colorEscape; | 253 | *icon = *meta = colorEscape; |
250 | } | 254 | } |
251 | if (isHover_LabelWidget_(d)) { | 255 | if (isHover) { |
252 | if (isFrameless) { | 256 | if (isFrameless) { |
253 | *bg = uiBackgroundFramelessHover_ColorId; | 257 | *bg = uiBackgroundFramelessHover_ColorId; |
254 | *fg = uiTextFramelessHover_ColorId; | 258 | *fg = uiTextFramelessHover_ColorId; |
@@ -274,7 +278,7 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
274 | } | 278 | } |
275 | } | 279 | } |
276 | if (d->forceFg >= 0) { | 280 | if (d->forceFg >= 0) { |
277 | *fg = /* *icon = */ *meta = d->forceFg; | 281 | *fg = *meta = d->forceFg; |
278 | } | 282 | } |
279 | if (isPress) { | 283 | if (isPress) { |
280 | if (colorEscape == uiTextAction_ColorId || colorEscape == uiTextCaution_ColorId) { | 284 | if (colorEscape == uiTextAction_ColorId || colorEscape == uiTextCaution_ColorId) { |
@@ -289,13 +293,12 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
289 | *frame1 = uiEmbossPressed1_ColorId; | 293 | *frame1 = uiEmbossPressed1_ColorId; |
290 | *frame2 = colorEscape != none_ColorId ? colorEscape : uiEmbossPressed2_ColorId; | 294 | *frame2 = colorEscape != none_ColorId ? colorEscape : uiEmbossPressed2_ColorId; |
291 | } | 295 | } |
292 | //if (colorEscape == none_ColorId || colorEscape == uiTextAction_ColorId) { | ||
293 | *fg = *icon = *meta = uiTextPressed_ColorId | permanent_ColorId; | 296 | *fg = *icon = *meta = uiTextPressed_ColorId | permanent_ColorId; |
294 | // } | ||
295 | // else { | ||
296 | // *fg = (isDark_ColorTheme(colorTheme_App()) ? white_ColorId : black_ColorId) | permanent_ColorId; | ||
297 | // } | ||
298 | } | 297 | } |
298 | } | ||
299 | if (((isSel || isHover) && isFrameless) || isPress) { | ||
300 | /* Ensure that the full label text remains readable. */ | ||
301 | *fg |= permanent_ColorId; | ||
299 | } | 302 | } |
300 | } | 303 | } |
301 | 304 | ||
@@ -328,6 +331,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
328 | init_Paint(&p); | 331 | init_Paint(&p); |
329 | int bg, fg, frame, frame2, iconColor, metaColor; | 332 | int bg, fg, frame, frame2, iconColor, metaColor; |
330 | getColors_LabelWidget_(d, &bg, &fg, &frame, &frame2, &iconColor, &metaColor); | 333 | getColors_LabelWidget_(d, &bg, &fg, &frame, &frame2, &iconColor, &metaColor); |
334 | setBaseAttributes_Text(d->font, fg); | ||
331 | const enum iColorId colorEscape = parseEscape_Color(cstr_String(&d->label), NULL); | 335 | const enum iColorId colorEscape = parseEscape_Color(cstr_String(&d->label), NULL); |
332 | const iBool isCaution = (colorEscape == uiTextCaution_ColorId); | 336 | const iBool isCaution = (colorEscape == uiTextCaution_ColorId); |
333 | if (bg >= 0) { | 337 | if (bg >= 0) { |
@@ -362,10 +366,6 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
362 | } | 366 | } |
363 | setClip_Paint(&p, rect); | 367 | setClip_Paint(&p, rect); |
364 | const int iconPad = iconPadding_LabelWidget_(d); | 368 | const int iconPad = iconPadding_LabelWidget_(d); |
365 | // const int iconColor = isCaution ? uiTextCaution_ColorId | ||
366 | // : flags & (disabled_WidgetFlag | pressed_WidgetFlag) ? fg | ||
367 | // : isHover ? uiIconHover_ColorId | ||
368 | // : uiIcon_ColorId; | ||
369 | if (d->icon && d->icon != 0x20) { /* no need to draw an empty icon */ | 369 | if (d->icon && d->icon != 0x20) { /* no need to draw an empty icon */ |
370 | iString str; | 370 | iString str; |
371 | initUnicodeN_String(&str, &d->icon, 1); | 371 | initUnicodeN_String(&str, &d->icon, 1); |
@@ -427,22 +427,35 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
427 | else { | 427 | else { |
428 | drawCenteredOutline_Text( | 428 | drawCenteredOutline_Text( |
429 | d->font, | 429 | d->font, |
430 | adjusted_Rect(bounds, init_I2(iconPad * (flags & tight_WidgetFlag ? 1.0f : 1.5f), 0), | 430 | moved_Rect( |
431 | adjusted_Rect(bounds, | ||
432 | init_I2(iconPad * (flags & tight_WidgetFlag ? 1.0f : 1.5f), 0), | ||
431 | init_I2(-iconPad * (flags & tight_WidgetFlag ? 0.5f : 1.0f), 0)), | 433 | init_I2(-iconPad * (flags & tight_WidgetFlag ? 0.5f : 1.0f), 0)), |
434 | d->labelOffset), | ||
432 | d->flags.alignVisual, | 435 | d->flags.alignVisual, |
433 | d->flags.drawAsOutline ? fg : none_ColorId, | 436 | d->flags.drawAsOutline ? fg : none_ColorId, |
434 | d->flags.drawAsOutline ? d->widget.bgColor : fg, | 437 | d->flags.drawAsOutline ? d->widget.bgColor : fg, |
435 | "%s", | 438 | "%s", |
436 | cstr_String(&d->label)); | 439 | cstr_String(&d->label)); |
437 | } | 440 | } |
438 | if (d->flags.chevron) { | 441 | if (d->flags.chevron || (flags & selected_WidgetFlag && d->flags.checkMark)) { |
439 | const iRect chRect = rect; | 442 | const iRect chRect = rect; |
440 | const int chSize = lineHeight_Text(d->font); | 443 | const int chSize = lineHeight_Text(d->font); |
444 | int offset = 0; | ||
445 | if (d->flags.chevron) { | ||
446 | offset = -iconPad; | ||
447 | } | ||
448 | else { | ||
449 | offset = -10 * gap_UI; | ||
450 | } | ||
441 | drawCentered_Text(d->font, | 451 | drawCentered_Text(d->font, |
442 | (iRect){ addX_I2(topRight_Rect(chRect), -iconPad), | 452 | (iRect){ addX_I2(topRight_Rect(chRect), offset), |
443 | init_I2(chSize, height_Rect(chRect)) }, | 453 | init_I2(chSize, height_Rect(chRect)) }, |
444 | iTrue, iconColor, rightAngle_Icon); | 454 | iTrue, |
455 | iconColor, | ||
456 | d->flags.chevron ? rightAngle_Icon : check_Icon); | ||
445 | } | 457 | } |
458 | setBaseAttributes_Text(-1, -1); | ||
446 | unsetClip_Paint(&p); | 459 | unsetClip_Paint(&p); |
447 | drawChildren_Widget(w); | 460 | drawChildren_Widget(w); |
448 | } | 461 | } |
@@ -482,9 +495,10 @@ int font_LabelWidget(const iLabelWidget *d) { | |||
482 | } | 495 | } |
483 | 496 | ||
484 | void updateSize_LabelWidget(iLabelWidget *d) { | 497 | void updateSize_LabelWidget(iLabelWidget *d) { |
485 | iWidget *w = as_Widget(d); | 498 | if (!d) return; |
499 | iWidget *w = as_Widget(d); | ||
486 | const int64_t flags = flags_Widget(w); | 500 | const int64_t flags = flags_Widget(w); |
487 | const iInt2 size = defaultSize_LabelWidget(d); | 501 | const iInt2 size = defaultSize_LabelWidget(d); |
488 | if (!d->flags.noAutoMinHeight) { | 502 | if (!d->flags.noAutoMinHeight) { |
489 | w->minSize.y = size.y; /* vertically text must remain visible */ | 503 | w->minSize.y = size.y; /* vertically text must remain visible */ |
490 | } | 504 | } |
@@ -514,6 +528,7 @@ void init_LabelWidget(iLabelWidget *d, const char *label, const char *cmd) { | |||
514 | d->font = uiLabel_FontId; | 528 | d->font = uiLabel_FontId; |
515 | d->forceFg = none_ColorId; | 529 | d->forceFg = none_ColorId; |
516 | d->icon = 0; | 530 | d->icon = 0; |
531 | d->labelOffset = zero_I2(); | ||
517 | initCStr_String(&d->srcLabel, label); | 532 | initCStr_String(&d->srcLabel, label); |
518 | initCopy_String(&d->label, &d->srcLabel); | 533 | initCopy_String(&d->label, &d->srcLabel); |
519 | replaceVariables_LabelWidget_(d); | 534 | replaceVariables_LabelWidget_(d); |
@@ -551,18 +566,22 @@ void setTextColor_LabelWidget(iLabelWidget *d, int color) { | |||
551 | } | 566 | } |
552 | 567 | ||
553 | void setText_LabelWidget(iLabelWidget *d, const iString *text) { | 568 | void setText_LabelWidget(iLabelWidget *d, const iString *text) { |
569 | if (d) { | ||
554 | updateText_LabelWidget(d, text); | 570 | updateText_LabelWidget(d, text); |
555 | updateSize_LabelWidget(d); | 571 | updateSize_LabelWidget(d); |
556 | if (isWrapped_LabelWidget(d)) { | 572 | if (isWrapped_LabelWidget(d)) { |
557 | sizeChanged_LabelWidget_(d); | 573 | sizeChanged_LabelWidget_(d); |
574 | } | ||
558 | } | 575 | } |
559 | } | 576 | } |
560 | 577 | ||
561 | void setTextCStr_LabelWidget(iLabelWidget *d, const char *text) { | 578 | void setTextCStr_LabelWidget(iLabelWidget *d, const char *text) { |
579 | if (d) { | ||
562 | updateTextCStr_LabelWidget(d, text); | 580 | updateTextCStr_LabelWidget(d, text); |
563 | updateSize_LabelWidget(d); | 581 | updateSize_LabelWidget(d); |
564 | if (isWrapped_LabelWidget(d)) { | 582 | if (isWrapped_LabelWidget(d)) { |
565 | sizeChanged_LabelWidget_(d); | 583 | sizeChanged_LabelWidget_(d); |
584 | } | ||
566 | } | 585 | } |
567 | } | 586 | } |
568 | 587 | ||
@@ -586,6 +605,10 @@ void setChevron_LabelWidget(iLabelWidget *d, iBool chevron) { | |||
586 | d->flags.chevron = chevron; | 605 | d->flags.chevron = chevron; |
587 | } | 606 | } |
588 | 607 | ||
608 | void setCheckMark_LabelWidget(iLabelWidget *d, iBool checkMark) { | ||
609 | d->flags.checkMark = checkMark; | ||
610 | } | ||
611 | |||
589 | void setWrap_LabelWidget(iLabelWidget *d, iBool wrap) { | 612 | void setWrap_LabelWidget(iLabelWidget *d, iBool wrap) { |
590 | d->flags.wrap = wrap; | 613 | d->flags.wrap = wrap; |
591 | } | 614 | } |
@@ -610,6 +633,10 @@ void setRemoveTrailingColon_LabelWidget(iLabelWidget *d, iBool removeTrailingCol | |||
610 | } | 633 | } |
611 | } | 634 | } |
612 | 635 | ||
636 | void setTextOffset_LabelWidget(iLabelWidget *d, iInt2 offset) { | ||
637 | d->labelOffset = offset; | ||
638 | } | ||
639 | |||
613 | void updateText_LabelWidget(iLabelWidget *d, const iString *text) { | 640 | void updateText_LabelWidget(iLabelWidget *d, const iString *text) { |
614 | set_String(&d->label, text); | 641 | set_String(&d->label, text); |
615 | set_String(&d->srcLabel, text); | 642 | set_String(&d->srcLabel, text); |