summaryrefslogtreecommitdiff
path: root/src/ui/labelwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/labelwidget.c')
-rw-r--r--src/ui/labelwidget.c101
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
484void updateSize_LabelWidget(iLabelWidget *d) { 497void 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
553void setText_LabelWidget(iLabelWidget *d, const iString *text) { 568void 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
561void setTextCStr_LabelWidget(iLabelWidget *d, const char *text) { 578void 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
608void setCheckMark_LabelWidget(iLabelWidget *d, iBool checkMark) {
609 d->flags.checkMark = checkMark;
610}
611
589void setWrap_LabelWidget(iLabelWidget *d, iBool wrap) { 612void 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
636void setTextOffset_LabelWidget(iLabelWidget *d, iInt2 offset) {
637 d->labelOffset = offset;
638}
639
613void updateText_LabelWidget(iLabelWidget *d, const iString *text) { 640void 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);