summaryrefslogtreecommitdiff
path: root/src/ui/labelwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-03-04 22:24:26 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-03-04 22:24:43 +0200
commit35f60fa0da324ee79923d8a730cf4f10dbb6ccdb (patch)
tree3de80c1a65333a62e3cebedce339a9386f4ce8dc /src/ui/labelwidget.c
parent900b449a5dbe8cbf08c7ad54662b1c3067093356 (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.c64
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
31iLocalDef iInt2 padding_(int64_t flags) { 31iLocalDef 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
206iLocalDef int iconPadding_LabelWidget_(const iLabelWidget *d) {
207 return d->icon ? iRound(lineHeight_Text(d->font) * 1.5f) : 0;
208}
209
204static void draw_LabelWidget_(const iLabelWidget *d) { 210static 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
405void setIcon_LabelWidget(iLabelWidget *d, iChar icon) {
406 if (d->icon != icon) {
407 d->icon = icon;
408 updateSize_LabelWidget(d);
409 }
410}
411
412iBool 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
427iChar icon_LabelWidget(const iLabelWidget *d) {
428 return d->icon;
429}
430
377const iString *text_LabelWidget(const iLabelWidget *d) { 431const iString *text_LabelWidget(const iLabelWidget *d) {
378 return &d->label; 432 return &d->label;
379} 433}