Changeset 59768c7 in mainline


Ignore:
Timestamp:
2022-01-10T19:29:00Z (2 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5de852c
Parents:
9754ed2
git-author:
Jiri Svoboda <jiri@…> (2022-01-10 19:27:55)
git-committer:
Jiri Svoboda <jiri@…> (2022-01-10 19:29:00)
Message:

Menu control using F10, cursor keys, Enter, Escape

Location:
uspace/lib/ui
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ui/include/ui/menu.h

    r9754ed2 r59768c7  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4040#include <gfx/coord.h>
    4141#include <io/pos_event.h>
     42#include <stdbool.h>
    4243#include <types/ui/menu.h>
    4344#include <types/ui/menubar.h>
     
    4849extern ui_menu_t *ui_menu_first(ui_menu_bar_t *);
    4950extern ui_menu_t *ui_menu_next(ui_menu_t *);
     51extern ui_menu_t *ui_menu_last(ui_menu_bar_t *);
     52extern ui_menu_t *ui_menu_prev(ui_menu_t *);
    5053extern const char *ui_menu_caption(ui_menu_t *);
    5154extern void ui_menu_get_rect(ui_menu_t *, gfx_coord2_t *, gfx_rect_t *);
    5255extern errno_t ui_menu_open(ui_menu_t *, gfx_rect_t *);
    5356extern void ui_menu_close(ui_menu_t *);
     57extern bool ui_menu_is_open(ui_menu_t *);
    5458extern errno_t ui_menu_paint(ui_menu_t *, gfx_coord2_t *);
    5559extern ui_evclaim_t ui_menu_pos_event(ui_menu_t *, gfx_coord2_t *,
  • uspace/lib/ui/include/ui/menubar.h

    r9754ed2 r59768c7  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5353extern void ui_menu_bar_set_rect(ui_menu_bar_t *, gfx_rect_t *);
    5454extern errno_t ui_menu_bar_paint(ui_menu_bar_t *);
     55extern ui_evclaim_t ui_menu_bar_kbd_event(ui_menu_bar_t *, kbd_event_t *);
    5556extern ui_evclaim_t ui_menu_bar_pos_event(ui_menu_bar_t *, pos_event_t *);
    5657extern void ui_menu_bar_unfocus(ui_menu_bar_t *);
     58extern void ui_menu_bar_activate(ui_menu_bar_t *);
     59extern void ui_menu_bar_deactivate(ui_menu_bar_t *);
    5760
    5861#endif
  • uspace/lib/ui/include/ui/menuentry.h

    r9754ed2 r59768c7  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4040#include <gfx/coord.h>
    4141#include <io/pos_event.h>
     42#include <stdbool.h>
    4243#include <types/ui/menu.h>
    4344#include <types/ui/menuentry.h>
     
    5152    void *);
    5253extern ui_menu_entry_t *ui_menu_entry_first(ui_menu_t *);
     54extern ui_menu_entry_t *ui_menu_entry_last(ui_menu_t *);
    5355extern ui_menu_entry_t *ui_menu_entry_next(ui_menu_entry_t *);
     56extern ui_menu_entry_t *ui_menu_entry_prev(ui_menu_entry_t *);
    5457extern gfx_coord_t ui_menu_entry_calc_width(ui_menu_t *,
    5558    gfx_coord_t, gfx_coord_t);
     
    5861extern gfx_coord_t ui_menu_entry_height(ui_menu_entry_t *);
    5962extern errno_t ui_menu_entry_paint(ui_menu_entry_t *, gfx_coord2_t *);
     63extern bool ui_menu_entry_selectable(ui_menu_entry_t *);
    6064extern void ui_menu_entry_press(ui_menu_entry_t *, gfx_coord2_t *);
    6165extern void ui_menu_entry_release(ui_menu_entry_t *);
    6266extern void ui_menu_entry_enter(ui_menu_entry_t *, gfx_coord2_t *);
    6367extern void ui_menu_entry_leave(ui_menu_entry_t *, gfx_coord2_t *);
     68extern void ui_menu_entry_activate(ui_menu_entry_t *);
    6469extern ui_evclaim_t ui_menu_entry_pos_event(ui_menu_entry_t *, gfx_coord2_t *,
    6570    pos_event_t *);
  • uspace/lib/ui/private/menu.h

    r9754ed2 r59768c7  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    8484extern errno_t ui_menu_paint_bg_gfx(ui_menu_t *, gfx_coord2_t *);
    8585extern errno_t ui_menu_paint_bg_text(ui_menu_t *, gfx_coord2_t *);
     86extern void ui_menu_up(ui_menu_t *);
     87extern void ui_menu_down(ui_menu_t *);
    8688
    8789#endif
  • uspace/lib/ui/private/menubar.h

    r9754ed2 r59768c7  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4040#include <adt/list.h>
    4141#include <gfx/coord.h>
     42#include <stdbool.h>
    4243#include <types/ui/menu.h>
    4344#include <types/ui/menubar.h>
     
    5657        /** Menu bar rectangle */
    5758        gfx_rect_t rect;
     59        /** Menu bar is active */
     60        bool active;
    5861        /** Selected menu or @c NULL */
    5962        struct ui_menu *selected;
     
    6265};
    6366
    64 extern void ui_menu_bar_select(ui_menu_bar_t *, gfx_rect_t *, ui_menu_t *);
     67extern void ui_menu_bar_select(ui_menu_bar_t *, ui_menu_t *, bool);
     68extern void ui_menu_bar_left(ui_menu_bar_t *);
     69extern void ui_menu_bar_right(ui_menu_bar_t *);
     70extern ui_evclaim_t ui_menu_bar_key_press_unmod(ui_menu_bar_t *, kbd_event_t *);
     71extern void ui_menu_bar_entry_rect(ui_menu_bar_t *, ui_menu_t *, gfx_rect_t *);
    6572
    6673#endif
  • uspace/lib/ui/src/menu.c

    r9754ed2 r59768c7  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4747#include <ui/popup.h>
    4848#include <ui/menu.h>
     49#include <ui/menubar.h>
    4950#include <ui/menuentry.h>
    5051#include <ui/resource.h>
     
    6364
    6465static void ui_menu_popup_close(ui_popup_t *, void *);
     66static void ui_menu_popup_kbd(ui_popup_t *, void *, kbd_event_t *);
    6567static void ui_menu_popup_pos(ui_popup_t *, void *, pos_event_t *);
    6668
    6769static ui_popup_cb_t ui_menu_popup_cb = {
    6870        .close = ui_menu_popup_close,
     71        .kbd = ui_menu_popup_kbd,
    6972        .pos = ui_menu_popup_pos
    7073};
     
    149152
    150153        link = list_next(&cur->lmenus, &cur->mbar->menus);
     154        if (link == NULL)
     155                return NULL;
     156
     157        return list_get_instance(link, ui_menu_t, lmenus);
     158}
     159
     160/** Get last menu in menu bar.
     161 *
     162 * @param mbar Menu bar
     163 * @return Last menu or @c NULL if there is none
     164 */
     165ui_menu_t *ui_menu_last(ui_menu_bar_t *mbar)
     166{
     167        link_t *link;
     168
     169        link = list_last(&mbar->menus);
     170        if (link == NULL)
     171                return NULL;
     172
     173        return list_get_instance(link, ui_menu_t, lmenus);
     174}
     175
     176/** Get previous menu in menu bar.
     177 *
     178 * @param cur Current menu
     179 * @return Previous menu or @c NULL if @a cur is the fist one
     180 */
     181ui_menu_t *ui_menu_prev(ui_menu_t *cur)
     182{
     183        link_t *link;
     184
     185        link = list_prev(&cur->lmenus, &cur->mbar->menus);
    151186        if (link == NULL)
    152187                return NULL;
     
    240275        errno_t rc;
    241276
     277        /* Select first entry */
     278        menu->selected = ui_menu_entry_first(menu);
     279
    242280        /* Determine menu dimensions */
    243281
     
    269307        ui_popup_destroy(menu->popup);
    270308        menu->popup = NULL;
     309}
     310
     311/** Determine if menu is open.
     312 *
     313 * @param menu Menu
     314 * @return @c true iff menu is open
     315 */
     316bool ui_menu_is_open(ui_menu_t *menu)
     317{
     318        return menu->popup != NULL;
    271319}
    272320
     
    439487                /* Press outside menu - close it */
    440488                if (event->type == POS_PRESS)
    441                         ui_menu_bar_select(menu->mbar, NULL, NULL);
     489                        ui_menu_bar_deactivate(menu->mbar);
    442490        }
    443491
     
    454502        ui_menu_t *menu = (ui_menu_t *)arg;
    455503
    456         /* Close the menu */
    457         ui_menu_bar_select(menu->mbar, NULL, NULL);
     504        /* Deactivate menu bar, close menu */
     505        ui_menu_bar_deactivate(menu->mbar);
     506}
     507
     508/** Move one entry up.
     509 *
     510 * Non-selectable entries are skipped. If we are already at the top,
     511 * we wrap around.
     512 *
     513 * @param menu Menu
     514 */
     515void ui_menu_up(ui_menu_t *menu)
     516{
     517        gfx_coord2_t mpos;
     518        ui_menu_entry_t *nentry;
     519
     520        if (menu->selected == NULL)
     521                return;
     522
     523        nentry = ui_menu_entry_prev(menu->selected);
     524        if (nentry == NULL)
     525                nentry = ui_menu_entry_last(menu);
     526
     527        /* Need to find a selectable entry */
     528        while (!ui_menu_entry_selectable(nentry)) {
     529                nentry = ui_menu_entry_prev(nentry);
     530                if (nentry == NULL)
     531                        nentry = ui_menu_entry_last(menu);
     532
     533                /* Went completely around and found nothing? */
     534                if (nentry == menu->selected)
     535                        return;
     536        }
     537
     538        menu->selected = nentry;
     539
     540        mpos.x = 0;
     541        mpos.y = 0;
     542        (void) ui_menu_paint(menu, &mpos);
     543}
     544
     545/** Move one entry down.
     546 *
     547 * Non-selectable entries are skipped. If we are already at the bottom,
     548 * we wrap around.
     549 *
     550 * @param menu Menu
     551 */
     552void ui_menu_down(ui_menu_t *menu)
     553{
     554        gfx_coord2_t mpos;
     555        ui_menu_entry_t *nentry;
     556
     557        if (menu->selected == NULL)
     558                return;
     559
     560        nentry = ui_menu_entry_next(menu->selected);
     561        if (nentry == NULL)
     562                nentry = ui_menu_entry_first(menu);
     563
     564        /* Need to find a selectable entry */
     565        while (!ui_menu_entry_selectable(nentry)) {
     566                nentry = ui_menu_entry_next(nentry);
     567                if (nentry == NULL)
     568                        nentry = ui_menu_entry_first(menu);
     569
     570                /* Went completely around and found nothing? */
     571                if (nentry == menu->selected)
     572                        return;
     573        }
     574
     575        menu->selected = nentry;
     576
     577        mpos.x = 0;
     578        mpos.y = 0;
     579        (void) ui_menu_paint(menu, &mpos);
     580}
     581
     582/** Handle key press without modifiers in menu popup window.
     583 *
     584 * @param menu Menu
     585 * @param event Keyboard event
     586 */
     587static void ui_menu_key_press_unmod(ui_menu_t *menu, kbd_event_t *event)
     588{
     589        switch (event->key) {
     590        case KC_ESCAPE:
     591                ui_menu_bar_deactivate(menu->mbar);
     592                break;
     593        case KC_LEFT:
     594                ui_menu_bar_left(menu->mbar);
     595                break;
     596        case KC_RIGHT:
     597                ui_menu_bar_right(menu->mbar);
     598                break;
     599        case KC_UP:
     600                ui_menu_up(menu);
     601                break;
     602        case KC_DOWN:
     603                ui_menu_down(menu);
     604                break;
     605        case KC_ENTER:
     606                if (menu->selected != NULL)
     607                        ui_menu_entry_activate(menu->selected);
     608                break;
     609        default:
     610                break;
     611        }
     612}
     613
     614/** Handle keyboard event in menu popup window.
     615 *
     616 * @param popup Menu popup window
     617 * @param arg Argument (ui_menu_t *)
     618 * @param event Keyboard event
     619 */
     620static void ui_menu_popup_kbd(ui_popup_t *popup, void *arg, kbd_event_t *event)
     621{
     622        ui_menu_t *menu = (ui_menu_t *)arg;
     623
     624        if (event->type == KEY_PRESS && (event->mods &
     625            (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
     626                ui_menu_key_press_unmod(menu, event);
     627        }
    458628}
    459629
  • uspace/lib/ui/src/menubar.c

    r9754ed2 r59768c7  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6060static void ui_menu_bar_ctl_destroy(void *);
    6161static errno_t ui_menu_bar_ctl_paint(void *);
     62static ui_evclaim_t ui_menu_bar_ctl_kbd_event(void *, kbd_event_t *);
    6263static ui_evclaim_t ui_menu_bar_ctl_pos_event(void *, pos_event_t *);
    6364
     
    6667        .destroy = ui_menu_bar_ctl_destroy,
    6768        .paint = ui_menu_bar_ctl_paint,
    68         .pos_event = ui_menu_bar_ctl_pos_event,
     69        .kbd_event = ui_menu_bar_ctl_kbd_event,
     70        .pos_event = ui_menu_bar_ctl_pos_event
    6971};
    7072
     
    236238 *
    237239 * @param mbar Menu bar
    238  * @param rect Menu bar entry rectangle
    239240 * @param menu Menu to select (or deselect if selected) or @c NULL
    240  */
    241 void ui_menu_bar_select(ui_menu_bar_t *mbar, gfx_rect_t *rect,
    242     ui_menu_t *menu)
     241 * @param openup Open menu even if not currently open
     242 */
     243void ui_menu_bar_select(ui_menu_bar_t *mbar, ui_menu_t *menu, bool openup)
    243244{
    244245        ui_menu_t *old_menu;
     246        gfx_rect_t rect;
     247        bool was_open;
    245248
    246249        old_menu = mbar->selected;
     
    252255
    253256        /* Close previously open menu */
    254         if (old_menu != NULL)
     257        if (old_menu != NULL && ui_menu_is_open(old_menu)) {
     258                was_open = true;
    255259                (void) ui_menu_close(old_menu);
     260        } else {
     261                was_open = false;
     262        }
    256263
    257264        (void) ui_menu_bar_paint(mbar);
    258265
    259266        if (mbar->selected != NULL) {
    260                 (void) ui_menu_open(mbar->selected, rect);
    261         }
     267                ui_menu_bar_entry_rect(mbar, mbar->selected, &rect);
     268                if (openup || was_open) {
     269                        /*
     270                         * Open the newly selected menu if either
     271                         * the old menu was open or @a openup was
     272                         * specified.
     273                         */
     274                        (void) ui_menu_open(mbar->selected, &rect);
     275                }
     276        }
     277}
     278
     279/** Move one entry left.
     280 *
     281 * If the selected menu is open, the newly selected menu will be open
     282 * as well. If we are already at the first entry, we wrap around.
     283 *
     284 * @param mbar Menu bar
     285 */
     286void ui_menu_bar_left(ui_menu_bar_t *mbar)
     287{
     288        ui_menu_t *nmenu;
     289
     290        if (mbar->selected == NULL)
     291                return;
     292
     293        nmenu = ui_menu_prev(mbar->selected);
     294        if (nmenu == NULL)
     295                nmenu = ui_menu_last(mbar);
     296
     297        ui_menu_bar_select(mbar, nmenu, false);
     298}
     299
     300/** Move one entry right.
     301 *
     302 * If the selected menu is open, the newly selected menu will be open
     303 * as well. If we are already at the last entry, we wrap around.
     304 *
     305 * @param mbar Menu bar
     306 */
     307void ui_menu_bar_right(ui_menu_bar_t *mbar)
     308{
     309        ui_menu_t *nmenu;
     310
     311        if (mbar->selected == NULL)
     312                return;
     313
     314        nmenu = ui_menu_next(mbar->selected);
     315        if (nmenu == NULL)
     316                nmenu = ui_menu_first(mbar);
     317
     318        ui_menu_bar_select(mbar, nmenu, false);
     319}
     320
     321/** Handle menu bar key press without modifiers.
     322 *
     323 * @param mbar Menu bar
     324 * @param kbd_event Keyboard event
     325 * @return @c ui_claimed iff the event is claimed
     326 */
     327ui_evclaim_t ui_menu_bar_key_press_unmod(ui_menu_bar_t *mbar, kbd_event_t *event)
     328{
     329        gfx_rect_t rect;
     330
     331        if (event->key == KC_F10) {
     332                ui_menu_bar_activate(mbar);
     333                return ui_claimed;
     334        }
     335
     336        if (!mbar->active)
     337                return ui_unclaimed;
     338
     339        if (event->key == KC_ESCAPE) {
     340                ui_menu_bar_deactivate(mbar);
     341                return ui_claimed;
     342        }
     343
     344        if (event->key == KC_LEFT)
     345                ui_menu_bar_left(mbar);
     346
     347        if (event->key == KC_RIGHT)
     348                ui_menu_bar_right(mbar);
     349
     350        if (event->key == KC_ENTER || event->key == KC_DOWN) {
     351                if (mbar->selected != NULL && !ui_menu_is_open(mbar->selected)) {
     352                        ui_menu_bar_entry_rect(mbar, mbar->selected,
     353                            &rect);
     354                        ui_menu_open(mbar->selected, &rect);
     355                }
     356
     357                return ui_claimed;
     358        }
     359
     360        return ui_claimed;
     361}
     362
     363/** Handle menu bar keyboard event.
     364 *
     365 * @param mbar Menu bar
     366 * @param kbd_event Keyboard event
     367 * @return @c ui_claimed iff the event is claimed
     368 */
     369ui_evclaim_t ui_menu_bar_kbd_event(ui_menu_bar_t *mbar, kbd_event_t *event)
     370{
     371        if (event->type == KEY_PRESS && (event->mods &
     372            (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
     373                ui_menu_bar_key_press_unmod(mbar, event);
     374                return ui_claimed;
     375        }
     376
     377        return ui_claimed;
    262378}
    263379
     
    304420                if (event->type == POS_PRESS &&
    305421                    gfx_pix_inside_rect(&ppos, &rect)) {
    306                         ui_menu_bar_select(mbar, &rect, menu);
     422                        mbar->active = true;
     423                        ui_menu_bar_select(mbar, menu, true);
    307424                        return ui_claimed;
    308425                }
     
    315432}
    316433
     434/** Handle menu bar position event.
     435 *
     436 * @param mbar Menu bar
     437 * @param menu Menu whose entry's rectangle is to be returned
     438 * @param rrect Place to store entry rectangle
     439 */
     440void ui_menu_bar_entry_rect(ui_menu_bar_t *mbar, ui_menu_t *menu,
     441    gfx_rect_t *rrect)
     442{
     443        ui_resource_t *res;
     444        gfx_coord2_t pos;
     445        gfx_rect_t rect;
     446        ui_menu_t *cur;
     447        const char *caption;
     448        gfx_coord_t width;
     449        gfx_coord_t hpad;
     450
     451        res = ui_window_get_res(mbar->window);
     452
     453        if (res->textmode) {
     454                hpad = menubar_hpad_text;
     455        } else {
     456                hpad = menubar_hpad;
     457        }
     458
     459        pos = mbar->rect.p0;
     460
     461        cur = ui_menu_first(mbar);
     462        while (cur != NULL) {
     463                caption = ui_menu_caption(cur);
     464                width = gfx_text_width(res->font, caption) + 2 * hpad;
     465
     466                rect.p0 = pos;
     467                rect.p1.x = rect.p0.x + width;
     468                rect.p1.y = mbar->rect.p1.y;
     469
     470                if (cur == menu) {
     471                        *rrect = rect;
     472                        return;
     473                }
     474
     475                pos.x += width;
     476                cur = ui_menu_next(cur);
     477        }
     478
     479        /* We should never get here */
     480        assert(false);
     481}
     482
     483/** Activate menu bar.
     484 *
     485 * @param mbar Menu bar
     486 */
     487void ui_menu_bar_activate(ui_menu_bar_t *mbar)
     488{
     489        if (mbar->active)
     490                return;
     491
     492        mbar->active = true;
     493        if (mbar->selected == NULL)
     494                mbar->selected = ui_menu_first(mbar);
     495
     496        (void) ui_menu_bar_paint(mbar);
     497}
     498
     499void ui_menu_bar_deactivate(ui_menu_bar_t *mbar)
     500{
     501        ui_menu_bar_select(mbar, NULL, false);
     502        mbar->active = false;
     503}
     504
    317505/** Destroy menu bar control.
    318506 *
     
    338526}
    339527
    340 /** Handle menu bar control position event.
     528/** Handle menu bar control keyboard event.
    341529 *
    342530 * @param arg Argument (ui_menu_bar_t *)
     
    344532 * @return @c ui_claimed iff the event is claimed
    345533 */
     534ui_evclaim_t ui_menu_bar_ctl_kbd_event(void *arg, kbd_event_t *event)
     535{
     536        ui_menu_bar_t *mbar = (ui_menu_bar_t *) arg;
     537
     538        return ui_menu_bar_kbd_event(mbar, event);
     539}
     540
     541/** Handle menu bar control position event.
     542 *
     543 * @param arg Argument (ui_menu_bar_t *)
     544 * @param pos_event Position event
     545 * @return @c ui_claimed iff the event is claimed
     546 */
    346547ui_evclaim_t ui_menu_bar_ctl_pos_event(void *arg, pos_event_t *event)
    347548{
  • uspace/lib/ui/src/menuentry.c

    r9754ed2 r59768c7  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4545#include <ui/control.h>
    4646#include <ui/paint.h>
     47#include <ui/menubar.h>
    4748#include <ui/menuentry.h>
    4849#include <ui/window.h>
     
    177178}
    178179
     180/** Get last menu entry in menu.
     181 *
     182 * @param menu Menu
     183 * @return Last menu entry or @c NULL if there is none
     184 */
     185ui_menu_entry_t *ui_menu_entry_last(ui_menu_t *menu)
     186{
     187        link_t *link;
     188
     189        link = list_last(&menu->entries);
     190        if (link == NULL)
     191                return NULL;
     192
     193        return list_get_instance(link, ui_menu_entry_t, lentries);
     194}
     195
    179196/** Get next menu entry in menu.
    180197 *
     
    187204
    188205        link = list_next(&cur->lentries, &cur->menu->entries);
     206        if (link == NULL)
     207                return NULL;
     208
     209        return list_get_instance(link, ui_menu_entry_t, lentries);
     210}
     211
     212/** Get previous menu entry in menu.
     213 *
     214 * @param cur Current menu entry
     215 * @return Next menu entry or @c NULL if @a cur is the last one
     216 */
     217ui_menu_entry_t *ui_menu_entry_prev(ui_menu_entry_t *cur)
     218{
     219        link_t *link;
     220
     221        link = list_prev(&cur->lentries, &cur->menu->entries);
    189222        if (link == NULL)
    190223                return NULL;
     
    378411}
    379412
     413/** Determine if entry is selectable.
     414 *
     415 * @return @c true iff entry is selectable
     416 */
     417bool ui_menu_entry_selectable(ui_menu_entry_t *mentry)
     418{
     419        return !mentry->separator;
     420}
     421
    380422/** Handle button press in menu entry.
    381423 *
     
    407449        mentry->held = false;
    408450
    409         if (mentry->inside) {
    410                 /* Close menu */
    411                 ui_menu_bar_select(mentry->menu->mbar, NULL, NULL);
    412 
    413                 /* Call back */
    414                 ui_menu_entry_cb(mentry);
    415         }
     451        ui_menu_entry_activate(mentry);
     452}
     453
     454/** Activate menu entry.
     455 *
     456 * @param mentry Menu entry
     457 */
     458void ui_menu_entry_activate(ui_menu_entry_t *mentry)
     459{
     460        /* Deactivate menu bar, close menu */
     461        ui_menu_bar_deactivate(mentry->menu->mbar);
     462
     463        /* Call back */
     464        ui_menu_entry_cb(mentry);
    416465}
    417466
  • uspace/lib/ui/src/popup.c

    r9754ed2 r59768c7  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636#include <errno.h>
    3737#include <gfx/context.h>
    38 //#include <io/kbd_event.h>
     38#include <io/kbd_event.h>
    3939#include <io/pos_event.h>
    4040#include <mem.h>
     
    4747
    4848static void ui_popup_window_close(ui_window_t *, void *);
     49static void ui_popup_window_kbd(ui_window_t *, void *, kbd_event_t *);
    4950static void ui_popup_window_pos(ui_window_t *, void *, pos_event_t *);
    5051
    5152static ui_window_cb_t ui_popup_window_cb = {
    5253        .close = ui_popup_window_close,
     54        .kbd = ui_popup_window_kbd,
    5355        .pos = ui_popup_window_pos
    5456};
     
    200202}
    201203
     204/** Handle keyboard event in popup window.
     205 *
     206 * @param window Window
     207 * @param arg Argument (ui_popup_t *)
     208 * @param event Keyboard event
     209 */
     210static void ui_popup_window_kbd(ui_window_t *window, void *arg,
     211    kbd_event_t *event)
     212{
     213        ui_popup_t *popup = (ui_popup_t *)arg;
     214
     215        if (popup->cb != NULL && popup->cb->kbd != NULL)
     216                popup->cb->kbd(popup, popup->arg, event);
     217}
     218
    202219/** Handle position event in popup window.
    203220 *
  • uspace/lib/ui/test/menu.c

    r9754ed2 r59768c7  
    3636#include <ui/menu.h>
    3737#include <ui/menubar.h>
     38#include <ui/menuentry.h>
    3839#include <ui/ui.h>
    3940#include <ui/window.h>
     
    122123}
    123124
     125/** ui_menu_last() / ui_menu_prev() iterate over menus in reverse */
     126PCUT_TEST(last_prev)
     127{
     128        ui_t *ui = NULL;
     129        ui_window_t *window = NULL;
     130        ui_wnd_params_t params;
     131        ui_menu_bar_t *mbar = NULL;
     132        ui_menu_t *menu1 = NULL;
     133        ui_menu_t *menu2 = NULL;
     134        ui_menu_t *m;
     135        errno_t rc;
     136
     137        rc = ui_create_disp(NULL, &ui);
     138        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     139
     140        ui_wnd_params_init(&params);
     141        params.caption = "Hello";
     142
     143        rc = ui_window_create(ui, &params, &window);
     144        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     145        PCUT_ASSERT_NOT_NULL(window);
     146
     147        rc = ui_menu_bar_create(ui, window, &mbar);
     148        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     149        PCUT_ASSERT_NOT_NULL(mbar);
     150
     151        rc = ui_menu_create(mbar, "Test 1", &menu1);
     152        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     153        PCUT_ASSERT_NOT_NULL(menu1);
     154
     155        rc = ui_menu_create(mbar, "Test 1", &menu2);
     156        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     157        PCUT_ASSERT_NOT_NULL(menu2);
     158
     159        m = ui_menu_last(mbar);
     160        PCUT_ASSERT_EQUALS(menu2, m);
     161
     162        m = ui_menu_prev(m);
     163        PCUT_ASSERT_EQUALS(menu1, m);
     164
     165        m = ui_menu_prev(m);
     166        PCUT_ASSERT_NULL(m);
     167
     168        ui_menu_bar_destroy(mbar);
     169        ui_window_destroy(window);
     170        ui_destroy(ui);
     171}
     172
    124173/** ui_menu_caption() returns the menu's caption */
    125174PCUT_TEST(caption)
     
    209258}
    210259
    211 /** Paint background in graphics mode */
    212 PCUT_TEST(paint_bg_gfx)
     260/** Open and close menu with ui_menu_open() / ui_menu_close() */
     261PCUT_TEST(open_close)
    213262{
    214263        ui_t *ui = NULL;
     
    218267        ui_menu_t *menu = NULL;
    219268        gfx_rect_t prect;
    220         gfx_coord2_t pos;
    221269        errno_t rc;
    222270
     
    244292        prect.p1.y = 0;
    245293
    246         /* Menu needs to be open to be able to paint it */
     294        /* Open and close */
    247295        rc = ui_menu_open(menu, &prect);
    248296        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    249297
    250         pos.x = 0;
    251         pos.y = 0;
    252         rc = ui_menu_paint_bg_gfx(menu, &pos);
    253         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    254 
    255         ui_menu_bar_destroy(mbar);
    256         ui_window_destroy(window);
    257         ui_destroy(ui);
    258 }
    259 
    260 /** Paint background in text mode */
    261 PCUT_TEST(paint_bg_text)
     298        ui_menu_close(menu);
     299
     300        ui_menu_bar_destroy(mbar);
     301        ui_window_destroy(window);
     302        ui_destroy(ui);
     303}
     304
     305/** ui_menu_is_open() correctly returns menu state */
     306PCUT_TEST(is_open)
    262307{
    263308        ui_t *ui = NULL;
     
    267312        ui_menu_t *menu = NULL;
    268313        gfx_rect_t prect;
    269         gfx_coord2_t pos;
     314        bool open;
    270315        errno_t rc;
    271316
     
    293338        prect.p1.y = 0;
    294339
    295         /* Menu needs to be open to be able to paint it */
     340        open = ui_menu_is_open(menu);
     341        PCUT_ASSERT_FALSE(open);
     342
    296343        rc = ui_menu_open(menu, &prect);
    297344        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    298345
    299         pos.x = 0;
    300         pos.y = 0;
    301         rc = ui_menu_paint_bg_text(menu, &pos);
    302         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    303 
    304         ui_menu_bar_destroy(mbar);
    305         ui_window_destroy(window);
    306         ui_destroy(ui);
    307 }
    308 
    309 /** Paint menu */
    310 PCUT_TEST(paint)
     346        open = ui_menu_is_open(menu);
     347        PCUT_ASSERT_TRUE(open);
     348
     349        ui_menu_close(menu);
     350
     351        open = ui_menu_is_open(menu);
     352        PCUT_ASSERT_FALSE(open);
     353
     354        ui_menu_bar_destroy(mbar);
     355        ui_window_destroy(window);
     356        ui_destroy(ui);
     357}
     358
     359/** Paint background in graphics mode */
     360PCUT_TEST(paint_bg_gfx)
    311361{
    312362        ui_t *ui = NULL;
     
    348398        pos.x = 0;
    349399        pos.y = 0;
     400        rc = ui_menu_paint_bg_gfx(menu, &pos);
     401        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     402
     403        ui_menu_bar_destroy(mbar);
     404        ui_window_destroy(window);
     405        ui_destroy(ui);
     406}
     407
     408/** Paint background in text mode */
     409PCUT_TEST(paint_bg_text)
     410{
     411        ui_t *ui = NULL;
     412        ui_window_t *window = NULL;
     413        ui_wnd_params_t params;
     414        ui_menu_bar_t *mbar = NULL;
     415        ui_menu_t *menu = NULL;
     416        gfx_rect_t prect;
     417        gfx_coord2_t pos;
     418        errno_t rc;
     419
     420        rc = ui_create_disp(NULL, &ui);
     421        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     422
     423        ui_wnd_params_init(&params);
     424        params.caption = "Hello";
     425
     426        rc = ui_window_create(ui, &params, &window);
     427        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     428        PCUT_ASSERT_NOT_NULL(window);
     429
     430        rc = ui_menu_bar_create(ui, window, &mbar);
     431        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     432        PCUT_ASSERT_NOT_NULL(mbar);
     433
     434        rc = ui_menu_create(mbar, "Test", &menu);
     435        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     436        PCUT_ASSERT_NOT_NULL(menu);
     437
     438        prect.p0.x = 0;
     439        prect.p0.y = 0;
     440        prect.p1.x = 0;
     441        prect.p1.y = 0;
     442
     443        /* Menu needs to be open to be able to paint it */
     444        rc = ui_menu_open(menu, &prect);
     445        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     446
     447        pos.x = 0;
     448        pos.y = 0;
     449        rc = ui_menu_paint_bg_text(menu, &pos);
     450        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     451
     452        ui_menu_bar_destroy(mbar);
     453        ui_window_destroy(window);
     454        ui_destroy(ui);
     455}
     456
     457/** Paint menu */
     458PCUT_TEST(paint)
     459{
     460        ui_t *ui = NULL;
     461        ui_window_t *window = NULL;
     462        ui_wnd_params_t params;
     463        ui_menu_bar_t *mbar = NULL;
     464        ui_menu_t *menu = NULL;
     465        gfx_rect_t prect;
     466        gfx_coord2_t pos;
     467        errno_t rc;
     468
     469        rc = ui_create_disp(NULL, &ui);
     470        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     471
     472        ui_wnd_params_init(&params);
     473        params.caption = "Hello";
     474
     475        rc = ui_window_create(ui, &params, &window);
     476        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     477        PCUT_ASSERT_NOT_NULL(window);
     478
     479        rc = ui_menu_bar_create(ui, window, &mbar);
     480        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     481        PCUT_ASSERT_NOT_NULL(mbar);
     482
     483        rc = ui_menu_create(mbar, "Test", &menu);
     484        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     485        PCUT_ASSERT_NOT_NULL(menu);
     486
     487        prect.p0.x = 0;
     488        prect.p0.y = 0;
     489        prect.p1.x = 0;
     490        prect.p1.y = 0;
     491
     492        /* Menu needs to be open to be able to paint it */
     493        rc = ui_menu_open(menu, &prect);
     494        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     495
     496        pos.x = 0;
     497        pos.y = 0;
    350498        rc = ui_menu_paint(menu, &pos);
    351499        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     500
     501        ui_menu_bar_destroy(mbar);
     502        ui_window_destroy(window);
     503        ui_destroy(ui);
     504}
     505
     506/** ui_menu_up() with empty menu does nothing */
     507PCUT_TEST(up_empty)
     508{
     509        ui_t *ui = NULL;
     510        ui_window_t *window = NULL;
     511        ui_wnd_params_t params;
     512        ui_menu_bar_t *mbar = NULL;
     513        ui_menu_t *menu = NULL;
     514        gfx_rect_t prect;
     515        errno_t rc;
     516
     517        rc = ui_create_disp(NULL, &ui);
     518        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     519
     520        ui_wnd_params_init(&params);
     521        params.caption = "Hello";
     522
     523        rc = ui_window_create(ui, &params, &window);
     524        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     525        PCUT_ASSERT_NOT_NULL(window);
     526
     527        rc = ui_menu_bar_create(ui, window, &mbar);
     528        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     529        PCUT_ASSERT_NOT_NULL(mbar);
     530
     531        rc = ui_menu_create(mbar, "Test", &menu);
     532        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     533        PCUT_ASSERT_NOT_NULL(menu);
     534
     535        prect.p0.x = 0;
     536        prect.p0.y = 0;
     537        prect.p1.x = 0;
     538        prect.p1.y = 0;
     539
     540        /* Menu needs to be open to be able to move around it */
     541        rc = ui_menu_open(menu, &prect);
     542        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     543
     544        ui_menu_up(menu);
     545
     546        ui_menu_bar_destroy(mbar);
     547        ui_window_destroy(window);
     548        ui_destroy(ui);
     549}
     550
     551/** ui_menu_up() moves one entry up, skips separators, wraps around */
     552PCUT_TEST(up)
     553{
     554        ui_t *ui = NULL;
     555        ui_window_t *window = NULL;
     556        ui_wnd_params_t params;
     557        ui_menu_bar_t *mbar = NULL;
     558        ui_menu_t *menu = NULL;
     559        ui_menu_entry_t *mentry1 = NULL;
     560        ui_menu_entry_t *mentry2 = NULL;
     561        ui_menu_entry_t *mentry3 = NULL;
     562        gfx_rect_t prect;
     563        errno_t rc;
     564
     565        rc = ui_create_disp(NULL, &ui);
     566        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     567
     568        ui_wnd_params_init(&params);
     569        params.caption = "Hello";
     570
     571        rc = ui_window_create(ui, &params, &window);
     572        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     573        PCUT_ASSERT_NOT_NULL(window);
     574
     575        rc = ui_menu_bar_create(ui, window, &mbar);
     576        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     577        PCUT_ASSERT_NOT_NULL(mbar);
     578
     579        rc = ui_menu_create(mbar, "Test", &menu);
     580        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     581        PCUT_ASSERT_NOT_NULL(menu);
     582
     583        rc = ui_menu_entry_create(menu, "Foo", "F1", &mentry1);
     584        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     585        PCUT_ASSERT_NOT_NULL(mentry1);
     586
     587        rc = ui_menu_entry_sep_create(menu, &mentry2);
     588        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     589        PCUT_ASSERT_NOT_NULL(mentry2);
     590
     591        rc = ui_menu_entry_create(menu, "Bar", "F2", &mentry3);
     592        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     593        PCUT_ASSERT_NOT_NULL(mentry3);
     594
     595        prect.p0.x = 0;
     596        prect.p0.y = 0;
     597        prect.p1.x = 0;
     598        prect.p1.y = 0;
     599
     600        /* Menu needs to be open to be able to move around it */
     601        rc = ui_menu_open(menu, &prect);
     602        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     603
     604        /* When menu is open, the first entry is selected */
     605        PCUT_ASSERT_EQUALS(mentry1, menu->selected);
     606
     607        ui_menu_up(menu);
     608
     609        /* Now we've wrapped around to the last entry */
     610        PCUT_ASSERT_EQUALS(mentry3, menu->selected);
     611
     612        ui_menu_up(menu);
     613
     614        /* mentry2 is a separator and was skipped */
     615        PCUT_ASSERT_EQUALS(mentry1, menu->selected);
     616
     617        ui_menu_bar_destroy(mbar);
     618        ui_window_destroy(window);
     619        ui_destroy(ui);
     620}
     621
     622/** ui_menu_down() with empty menu does nothing */
     623PCUT_TEST(down_empty)
     624{
     625        ui_t *ui = NULL;
     626        ui_window_t *window = NULL;
     627        ui_wnd_params_t params;
     628        ui_menu_bar_t *mbar = NULL;
     629        ui_menu_t *menu = NULL;
     630        gfx_rect_t prect;
     631        errno_t rc;
     632
     633        rc = ui_create_disp(NULL, &ui);
     634        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     635
     636        ui_wnd_params_init(&params);
     637        params.caption = "Hello";
     638
     639        rc = ui_window_create(ui, &params, &window);
     640        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     641        PCUT_ASSERT_NOT_NULL(window);
     642
     643        rc = ui_menu_bar_create(ui, window, &mbar);
     644        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     645        PCUT_ASSERT_NOT_NULL(mbar);
     646
     647        rc = ui_menu_create(mbar, "Test", &menu);
     648        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     649        PCUT_ASSERT_NOT_NULL(menu);
     650
     651        prect.p0.x = 0;
     652        prect.p0.y = 0;
     653        prect.p1.x = 0;
     654        prect.p1.y = 0;
     655
     656        /* Menu needs to be open to be able to move around it */
     657        rc = ui_menu_open(menu, &prect);
     658        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     659
     660        ui_menu_down(menu);
     661
     662        ui_menu_bar_destroy(mbar);
     663        ui_window_destroy(window);
     664        ui_destroy(ui);
     665}
     666
     667/** ui_menu_down() moves one entry down, skips separators, wraps around */
     668PCUT_TEST(down)
     669{
     670        ui_t *ui = NULL;
     671        ui_window_t *window = NULL;
     672        ui_wnd_params_t params;
     673        ui_menu_bar_t *mbar = NULL;
     674        ui_menu_t *menu = NULL;
     675        ui_menu_entry_t *mentry1 = NULL;
     676        ui_menu_entry_t *mentry2 = NULL;
     677        ui_menu_entry_t *mentry3 = NULL;
     678        gfx_rect_t prect;
     679        errno_t rc;
     680
     681        rc = ui_create_disp(NULL, &ui);
     682        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     683
     684        ui_wnd_params_init(&params);
     685        params.caption = "Hello";
     686
     687        rc = ui_window_create(ui, &params, &window);
     688        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     689        PCUT_ASSERT_NOT_NULL(window);
     690
     691        rc = ui_menu_bar_create(ui, window, &mbar);
     692        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     693        PCUT_ASSERT_NOT_NULL(mbar);
     694
     695        rc = ui_menu_create(mbar, "Test", &menu);
     696        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     697        PCUT_ASSERT_NOT_NULL(menu);
     698
     699        rc = ui_menu_entry_create(menu, "Foo", "F1", &mentry1);
     700        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     701        PCUT_ASSERT_NOT_NULL(mentry1);
     702
     703        rc = ui_menu_entry_sep_create(menu, &mentry2);
     704        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     705        PCUT_ASSERT_NOT_NULL(mentry2);
     706
     707        rc = ui_menu_entry_create(menu, "Bar", "F2", &mentry3);
     708        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     709        PCUT_ASSERT_NOT_NULL(mentry3);
     710
     711        prect.p0.x = 0;
     712        prect.p0.y = 0;
     713        prect.p1.x = 0;
     714        prect.p1.y = 0;
     715
     716        /* Menu needs to be open to be able to move around it */
     717        rc = ui_menu_open(menu, &prect);
     718        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     719
     720        /* When menu is open, the first entry is selected */
     721        PCUT_ASSERT_EQUALS(mentry1, menu->selected);
     722
     723        ui_menu_down(menu);
     724
     725        /* mentry2 is a separator and was skipped */
     726        PCUT_ASSERT_EQUALS(mentry3, menu->selected);
     727
     728        ui_menu_up(menu);
     729
     730        /* Now we've wrapped around to the first entry */
     731        PCUT_ASSERT_EQUALS(mentry1, menu->selected);
    352732
    353733        ui_menu_bar_destroy(mbar);
  • uspace/lib/ui/test/menubar.c

    r9754ed2 r59768c7  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    149149}
    150150
    151 /** Press event on menu bar entry selects menu */
    152 PCUT_TEST(pos_event_select)
     151/** Deliver menu bar keyboard event */
     152PCUT_TEST(kbd_event)
    153153{
    154154        ui_t *ui = NULL;
     
    158158        ui_menu_t *menu = NULL;
    159159        ui_evclaim_t claimed;
    160         pos_event_t event;
     160        kbd_event_t event;
    161161        gfx_rect_t rect;
    162162        errno_t rc;
     
    186186        PCUT_ASSERT_NOT_NULL(menu);
    187187
     188        event.type = KEY_PRESS;
     189        event.key = KC_ESCAPE;
     190        claimed = ui_menu_kbd_pos_event(mbar, &event);
     191        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     192        PCUT_ASSERT_EQUALS(ui_claimed, claimed);
     193
     194        ui_menu_bar_destroy(mbar);
     195        ui_window_destroy(window);
     196        ui_destroy(ui);
     197}
     198
     199/** Press event on menu bar entry selects menu */
     200PCUT_TEST(pos_event_select)
     201{
     202        ui_t *ui = NULL;
     203        ui_window_t *window = NULL;
     204        ui_wnd_params_t params;
     205        ui_menu_bar_t *mbar = NULL;
     206        ui_menu_t *menu = NULL;
     207        ui_evclaim_t claimed;
     208        pos_event_t event;
     209        gfx_rect_t rect;
     210        errno_t rc;
     211
     212        rc = ui_create_disp(NULL, &ui);
     213        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     214
     215        ui_wnd_params_init(&params);
     216        params.caption = "Hello";
     217
     218        rc = ui_window_create(ui, &params, &window);
     219        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     220        PCUT_ASSERT_NOT_NULL(window);
     221
     222        rc = ui_menu_bar_create(ui, window, &mbar);
     223        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     224        PCUT_ASSERT_NOT_NULL(mbar);
     225
     226        rect.p0.x = 0;
     227        rect.p0.y = 0;
     228        rect.p1.x = 50;
     229        rect.p1.y = 25;
     230        ui_menu_bar_set_rect(mbar, &rect);
     231
     232        rc = ui_menu_create(mbar, "Test", &menu);
     233        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     234        PCUT_ASSERT_NOT_NULL(menu);
     235
    188236        event.type = POS_PRESS;
    189237        event.hpos = 4;
     
    209257        ui_menu_bar_t *mbar = NULL;
    210258        ui_menu_t *menu = NULL;
    211         gfx_rect_t rect;
    212259        errno_t rc;
    213260
     
    230277        PCUT_ASSERT_NOT_NULL(menu);
    231278
    232         rect.p0.x = 0;
    233         rect.p0.y = 0;
    234         rect.p1.x = 0;
    235         rect.p1.y = 0;
    236         ui_menu_bar_select(mbar, &rect, menu);
     279        ui_menu_bar_select(mbar, menu, true);
    237280        PCUT_ASSERT_EQUALS(menu, mbar->selected);
    238281
    239282        /* Selecting again should unselect the menu */
    240         ui_menu_bar_select(mbar, &rect, menu);
     283        ui_menu_bar_select(mbar, menu, true);
    241284        PCUT_ASSERT_NULL(mbar->selected);
    242285
     
    255298        ui_menu_t *menu1 = NULL;
    256299        ui_menu_t *menu2 = NULL;
    257         gfx_rect_t rect;
    258300        errno_t rc;
    259301
     
    280322        PCUT_ASSERT_NOT_NULL(menu2);
    281323
    282         rect.p0.x = 0;
    283         rect.p0.y = 0;
    284         rect.p1.x = 0;
    285         rect.p1.y = 0;
    286         ui_menu_bar_select(mbar, &rect, menu1);
     324        ui_menu_bar_select(mbar, menu1, true);
    287325        PCUT_ASSERT_EQUALS(menu1, mbar->selected);
    288326
    289327        /* Selecting different menu should select it */
    290         ui_menu_bar_select(mbar, &rect, menu2);
     328        ui_menu_bar_select(mbar, menu2, true);
    291329        PCUT_ASSERT_EQUALS(menu2, mbar->selected);
    292330
     
    296334}
    297335
     336/** ui_menu_bar_activate() activates/deactivates menu bar */
     337PCUT_TEST(activate_deactivate)
     338{
     339        ui_t *ui = NULL;
     340        ui_window_t *window = NULL;
     341        ui_wnd_params_t params;
     342        ui_menu_bar_t *mbar = NULL;
     343        ui_menu_t *menu = NULL;
     344        errno_t rc;
     345
     346        rc = ui_create_disp(NULL, &ui);
     347        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     348
     349        ui_wnd_params_init(&params);
     350        params.caption = "Hello";
     351
     352        rc = ui_window_create(ui, &params, &window);
     353        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     354        PCUT_ASSERT_NOT_NULL(window);
     355
     356        rc = ui_menu_bar_create(ui, window, &mbar);
     357        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     358        PCUT_ASSERT_NOT_NULL(mbar);
     359
     360        rc = ui_menu_create(mbar, "Test", &menu);
     361        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     362        PCUT_ASSERT_NOT_NULL(menu);
     363
     364        ui_menu_bar_activate(mbar);
     365        PCUT_ASSERT_EQUALS(menu, mbar->selected);
     366
     367        ui_menu_bar_deactivate(mbar);
     368        PCUT_ASSERT_NULL(mbar->selected);
     369
     370        ui_menu_bar_destroy(mbar);
     371        ui_window_destroy(window);
     372        ui_destroy(ui);
     373}
     374
    298375PCUT_EXPORT(menubar);
  • uspace/lib/ui/test/menuentry.c

    r9754ed2 r59768c7  
    236236}
    237237
     238/** ui_menu_entry_last() / ui_menu_entry_prev() iterate over entries in reverse */
     239PCUT_TEST(last_prev)
     240{
     241        ui_t *ui = NULL;
     242        ui_window_t *window = NULL;
     243        ui_wnd_params_t params;
     244        ui_menu_bar_t *mbar = NULL;
     245        ui_menu_t *menu = NULL;
     246        ui_menu_entry_t *entry1 = NULL;
     247        ui_menu_entry_t *entry2 = NULL;
     248        ui_menu_entry_t *e;
     249        errno_t rc;
     250
     251        rc = ui_create_disp(NULL, &ui);
     252        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     253
     254        ui_wnd_params_init(&params);
     255        params.caption = "Hello";
     256
     257        rc = ui_window_create(ui, &params, &window);
     258        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     259        PCUT_ASSERT_NOT_NULL(window);
     260
     261        rc = ui_menu_bar_create(ui, window, &mbar);
     262        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     263        PCUT_ASSERT_NOT_NULL(mbar);
     264
     265        rc = ui_menu_create(mbar, "Test", &menu);
     266        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     267        PCUT_ASSERT_NOT_NULL(menu);
     268
     269        rc = ui_menu_entry_create(menu, "Foo", "F1", &entry1);
     270        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     271        PCUT_ASSERT_NOT_NULL(entry1);
     272
     273        rc = ui_menu_entry_create(menu, "Bar", "F2", &entry2);
     274        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     275        PCUT_ASSERT_NOT_NULL(entry2);
     276
     277        e = ui_menu_entry_last(menu);
     278        PCUT_ASSERT_EQUALS(entry2, e);
     279
     280        e = ui_menu_entry_prev(e);
     281        PCUT_ASSERT_EQUALS(entry1, e);
     282
     283        e = ui_menu_entry_prev(e);
     284        PCUT_ASSERT_NULL(e);
     285
     286        ui_menu_bar_destroy(mbar);
     287        ui_window_destroy(window);
     288        ui_destroy(ui);
     289}
     290
    238291/** ui_menu_entry_column_widths() / ui_menu_entry_height() */
    239292PCUT_TEST(widths_height)
     
    335388        rc = ui_menu_entry_paint(mentry, &pos);
    336389        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     390
     391        ui_menu_bar_destroy(mbar);
     392        ui_window_destroy(window);
     393        ui_destroy(ui);
     394}
     395
     396/** ui_menu_entry_selectable() returns correct value based on entry type */
     397PCUT_TEST(selectable)
     398{
     399        ui_t *ui = NULL;
     400        ui_window_t *window = NULL;
     401        ui_wnd_params_t params;
     402        ui_menu_bar_t *mbar = NULL;
     403        ui_menu_t *menu = NULL;
     404        ui_menu_entry_t *mentry = NULL;
     405        errno_t rc;
     406
     407        rc = ui_create_disp(NULL, &ui);
     408        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     409
     410        ui_wnd_params_init(&params);
     411        params.caption = "Hello";
     412
     413        rc = ui_window_create(ui, &params, &window);
     414        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     415        PCUT_ASSERT_NOT_NULL(window);
     416
     417        rc = ui_menu_bar_create(ui, window, &mbar);
     418        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     419        PCUT_ASSERT_NOT_NULL(mbar);
     420
     421        rc = ui_menu_create(mbar, "Test", &menu);
     422        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     423        PCUT_ASSERT_NOT_NULL(menu);
     424
     425        /* Selectable entry */
     426
     427        rc = ui_menu_entry_create(menu, "Foo", "F1", &mentry);
     428        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     429        PCUT_ASSERT_NOT_NULL(mentry);
     430
     431        PCUT_ASSERT_TRUE(ui_menu_entry_selectable(mentry));
     432
     433        ui_menu_entry_destroy(mentry);
     434
     435        /* Non-selectable separator entry */
     436
     437        rc = ui_menu_entry_sep_create(menu, &mentry);
     438        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     439        PCUT_ASSERT_NOT_NULL(mentry);
     440
     441        PCUT_ASSERT_FALSE(ui_menu_entry_selectable(mentry));
     442
     443        ui_menu_entry_destroy(mentry);
    337444
    338445        ui_menu_bar_destroy(mbar);
     
    545652}
    546653
     654/** ui_menu_entry_activate() activates menu entry */
     655PCUT_TEST(activate)
     656{
     657        ui_t *ui = NULL;
     658        ui_window_t *window = NULL;
     659        ui_wnd_params_t params;
     660        ui_menu_bar_t *mbar = NULL;
     661        ui_menu_t *menu = NULL;
     662        ui_menu_entry_t *mentry = NULL;
     663        gfx_rect_t prect;
     664        test_resp_t resp;
     665        errno_t rc;
     666
     667        rc = ui_create_disp(NULL, &ui);
     668        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     669
     670        ui_wnd_params_init(&params);
     671        params.caption = "Hello";
     672
     673        rc = ui_window_create(ui, &params, &window);
     674        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     675        PCUT_ASSERT_NOT_NULL(window);
     676
     677        rc = ui_menu_bar_create(ui, window, &mbar);
     678        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     679        PCUT_ASSERT_NOT_NULL(mbar);
     680
     681        rc = ui_menu_create(mbar, "Test", &menu);
     682        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     683        PCUT_ASSERT_NOT_NULL(menu);
     684
     685        rc = ui_menu_entry_create(menu, "X", "Y", &mentry);
     686        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     687        PCUT_ASSERT_NOT_NULL(mentry);
     688
     689        ui_menu_entry_set_cb(mentry, test_entry_cb, &resp);
     690        resp.activated = false;
     691
     692        prect.p0.x = 0;
     693        prect.p0.y = 0;
     694        prect.p1.x = 0;
     695        prect.p1.y = 0;
     696
     697        rc = ui_menu_open(menu, &prect);
     698        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     699
     700        PCUT_ASSERT_FALSE(resp.activated);
     701        ui_menu_entry_activate(mentry);
     702
     703        ui_menu_entry_release(mentry);
     704        PCUT_ASSERT_TRUE(resp.activated);
     705
     706        ui_menu_bar_destroy(mbar);
     707        ui_window_destroy(window);
     708        ui_destroy(ui);
     709}
     710
    547711/** Press event inside menu entry */
    548712PCUT_TEST(pos_press_inside)
Note: See TracChangeset for help on using the changeset viewer.