Changeset 46bd63c9 in mainline for uspace/lib/ui/src


Ignore:
Timestamp:
2023-09-08T08:47:30Z (23 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1af103e
Parents:
0b6fad9
git-author:
Jiri Svoboda <jiri@…> (2023-09-07 18:47:09)
git-committer:
Jiri Svoboda <jiri@…> (2023-09-08 08:47:30)
Message:

Split drop-down menu into two classes: drop-down and menu

Naming is clearly the hardest problem in computer science.

Location:
uspace/lib/ui/src
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ui/src/menu.c

    r0b6fad9 r46bd63c9  
    4444#include <str.h>
    4545#include <uchar.h>
     46#include <ui/ui.h>
    4647#include <ui/accel.h>
    4748#include <ui/control.h>
     
    4950#include <ui/popup.h>
    5051#include <ui/menu.h>
    51 #include <ui/menubar.h>
    5252#include <ui/menuentry.h>
    5353#include <ui/resource.h>
    5454#include <ui/window.h>
    55 #include "../private/menubar.h"
    5655#include "../private/menu.h"
    5756#include "../private/resource.h"
     
    7877/** Create new menu.
    7978 *
     79 * @param parent Parent window
    8080 * @param mbar Menu bar
    81  * @param caption Caption
    8281 * @param rmenu Place to store pointer to new menu
    8382 * @return EOK on success, ENOMEM if out of memory
    8483 */
    85 errno_t ui_menu_create(ui_menu_bar_t *mbar, const char *caption,
    86     ui_menu_t **rmenu)
     84errno_t ui_menu_create(ui_window_t *parent, ui_menu_t **rmenu)
    8785{
    8886        ui_menu_t *menu;
     
    9290                return ENOMEM;
    9391
    94         menu->caption = str_dup(caption);
    95         if (menu->caption == NULL) {
    96                 free(menu);
    97                 return ENOMEM;
    98         }
    99 
    100         menu->mbar = mbar;
    101         list_append(&menu->lmenus, &mbar->menus);
     92        menu->parent = parent;
    10293        list_initialize(&menu->entries);
    10394
     
    124115        }
    125116
    126         list_remove(&menu->lmenus);
    127117        free(menu->caption);
    128118        free(menu);
    129119}
    130120
    131 /** Get first menu in menu bar.
    132  *
    133  * @param mbar Menu bar
    134  * @return First menu or @c NULL if there is none
    135  */
    136 ui_menu_t *ui_menu_first(ui_menu_bar_t *mbar)
    137 {
    138         link_t *link;
    139 
    140         link = list_first(&mbar->menus);
    141         if (link == NULL)
    142                 return NULL;
    143 
    144         return list_get_instance(link, ui_menu_t, lmenus);
    145 }
    146 
    147 /** Get next menu in menu bar.
    148  *
    149  * @param cur Current menu
    150  * @return Next menu or @c NULL if @a cur is the last one
    151  */
    152 ui_menu_t *ui_menu_next(ui_menu_t *cur)
    153 {
    154         link_t *link;
    155 
    156         link = list_next(&cur->lmenus, &cur->mbar->menus);
    157         if (link == NULL)
    158                 return NULL;
    159 
    160         return list_get_instance(link, ui_menu_t, lmenus);
    161 }
    162 
    163 /** Get last menu in menu bar.
    164  *
    165  * @param mbar Menu bar
    166  * @return Last menu or @c NULL if there is none
    167  */
    168 ui_menu_t *ui_menu_last(ui_menu_bar_t *mbar)
    169 {
    170         link_t *link;
    171 
    172         link = list_last(&mbar->menus);
    173         if (link == NULL)
    174                 return NULL;
    175 
    176         return list_get_instance(link, ui_menu_t, lmenus);
    177 }
    178 
    179 /** Get previous menu in menu bar.
    180  *
    181  * @param cur Current menu
    182  * @return Previous menu or @c NULL if @a cur is the fist one
    183  */
    184 ui_menu_t *ui_menu_prev(ui_menu_t *cur)
    185 {
    186         link_t *link;
    187 
    188         link = list_prev(&cur->lmenus, &cur->mbar->menus);
    189         if (link == NULL)
    190                 return NULL;
    191 
    192         return list_get_instance(link, ui_menu_t, lmenus);
    193 }
    194 
    195 /** Get menu caption.
    196  *
    197  * @param menu Menu
    198  * @return Caption (owned by @a menu)
    199  */
    200 const char *ui_menu_caption(ui_menu_t *menu)
    201 {
    202         return menu->caption;
     121/** Set menu callbacks.
     122 *
     123 * @param menu Menu
     124 * @param cb Callbacks
     125 * @param arg Callback argument
     126 */
     127void ui_menu_set_cb(ui_menu_t *menu, ui_menu_cb_t *cb, void *arg)
     128{
     129        menu->cb = cb;
     130        menu->arg = arg;
    203131}
    204132
     
    212140    ui_menu_geom_t *geom)
    213141{
    214         ui_resource_t *res;
    215142        gfx_coord2_t edim;
    216143        gfx_coord_t frame_w;
    217144        gfx_coord_t frame_h;
    218 
    219         res = ui_window_get_res(menu->mbar->window);
     145        ui_resource_t *res;
     146
     147        res = ui_window_get_res(menu->parent);
    220148
    221149        if (res->textmode) {
     
    241169}
    242170
    243 /** Get menu rectangle.
    244  *
    245  * @param menu Menu
    246  * @param spos Starting position (top-left corner)
    247  * @param rect Place to store menu rectangle
    248  */
    249 void ui_menu_get_rect(ui_menu_t *menu, gfx_coord2_t *spos, gfx_rect_t *rect)
    250 {
    251         ui_menu_geom_t geom;
    252 
    253         ui_menu_get_geom(menu, spos, &geom);
    254         *rect = geom.outer_rect;
    255 }
    256 
    257 /** Get menu accelerator character.
    258  *
    259  * @param menu Menu
    260  * @return Accelerator character (lowercase) or the null character if
    261  *         the menu has no accelerator.
    262  */
    263 char32_t ui_menu_get_accel(ui_menu_t *menu)
    264 {
    265         return ui_accel_get(menu->caption);
    266 }
    267 
    268171/** Get UI resource from menu.
    269172 *
     
    304207        params.idev_id = idev_id;
    305208
    306         rc = ui_popup_create(menu->mbar->ui, menu->mbar->window, &params,
    307             &popup);
     209        rc = ui_popup_create(ui_window_get_ui(menu->parent), menu->parent,
     210            &params, &popup);
    308211        if (rc != EOK)
    309212                return rc;
     
    503406                /* Press outside menu - close it */
    504407                if (event->type == POS_PRESS)
    505                         ui_menu_bar_deactivate(menu->mbar);
     408                        ui_menu_close_req(menu);
    506409        }
    507410
     
    524427        if (event->type == KEY_PRESS && (event->mods & KM_ALT) != 0 &&
    525428            (event->mods & (KM_CTRL | KM_SHIFT)) == 0 && event->c != '\0')
    526                 ui_menu_bar_press_accel(menu->mbar, event->c, event->kbd_id);
     429                ui_menu_press_accel(menu, event->c, event->kbd_id);
    527430
    528431        return ui_claimed;
     
    615518        switch (event->key) {
    616519        case KC_ESCAPE:
    617                 ui_menu_bar_deactivate(menu->mbar);
     520                ui_menu_close_req(menu);
    618521                break;
    619522        case KC_LEFT:
    620                 ui_menu_bar_left(menu->mbar, event->kbd_id);
     523                ui_menu_left(menu, event->kbd_id);
    621524                break;
    622525        case KC_RIGHT:
    623                 ui_menu_bar_right(menu->mbar, event->kbd_id);
     526                ui_menu_right(menu, event->kbd_id);
    624527                break;
    625528        case KC_UP:
     
    658561        ui_menu_t *menu = (ui_menu_t *)arg;
    659562
    660         /* Deactivate menu bar, close menu */
    661         ui_menu_bar_deactivate(menu->mbar);
     563        /* Forward close request to caller */
     564        ui_menu_close_req(menu);
    662565}
    663566
     
    691594}
    692595
     596/** Send menu left event.
     597 *
     598 * @param menu Menu
     599 * @param idev_id Input device ID
     600 */
     601void ui_menu_left(ui_menu_t *menu, sysarg_t idev_id)
     602{
     603        if (menu->cb != NULL && menu->cb->left != NULL)
     604                menu->cb->left(menu, menu->arg, idev_id);
     605}
     606
     607/** Send menu right event.
     608 *
     609 * @param menu Menu
     610 * @param idev_id Input device ID
     611 */
     612void ui_menu_right(ui_menu_t *menu, sysarg_t idev_id)
     613{
     614        if (menu->cb != NULL && menu->cb->right != NULL)
     615                menu->cb->right(menu, menu->arg, idev_id);
     616}
     617
     618/** Send menu close request event.
     619 *
     620 * @param menu Menu
     621 */
     622void ui_menu_close_req(ui_menu_t *menu)
     623{
     624        if (menu->cb != NULL && menu->cb->close_req != NULL)
     625                menu->cb->close_req(menu, menu->arg);
     626}
     627
     628/** Send menu accelerator key press event.
     629 *
     630 * @param menu Menu
     631 * @param c Character
     632 * @param kbd_id Keyboard ID
     633 */
     634void ui_menu_press_accel(ui_menu_t *menu, char32_t c, sysarg_t kbd_id)
     635{
     636        if (menu->cb != NULL && menu->cb->press_accel != NULL)
     637                menu->cb->press_accel(menu, menu->arg, c, kbd_id);
     638}
     639
    693640/** @}
    694641 */
  • uspace/lib/ui/src/menubar.c

    r0b6fad9 r46bd63c9  
    4545#include <ui/control.h>
    4646#include <ui/paint.h>
    47 #include <ui/menu.h>
    4847#include <ui/menubar.h>
     48#include <ui/menudd.h>
    4949#include <ui/window.h>
    5050#include "../private/menubar.h"
     
    9595        mbar->ui = ui;
    9696        mbar->window = window;
    97         list_initialize(&mbar->menus);
     97        list_initialize(&mbar->menudds);
    9898        *rmbar = mbar;
    9999        return EOK;
     
    106106void ui_menu_bar_destroy(ui_menu_bar_t *mbar)
    107107{
    108         ui_menu_t *menu;
     108        ui_menu_dd_t *mdd;
    109109
    110110        if (mbar == NULL)
    111111                return;
    112112
    113         /* Destroy menus */
    114         menu = ui_menu_first(mbar);
    115         while (menu != NULL) {
    116                 ui_menu_destroy(menu);
    117                 menu = ui_menu_first(mbar);
     113        /* Destroy menu drop-downs */
     114        mdd = ui_menu_dd_first(mbar);
     115        while (mdd != NULL) {
     116                ui_menu_dd_destroy(mdd);
     117                mdd = ui_menu_dd_first(mbar);
    118118        }
    119119
     
    155155        gfx_rect_t rect;
    156156        gfx_color_t *bg_color;
    157         ui_menu_t *menu;
     157        ui_menu_dd_t *mdd;
    158158        const char *caption;
    159159        gfx_coord_t width;
     
    189189        fmt.valign = gfx_valign_top;
    190190
    191         menu = ui_menu_first(mbar);
    192         while (menu != NULL) {
    193                 caption = ui_menu_caption(menu);
     191        mdd = ui_menu_dd_first(mbar);
     192        while (mdd != NULL) {
     193                caption = ui_menu_dd_caption(mdd);
    194194                width = ui_text_width(res->font, caption) + 2 * hpad;
    195195                tpos.x = pos.x + hpad;
     
    200200                rect.p1.y = mbar->rect.p1.y;
    201201
    202                 if (menu == mbar->selected) {
     202                if (mdd == mbar->selected) {
    203203                        fmt.color = res->wnd_sel_text_color;
    204204                        fmt.hgl_color = res->wnd_sel_text_hgl_color;
     
    223223
    224224                pos.x += width;
    225                 menu = ui_menu_next(menu);
     225                mdd = ui_menu_dd_next(mdd);
    226226        }
    227227
     
    241241 *
    242242 * @param mbar Menu bar
    243  * @param menu Menu to select (or deselect if selected) or @c NULL
     243 * @param mdd Menu drop-down to select (or deselect if selected) or @c NULL
    244244 * @param openup Open menu even if not currently open
    245245 * @param idev_id Input device ID associated with the selecting seat
    246246 */
    247 void ui_menu_bar_select(ui_menu_bar_t *mbar, ui_menu_t *menu, bool openup,
     247void ui_menu_bar_select(ui_menu_bar_t *mbar, ui_menu_dd_t *mdd, bool openup,
    248248    sysarg_t idev_id)
    249249{
    250         ui_menu_t *old_menu;
     250        ui_menu_dd_t *old_mdd;
    251251        gfx_rect_t rect;
    252252        bool was_open;
    253253
    254         old_menu = mbar->selected;
    255 
    256         mbar->selected = menu;
    257 
    258         /* Close previously open menu */
    259         if (old_menu != NULL && ui_menu_is_open(old_menu)) {
     254        old_mdd = mbar->selected;
     255
     256        mbar->selected = mdd;
     257
     258        /* Close previously open menu drop-down */
     259        if (old_mdd != NULL && ui_menu_dd_is_open(old_mdd)) {
    260260                was_open = true;
    261                 (void) ui_menu_close(old_menu);
     261                (void) ui_menu_dd_close(old_mdd);
    262262        } else {
    263263                was_open = false;
     
    270270                if (openup || was_open) {
    271271                        /*
    272                          * Open the newly selected menu if either
    273                          * the old menu was open or @a openup was
     272                         * Open the newly selected menu drop-down if either
     273                         * the old menu drop-down was open or @a openup was
    274274                         * specified.
    275275                         */
    276                         (void) ui_menu_open(mbar->selected, &rect, idev_id);
     276                        (void) ui_menu_dd_open(mbar->selected, &rect, idev_id);
    277277                }
    278278        }
     
    289289void ui_menu_bar_left(ui_menu_bar_t *mbar, sysarg_t idev_id)
    290290{
    291         ui_menu_t *nmenu;
     291        ui_menu_dd_t *nmdd;
    292292
    293293        if (mbar->selected == NULL)
    294294                return;
    295295
    296         nmenu = ui_menu_prev(mbar->selected);
    297         if (nmenu == NULL)
    298                 nmenu = ui_menu_last(mbar);
    299 
    300         if (nmenu != mbar->selected)
    301                 ui_menu_bar_select(mbar, nmenu, false, idev_id);
     296        nmdd = ui_menu_dd_prev(mbar->selected);
     297        if (nmdd == NULL)
     298                nmdd = ui_menu_dd_last(mbar);
     299
     300        if (nmdd != mbar->selected)
     301                ui_menu_bar_select(mbar, nmdd, false, idev_id);
    302302}
    303303
     
    312312void ui_menu_bar_right(ui_menu_bar_t *mbar, sysarg_t idev_id)
    313313{
    314         ui_menu_t *nmenu;
     314        ui_menu_dd_t *nmdd;
    315315
    316316        if (mbar->selected == NULL)
    317317                return;
    318318
    319         nmenu = ui_menu_next(mbar->selected);
    320         if (nmenu == NULL)
    321                 nmenu = ui_menu_first(mbar);
    322 
    323         if (nmenu != mbar->selected)
    324                 ui_menu_bar_select(mbar, nmenu, false, idev_id);
     319        nmdd = ui_menu_dd_next(mbar->selected);
     320        if (nmdd == NULL)
     321                nmdd = ui_menu_dd_first(mbar);
     322
     323        if (nmdd != mbar->selected)
     324                ui_menu_bar_select(mbar, nmdd, false, idev_id);
    325325}
    326326
     
    355355
    356356        if (event->key == KC_ENTER || event->key == KC_DOWN) {
    357                 if (mbar->selected != NULL && !ui_menu_is_open(mbar->selected)) {
     357                if (mbar->selected != NULL &&
     358                    !ui_menu_dd_is_open(mbar->selected)) {
    358359                        ui_menu_bar_entry_rect(mbar, mbar->selected,
    359360                            &rect);
    360                         ui_menu_open(mbar->selected, &rect, event->kbd_id);
     361                        ui_menu_dd_open(mbar->selected, &rect, event->kbd_id);
    361362                }
    362363
     
    364365        }
    365366
    366         if (event->c != '\0' && !ui_menu_is_open(mbar->selected)) {
     367        if (event->c != '\0' && !ui_menu_dd_is_open(mbar->selected)) {
    367368                /* Check if it is an accelerator. */
    368369                ui_menu_bar_press_accel(mbar, event->c, event->kbd_id);
     
    407408void ui_menu_bar_press_accel(ui_menu_bar_t *mbar, char32_t c, sysarg_t kbd_id)
    408409{
    409         ui_menu_t *menu;
     410        ui_menu_dd_t *mdd;
    410411        char32_t maccel;
    411412
    412         menu = ui_menu_first(mbar);
    413         while (menu != NULL) {
    414                 maccel = ui_menu_get_accel(menu);
     413        mdd = ui_menu_dd_first(mbar);
     414        while (mdd != NULL) {
     415                maccel = ui_menu_dd_get_accel(mdd);
    415416                if (c == maccel) {
    416                         ui_menu_bar_select(mbar, menu, true, kbd_id);
     417                        ui_menu_bar_select(mbar, mdd, true, kbd_id);
    417418                        return;
    418419                }
    419420
    420                 menu = ui_menu_next(menu);
     421                mdd = ui_menu_dd_next(mdd);
    421422        }
    422423}
     
    433434        gfx_coord2_t pos;
    434435        gfx_rect_t rect;
    435         ui_menu_t *menu;
     436        ui_menu_dd_t *mdd;
    436437        const char *caption;
    437438        gfx_coord_t width;
     
    454455        pos_id = event->pos_id;
    455456
    456         menu = ui_menu_first(mbar);
    457         while (menu != NULL) {
    458                 caption = ui_menu_caption(menu);
     457        mdd = ui_menu_dd_first(mbar);
     458        while (mdd != NULL) {
     459                caption = ui_menu_dd_caption(mdd);
    459460                width = ui_text_width(res->font, caption) + 2 * hpad;
    460461
     
    469470
    470471                        /* Open the menu, close if already open. */
    471                         if (menu == mbar->selected)
     472                        if (mdd == mbar->selected)
    472473                                ui_menu_bar_select(mbar, NULL, false, pos_id);
    473474                        else
    474                                 ui_menu_bar_select(mbar, menu, true, pos_id);
     475                                ui_menu_bar_select(mbar, mdd, true, pos_id);
    475476
    476477                        return ui_claimed;
     
    478479
    479480                pos.x += width;
    480                 menu = ui_menu_next(menu);
     481                mdd = ui_menu_dd_next(mdd);
    481482        }
    482483
     
    487488 *
    488489 * @param mbar Menu bar
    489  * @param menu Menu whose entry's rectangle is to be returned
     490 * @param mdd Menu drop-down whose entry's rectangle is to be returned
    490491 * @param rrect Place to store entry rectangle
    491492 */
    492 void ui_menu_bar_entry_rect(ui_menu_bar_t *mbar, ui_menu_t *menu,
     493void ui_menu_bar_entry_rect(ui_menu_bar_t *mbar, ui_menu_dd_t *mdd,
    493494    gfx_rect_t *rrect)
    494495{
     
    496497        gfx_coord2_t pos;
    497498        gfx_rect_t rect;
    498         ui_menu_t *cur;
     499        ui_menu_dd_t *cur;
    499500        const char *caption;
    500501        gfx_coord_t width;
     
    511512        pos = mbar->rect.p0;
    512513
    513         cur = ui_menu_first(mbar);
     514        cur = ui_menu_dd_first(mbar);
    514515        while (cur != NULL) {
    515                 caption = ui_menu_caption(cur);
     516                caption = ui_menu_dd_caption(cur);
    516517                width = ui_text_width(res->font, caption) + 2 * hpad;
    517518
     
    520521                rect.p1.y = mbar->rect.p1.y;
    521522
    522                 if (cur == menu) {
     523                if (cur == mdd) {
    523524                        *rrect = rect;
    524525                        return;
     
    526527
    527528                pos.x += width;
    528                 cur = ui_menu_next(cur);
     529                cur = ui_menu_dd_next(cur);
    529530        }
    530531
     
    544545        mbar->active = true;
    545546        if (mbar->selected == NULL)
    546                 mbar->selected = ui_menu_first(mbar);
     547                mbar->selected = ui_menu_dd_first(mbar);
    547548
    548549        (void) ui_menu_bar_paint(mbar);
  • uspace/lib/ui/src/menuentry.c

    r0b6fad9 r46bd63c9  
    11/*
    2  * Copyright (c) 2022 Jiri Svoboda
     2 * Copyright (c) 2023 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    241241         * This needs to work even if the menu is not open, so we cannot
    242242         * use the menu's resource, which is only created after the menu
    243          * is open (and its window is created). Use the menu bar's
     243         * is open (and its window is created). Use the parent window's
    244244         * resource instead.
    245245         */
    246         res = ui_window_get_res(mentry->menu->mbar->window);
     246        res = ui_window_get_res(mentry->menu->parent);
    247247
    248248        *caption_w = ui_text_width(res->font, mentry->caption);
     
    267267         * This needs to work even if the menu is not open, so we cannot
    268268         * use the menu's resource, which is only created after the menu
    269          * is open (and its window is created). Use the menu bar's
     269         * is open (and its window is created). Use the parent window's
    270270         * resource instead.
    271271         */
    272         res = ui_window_get_res(menu->mbar->window);
     272        res = ui_window_get_res(menu->parent);
    273273
    274274        if (res->textmode)
     
    306306         * This needs to work even if the menu is not open, so we cannot
    307307         * use the menu's resource, which is only created after the menu
    308          * is open (and its window is created). Use the menu bar's
     308         * is open (and its window is created). Use the parent window's
    309309         * resource instead.
    310310         */
    311         res = ui_window_get_res(mentry->menu->mbar->window);
     311        res = ui_window_get_res(mentry->menu->parent);
    312312
    313313        if (res->textmode) {
     
    474474void ui_menu_entry_activate(ui_menu_entry_t *mentry)
    475475{
    476         /* Deactivate menu bar, close menu */
    477         ui_menu_bar_deactivate(mentry->menu->mbar);
     476        /* Close menu */
     477        ui_menu_close_req(mentry->menu);
    478478
    479479        /* Call back */
Note: See TracChangeset for help on using the changeset viewer.