Changeset ca2680d in mainline


Ignore:
Timestamp:
2022-03-07T21:07:02Z (2 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
96c6a00
Parents:
4583015
Message:

Rendering UI text with highlighted accelerators

Location:
uspace
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/uidemo/uidemo.c

    r4583015 rca2680d  
    539539        }
    540540
    541         rc = ui_menu_create(demo.mbar, "File", &demo.mfile);
     541        rc = ui_menu_create(demo.mbar, "~F~ile", &demo.mfile);
    542542        if (rc != EOK) {
    543543                printf("Error creating menu.\n");
     
    593593        ui_menu_entry_set_cb(mexit, uidemo_file_exit, (void *) &demo);
    594594
    595         rc = ui_menu_create(demo.mbar, "Edit", &demo.medit);
     595        rc = ui_menu_create(demo.mbar, "~E~dit", &demo.medit);
    596596        if (rc != EOK) {
    597597                printf("Error creating menu.\n");
     
    607607        ui_menu_entry_set_cb(mmodify, uidemo_edit_modify, (void *) &demo);
    608608
    609         rc = ui_menu_create(demo.mbar, "Preferences", &demo.mpreferences);
    610         if (rc != EOK) {
    611                 printf("Error creating menu.\n");
    612                 return rc;
    613         }
    614 
    615         rc = ui_menu_create(demo.mbar, "Help", &demo.mhelp);
     609        rc = ui_menu_create(demo.mbar, "~P~references", &demo.mpreferences);
     610        if (rc != EOK) {
     611                printf("Error creating menu.\n");
     612                return rc;
     613        }
     614
     615        rc = ui_menu_create(demo.mbar, "~H~elp", &demo.mhelp);
    616616        if (rc != EOK) {
    617617                printf("Error creating menu.\n");
  • uspace/lib/ui/include/types/ui/paint.h

    r4583015 rca2680d  
    3636#ifndef _UI_TYPES_PAINT_H
    3737#define _UI_TYPES_PAINT_H
     38
     39#include <gfx/color.h>
     40#include <gfx/font.h>
    3841
    3942/** Filled circle parts */
     
    8184} ui_box_style_t;
    8285
     86/** UI text formatting */
     87typedef struct {
     88        /** Text font */
     89        gfx_font_t *font;
     90        /** Standard color */
     91        gfx_color_t *color;
     92        /** Highlight color */
     93        gfx_color_t *hgl_color;
     94        /** Horizontal alignment */
     95        gfx_halign_t halign;
     96        /** Justification width (for gfx_halign_justify) */
     97        gfx_coord_t justify_width;
     98        /** Vertical alignment */
     99        gfx_valign_t valign;
     100} ui_text_fmt_t;
     101
    83102#endif
    84103
  • uspace/lib/ui/include/ui/paint.h

    r4583015 rca2680d  
    5959extern errno_t ui_paint_text_hbrace(ui_resource_t *, gfx_rect_t *,
    6060    ui_box_style_t, gfx_color_t *);
     61extern void ui_text_fmt_init(ui_text_fmt_t *);
     62extern gfx_coord_t ui_text_width(gfx_font_t *, const char *);
     63extern errno_t ui_paint_text(gfx_coord2_t *, ui_text_fmt_t *, const char *);
    6164
    6265#endif
  • uspace/lib/ui/private/resource.h

    r4583015 rca2680d  
    7777        /** Window text color */
    7878        gfx_color_t *wnd_text_color;
     79        /** Window text highlight color */
     80        gfx_color_t *wnd_text_hgl_color;
    7981        /** Window selected text color */
    8082        gfx_color_t *wnd_sel_text_color;
     83        /** Window selected text highlight color */
     84        gfx_color_t *wnd_sel_text_hgl_color;
    8185        /** Window selected text background color */
    8286        gfx_color_t *wnd_sel_text_bg_color;
  • uspace/lib/ui/src/menubar.c

    r4583015 rca2680d  
    150150{
    151151        ui_resource_t *res;
    152         gfx_text_fmt_t fmt;
     152        ui_text_fmt_t fmt;
    153153        gfx_coord2_t pos;
    154154        gfx_coord2_t tpos;
     
    184184        pos = mbar->rect.p0;
    185185
    186         gfx_text_fmt_init(&fmt);
     186        ui_text_fmt_init(&fmt);
    187187        fmt.font = res->font;
    188188        fmt.halign = gfx_halign_left;
     
    192192        while (menu != NULL) {
    193193                caption = ui_menu_caption(menu);
    194                 width = gfx_text_width(res->font, caption) + 2 * hpad;
     194                width = ui_text_width(res->font, caption) + 2 * hpad;
    195195                tpos.x = pos.x + hpad;
    196196                tpos.y = pos.y + vpad;
     
    202202                if (menu == mbar->selected) {
    203203                        fmt.color = res->wnd_sel_text_color;
     204                        fmt.hgl_color = res->wnd_sel_text_hgl_color;
    204205                        bg_color = res->wnd_sel_text_bg_color;
    205206                } else {
    206207                        fmt.color = res->wnd_text_color;
     208                        fmt.hgl_color = res->wnd_text_hgl_color;
    207209                        bg_color = res->wnd_face_color;
    208210                }
     
    216218                        goto error;
    217219
    218                 rc = gfx_puttext(&tpos, &fmt, caption);
     220                rc = ui_paint_text(&tpos, &fmt, caption);
    219221                if (rc != EOK)
    220222                        goto error;
     
    416418        while (menu != NULL) {
    417419                caption = ui_menu_caption(menu);
    418                 width = gfx_text_width(res->font, caption) + 2 * hpad;
     420                width = ui_text_width(res->font, caption) + 2 * hpad;
    419421
    420422                rect.p0 = pos;
     
    467469        while (cur != NULL) {
    468470                caption = ui_menu_caption(cur);
    469                 width = gfx_text_width(res->font, caption) + 2 * hpad;
     471                width = ui_text_width(res->font, caption) + 2 * hpad;
    470472
    471473                rect.p0 = pos;
  • uspace/lib/ui/src/paint.c

    r4583015 rca2680d  
    554554}
    555555
     556/** Initialize UI text formatting structure.
     557 *
     558 * UI text formatting structure must always be initialized using this function
     559 * first.
     560 *
     561 * @param fmt UI text formatting structure
     562 */
     563void ui_text_fmt_init(ui_text_fmt_t *fmt)
     564{
     565        memset(fmt, 0, sizeof(ui_text_fmt_t));
     566}
     567
     568/** Process text with '~' markup.
     569 *
     570 * Parse text with tilde markup into a list of strings. @a *rbuf is set
     571 * to point to a newly allocated buffer containing consecutive null-terminated
     572 * strings.
     573 *
     574 * Each part between two '~' becomes one string. '~~' is translated into
     575 * a literal '~' character. @a *endptr is set to point to the first character
     576 * beyond the end of the list.
     577 *
     578 * @param str String with tilde markup
     579 * @param rbuf Place to store pointer to newly allocated buffer.
     580 * @param endptr Place to store end pointer (just after last character)
     581 * @return EOK on success or an error code
     582 */
     583static int ui_text_process(const char *str, char **rbuf, char **endptr)
     584{
     585        const char *sp;
     586        char *dp;
     587        char *buf;
     588
     589        buf = malloc(str_size(str) + 1);
     590        if (buf == NULL)
     591                return ENOMEM;
     592
     593        /* Break down string into list of (non)highlighted parts */
     594        sp = str;
     595        dp = buf;
     596        while (*sp != '\0') {
     597                if (*sp == '~') {
     598                        if (sp[1] == '~') {
     599                                sp += 2;
     600                                *dp++ = '~';
     601                        } else {
     602                                ++sp;
     603                                *dp++ = '\0';
     604                        }
     605                } else {
     606                        *dp++ = *sp++;
     607                }
     608        }
     609
     610        *dp++ = '\0';
     611        *rbuf = buf;
     612        *endptr = dp;
     613
     614        return EOK;
     615}
     616
     617/** Compute UI text width.
     618 *
     619 * @param font Font
     620 * @param str String
     621 * @return Text width
     622 */
     623gfx_coord_t ui_text_width(gfx_font_t *font, const char *str)
     624{
     625        gfx_coord_t w;
     626        gfx_coord_t tw;
     627        const char *sp;
     628
     629        /* Text including tildes */
     630        w = gfx_text_width(font, str);
     631        tw = gfx_text_width(font, "~");
     632
     633        /* Subtract width of singular tildes */
     634        sp = str;
     635        while (*sp != '\0') {
     636                if (*sp == '~' && sp[1] != '~')
     637                        w -= tw;
     638                ++sp;
     639        }
     640
     641        return w;
     642}
     643
     644/** Paint text (with highlighting markup).
     645 *
     646 * Paint some text with highlighted sections enclosed with tilde characters
     647 * ('~'). A literal tilde can be printed with "~~". Text can be highlighted
     648 * with an underline or different color, based on display capabilities.
     649 *
     650 * @param pos Anchor position
     651 * @param fmt Text formatting
     652 * @param str String containing '~' markup
     653 *
     654 * @return EOK on success or an error code
     655 */
     656errno_t ui_paint_text(gfx_coord2_t *pos, ui_text_fmt_t *fmt, const char *str)
     657{
     658        gfx_coord2_t tpos;
     659        gfx_text_fmt_t tfmt;
     660        char *buf;
     661        char *endptr;
     662        const char *sp;
     663        errno_t rc;
     664
     665        /* Break down string into list of (non)highlighted parts */
     666        rc = ui_text_process(str, &buf, &endptr);
     667        if (rc != EOK)
     668                return rc;
     669
     670        gfx_text_fmt_init(&tfmt);
     671        tfmt.font = fmt->font;
     672        tfmt.color = fmt->color;
     673        tfmt.halign = fmt->halign;
     674        tfmt.justify_width = fmt->justify_width;
     675        tfmt.valign = fmt->valign;
     676        tfmt.underline = false;
     677
     678        tpos = *pos;
     679        sp = buf;
     680        while (sp != endptr) {
     681                /* Print the current string */
     682                rc = gfx_puttext(&tpos, &tfmt, sp);
     683                if (rc != EOK)
     684                        goto error;
     685
     686                gfx_text_cont(&tpos, &tfmt, sp, &tpos, &tfmt);
     687                tfmt.underline = !tfmt.underline;
     688                tfmt.color = tfmt.underline ? fmt->hgl_color : fmt->color;
     689
     690                /* Skip to the next string */
     691                while (*sp != '\0')
     692                        ++sp;
     693                ++sp;
     694        }
     695
     696        free(buf);
     697        return EOK;
     698error:
     699        free(buf);
     700        return rc;
     701}
     702
    556703/** @}
    557704 */
  • uspace/lib/ui/src/resource.c

    r4583015 rca2680d  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6767        gfx_color_t *wnd_face_color = NULL;
    6868        gfx_color_t *wnd_text_color = NULL;
     69        gfx_color_t *wnd_text_hgl_color = NULL;
    6970        gfx_color_t *wnd_sel_text_color = NULL;
     71        gfx_color_t *wnd_sel_text_hgl_color = NULL;
    7072        gfx_color_t *wnd_sel_text_bg_color = NULL;
    7173        gfx_color_t *wnd_frame_hi_color = NULL;
     
    131133                goto error;
    132134
     135        rc = gfx_color_new_rgb_i16(0, 0, 0, &wnd_text_hgl_color);
     136        if (rc != EOK)
     137                goto error;
     138
    133139        rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &wnd_sel_text_color);
     140        if (rc != EOK)
     141                goto error;
     142
     143        rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff,
     144            &wnd_sel_text_hgl_color);
    134145        if (rc != EOK)
    135146                goto error;
     
    210221        resource->wnd_face_color = wnd_face_color;
    211222        resource->wnd_text_color = wnd_text_color;
     223        resource->wnd_text_hgl_color = wnd_text_hgl_color;
    212224        resource->wnd_sel_text_color = wnd_sel_text_color;
     225        resource->wnd_sel_text_hgl_color = wnd_sel_text_hgl_color;
    213226        resource->wnd_sel_text_bg_color = wnd_sel_text_bg_color;
    214227        resource->wnd_frame_hi_color = wnd_frame_hi_color;
     
    246259        if (wnd_text_color != NULL)
    247260                gfx_color_delete(wnd_text_color);
     261        if (wnd_text_hgl_color != NULL)
     262                gfx_color_delete(wnd_text_hgl_color);
    248263        if (wnd_sel_text_color != NULL)
    249264                gfx_color_delete(wnd_sel_text_color);
     265        if (wnd_sel_text_hgl_color != NULL)
     266                gfx_color_delete(wnd_sel_text_hgl_color);
    250267        if (wnd_sel_text_bg_color != NULL)
    251268                gfx_color_delete(wnd_sel_text_bg_color);
     
    304321        gfx_color_t *wnd_face_color = NULL;
    305322        gfx_color_t *wnd_text_color = NULL;
     323        gfx_color_t *wnd_text_hgl_color = NULL;
    306324        gfx_color_t *wnd_sel_text_color = NULL;
     325        gfx_color_t *wnd_sel_text_hgl_color = NULL;
    307326        gfx_color_t *wnd_sel_text_bg_color = NULL;
    308327        gfx_color_t *wnd_frame_hi_color = NULL;
     
    362381                goto error;
    363382
     383        rc = gfx_color_new_ega(0x74, &wnd_text_hgl_color);
     384        if (rc != EOK)
     385                goto error;
     386
    364387        rc = gfx_color_new_ega(0x07, &wnd_sel_text_color);
     388        if (rc != EOK)
     389                goto error;
     390
     391        rc = gfx_color_new_ega(0x04, &wnd_sel_text_hgl_color);
    365392        if (rc != EOK)
    366393                goto error;
     
    435462        resource->wnd_face_color = wnd_face_color;
    436463        resource->wnd_text_color = wnd_text_color;
     464        resource->wnd_text_hgl_color = wnd_text_hgl_color;
    437465        resource->wnd_sel_text_color = wnd_sel_text_color;
     466        resource->wnd_sel_text_hgl_color = wnd_sel_text_hgl_color;
    438467        resource->wnd_sel_text_bg_color = wnd_sel_text_bg_color;
    439468        resource->wnd_frame_hi_color = wnd_frame_hi_color;
     
    471500        if (wnd_text_color != NULL)
    472501                gfx_color_delete(wnd_text_color);
     502        if (wnd_text_hgl_color != NULL)
     503                gfx_color_delete(wnd_text_hgl_color);
    473504        if (wnd_sel_text_color != NULL)
    474505                gfx_color_delete(wnd_sel_text_color);
     506        if (wnd_sel_text_hgl_color != NULL)
     507                gfx_color_delete(wnd_sel_text_hgl_color);
    475508        if (wnd_sel_text_bg_color != NULL)
    476509                gfx_color_delete(wnd_sel_text_bg_color);
Note: See TracChangeset for help on using the changeset viewer.