Changeset dc5c303 in mainline for uspace/lib/ui/src


Ignore:
Timestamp:
2023-12-28T13:59:23Z (2 years ago)
Author:
GitHub <noreply@…>
Children:
6b66de6b
Parents:
42c2e65 (diff), f87ff8e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
boba-buba <120932204+boba-buba@…> (2023-12-28 13:59:23)
git-committer:
GitHub <noreply@…> (2023-12-28 13:59:23)
Message:

Merge branch 'master' into topic/packet-capture

Location:
uspace/lib/ui/src
Files:
2 added
13 edited

Legend:

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

    r42c2e65 rdc5c303  
    11/*
    2  * Copyright (c) 2022 Jiri Svoboda
     2 * Copyright (c) 2023 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3535 * Clickmatic is used to periodically generate events in particular cases
    3636 * when a mouse button is held down, such as when holding the button or
    37  * through of a scrollbar.
     37 * trough of a scrollbar.
    3838 */
    3939
  • uspace/lib/ui/src/filelist.c

    r42c2e65 rdc5c303  
    4646#include <qsort.h>
    4747#include "../private/filelist.h"
     48#include "../private/list.h"
    4849#include "../private/resource.h"
    4950
     
    290291 * @param entry File list entry
    291292 */
    292 void ui_file_list_entry_delete(ui_file_list_entry_t *entry)
    293 {
    294         ui_list_entry_delete(entry->entry);
     293void ui_file_list_entry_destroy(ui_file_list_entry_t *entry)
     294{
     295        ui_list_entry_destroy(entry->entry);
    295296        free(entry->name);
    296297        free(entry);
     
    307308        entry = ui_file_list_first(flist);
    308309        while (entry != NULL) {
    309                 ui_file_list_entry_delete(entry);
     310                ui_file_list_entry_destroy(entry);
    310311                entry = ui_file_list_first(flist);
    311312        }
  • uspace/lib/ui/src/list.c

    r42c2e65 rdc5c303  
    149149        list->cb = cb;
    150150        list->cb_arg = arg;
     151}
     152
     153/** Get UI list callback argument.
     154 *
     155 * @param list UI list
     156 * @return Callback argument
     157 */
     158void *ui_list_get_cb_arg(ui_list_t *list)
     159{
     160        return list->cb_arg;
    151161}
    152162
     
    701711}
    702712
    703 /** Delete UI list entry.
     713/** Destroy UI list entry.
     714 *
     715 * This is the quick way, but does not update cursor or page position.
    704716 *
    705717 * @param entry UI list entry
    706718 */
    707 void ui_list_entry_delete(ui_list_entry_t *entry)
     719void ui_list_entry_destroy(ui_list_entry_t *entry)
    708720{
    709721        if (entry->list->cursor == entry)
     
    718730}
    719731
     732/** Delete UI list entry.
     733 *
     734 * If required, update cursor and page position and repaint.
     735 *
     736 * @param entry UI list entry
     737 */
     738void ui_list_entry_delete(ui_list_entry_t *entry)
     739{
     740        ui_list_t *list = entry->list;
     741
     742        /* Try to make sure entry does not disappear under cursor or page */
     743        if (entry->list->cursor == entry)
     744                ui_list_cursor_up(entry->list);
     745        if (entry->list->cursor == entry)
     746                ui_list_cursor_down(entry->list);
     747        if (entry->list->page == entry)
     748                ui_list_scroll_up(entry->list);
     749        if (entry->list->page == entry)
     750                ui_list_scroll_down(entry->list);
     751
     752        ui_list_entry_destroy(entry);
     753
     754        /*
     755         * But it could still happen if there are not enough entries.
     756         * In that case just move page and/or cursor to the first
     757         * entry.
     758         */
     759        if (list->page == NULL) {
     760                list->page = ui_list_first(list);
     761                list->page_idx = 0;
     762        } else {
     763                /*
     764                 * Entry index might have changed if earlier entry
     765                 * was deleted.
     766                 */
     767                list->page_idx = ui_list_entry_get_idx(list->page);
     768        }
     769
     770        if (list->cursor == NULL) {
     771                list->cursor = ui_list_first(list);
     772                list->cursor_idx = 0;
     773        } else {
     774                /*
     775                 * Entry index might have changed if earlier entry
     776                 * was deleted.
     777                 */
     778                list->cursor_idx = ui_list_entry_get_idx(list->cursor);
     779        }
     780}
     781
    720782/** Get entry argument.
    721783 *
     
    728790}
    729791
     792/** Get containing list.
     793 *
     794 * @param entry UI list entry
     795 * @return Containing list
     796 */
     797ui_list_t *ui_list_entry_get_list(ui_list_entry_t *entry)
     798{
     799        return entry->list;
     800}
     801
     802/** Change list entry caption.
     803 *
     804 * @param entry UI list entry
     805 * @param caption New caption
     806 *
     807 * @return EOK on success, ENOMEM if out of memory
     808 */
     809errno_t ui_list_entry_set_caption(ui_list_entry_t *entry, const char *caption)
     810{
     811        char *dcaption;
     812
     813        dcaption = str_dup(caption);
     814        if (dcaption == NULL)
     815                return ENOMEM;
     816
     817        free(entry->caption);
     818        entry->caption = dcaption;
     819
     820        (void)ui_list_entry_paint(entry, ui_list_entry_get_idx(entry));
     821        return EOK;
     822}
     823
    730824/** Clear UI list entry list.
    731825 *
     
    738832        entry = ui_list_first(list);
    739833        while (entry != NULL) {
    740                 ui_list_entry_delete(entry);
     834                ui_list_entry_destroy(entry);
    741835                entry = ui_list_first(list);
    742836        }
     
    858952{
    859953        return list->cursor;
     954}
     955
     956/** Set new cursor position.
     957 *
     958 * O(N) in list size, use with caution.
     959 *
     960 * @param list UI list
     961 * @param entry New cursor position
     962 */
     963void ui_list_set_cursor(ui_list_t *list, ui_list_entry_t *entry)
     964{
     965        size_t idx;
     966
     967        idx = ui_list_entry_get_idx(entry);
     968        ui_list_cursor_move(list, entry, idx);
    860969}
    861970
     
    9121021                                /* Find first page entry (go back rows - 1) */
    9131022                                e = entry;
    914                                 for (i = 0; i < rows - 1; i++) {
     1023                                for (i = 0; i + 1 < rows; i++) {
    9151024                                        e = ui_list_prev(e);
    9161025                                }
     
    10981207        ui_list_entry_t *prev;
    10991208
     1209        if (list->page == NULL)
     1210                return;
     1211
    11001212        prev = ui_list_prev(list->page);
    11011213        if (prev == NULL)
     
    11201232        size_t i;
    11211233        size_t rows;
     1234
     1235        if (list->page == NULL)
     1236                return;
    11221237
    11231238        next = ui_list_next(list->page);
  • uspace/lib/ui/src/menu.c

    r42c2e65 rdc5c303  
    3535
    3636#include <adt/list.h>
     37#include <ctype.h>
    3738#include <errno.h>
    3839#include <gfx/color.h>
     
    4445#include <str.h>
    4546#include <uchar.h>
     47#include <ui/ui.h>
    4648#include <ui/accel.h>
    4749#include <ui/control.h>
     
    4951#include <ui/popup.h>
    5052#include <ui/menu.h>
    51 #include <ui/menubar.h>
    5253#include <ui/menuentry.h>
    5354#include <ui/resource.h>
    5455#include <ui/window.h>
    55 #include "../private/menubar.h"
    5656#include "../private/menu.h"
    5757#include "../private/resource.h"
     
    7878/** Create new menu.
    7979 *
     80 * @param parent Parent window
    8081 * @param mbar Menu bar
    81  * @param caption Caption
    8282 * @param rmenu Place to store pointer to new menu
    8383 * @return EOK on success, ENOMEM if out of memory
    8484 */
    85 errno_t ui_menu_create(ui_menu_bar_t *mbar, const char *caption,
    86     ui_menu_t **rmenu)
     85errno_t ui_menu_create(ui_window_t *parent, ui_menu_t **rmenu)
    8786{
    8887        ui_menu_t *menu;
     
    9291                return ENOMEM;
    9392
    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);
     93        menu->parent = parent;
    10294        list_initialize(&menu->entries);
    10395
     
    124116        }
    125117
    126         list_remove(&menu->lmenus);
    127118        free(menu->caption);
    128119        free(menu);
    129120}
    130121
    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;
     122/** Set menu callbacks.
     123 *
     124 * @param menu Menu
     125 * @param cb Callbacks
     126 * @param arg Callback argument
     127 */
     128void ui_menu_set_cb(ui_menu_t *menu, ui_menu_cb_t *cb, void *arg)
     129{
     130        menu->cb = cb;
     131        menu->arg = arg;
    203132}
    204133
     
    212141    ui_menu_geom_t *geom)
    213142{
    214         ui_resource_t *res;
    215143        gfx_coord2_t edim;
    216144        gfx_coord_t frame_w;
    217145        gfx_coord_t frame_h;
    218 
    219         res = ui_window_get_res(menu->mbar->window);
     146        ui_resource_t *res;
     147
     148        res = ui_window_get_res(menu->parent);
    220149
    221150        if (res->textmode) {
     
    241170}
    242171
    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 
    268172/** Get UI resource from menu.
    269173 *
     
    304208        params.idev_id = idev_id;
    305209
    306         rc = ui_popup_create(menu->mbar->ui, menu->mbar->window, &params,
    307             &popup);
     210        rc = ui_popup_create(ui_window_get_ui(menu->parent), menu->parent,
     211            &params, &popup);
    308212        if (rc != EOK)
    309213                return rc;
     
    503407                /* Press outside menu - close it */
    504408                if (event->type == POS_PRESS)
    505                         ui_menu_bar_deactivate(menu->mbar);
     409                        ui_menu_close_req(menu);
    506410        }
    507411
     
    524428        if (event->type == KEY_PRESS && (event->mods & KM_ALT) != 0 &&
    525429            (event->mods & (KM_CTRL | KM_SHIFT)) == 0 && event->c != '\0')
    526                 ui_menu_bar_press_accel(menu->mbar, event->c, event->kbd_id);
     430                ui_menu_press_accel(menu, event->c, event->kbd_id);
    527431
    528432        return ui_claimed;
     
    615519        switch (event->key) {
    616520        case KC_ESCAPE:
    617                 ui_menu_bar_deactivate(menu->mbar);
     521                ui_menu_close_req(menu);
    618522                break;
    619523        case KC_LEFT:
    620                 ui_menu_bar_left(menu->mbar, event->kbd_id);
     524                ui_menu_left(menu, event->kbd_id);
    621525                break;
    622526        case KC_RIGHT:
    623                 ui_menu_bar_right(menu->mbar, event->kbd_id);
     527                ui_menu_right(menu, event->kbd_id);
    624528                break;
    625529        case KC_UP:
     
    630534                break;
    631535        case KC_ENTER:
    632                 if (menu->selected != NULL)
     536                if (menu->selected != NULL &&
     537                    !ui_menu_entry_is_disabled(menu->selected))
    633538                        ui_menu_entry_activate(menu->selected);
    634539                break;
     
    638543                        while (mentry != NULL) {
    639544                                c = ui_menu_entry_get_accel(mentry);
    640                                 if (c == event->c && menu->selected != NULL) {
     545                                if (c == (char32_t)tolower(event->c) &&
     546                                    !ui_menu_entry_is_disabled(mentry)) {
    641547                                        ui_menu_entry_activate(mentry);
    642548                                        break;
     
    658564        ui_menu_t *menu = (ui_menu_t *)arg;
    659565
    660         /* Deactivate menu bar, close menu */
    661         ui_menu_bar_deactivate(menu->mbar);
     566        /* Forward close request to caller */
     567        ui_menu_close_req(menu);
    662568}
    663569
     
    691597}
    692598
     599/** Send menu left event.
     600 *
     601 * @param menu Menu
     602 * @param idev_id Input device ID
     603 */
     604void ui_menu_left(ui_menu_t *menu, sysarg_t idev_id)
     605{
     606        if (menu->cb != NULL && menu->cb->left != NULL)
     607                menu->cb->left(menu, menu->arg, idev_id);
     608}
     609
     610/** Send menu right event.
     611 *
     612 * @param menu Menu
     613 * @param idev_id Input device ID
     614 */
     615void ui_menu_right(ui_menu_t *menu, sysarg_t idev_id)
     616{
     617        if (menu->cb != NULL && menu->cb->right != NULL)
     618                menu->cb->right(menu, menu->arg, idev_id);
     619}
     620
     621/** Send menu close request event.
     622 *
     623 * @param menu Menu
     624 */
     625void ui_menu_close_req(ui_menu_t *menu)
     626{
     627        if (menu->cb != NULL && menu->cb->close_req != NULL)
     628                menu->cb->close_req(menu, menu->arg);
     629}
     630
     631/** Send menu accelerator key press event.
     632 *
     633 * @param menu Menu
     634 * @param c Character
     635 * @param kbd_id Keyboard ID
     636 */
     637void ui_menu_press_accel(ui_menu_t *menu, char32_t c, sysarg_t kbd_id)
     638{
     639        if (menu->cb != NULL && menu->cb->press_accel != NULL)
     640                menu->cb->press_accel(menu, menu->arg, c, kbd_id);
     641}
     642
    693643/** @}
    694644 */
  • uspace/lib/ui/src/menubar.c

    r42c2e65 rdc5c303  
    3535
    3636#include <adt/list.h>
     37#include <ctype.h>
    3738#include <errno.h>
    3839#include <gfx/color.h>
     
    4546#include <ui/control.h>
    4647#include <ui/paint.h>
    47 #include <ui/menu.h>
    4848#include <ui/menubar.h>
     49#include <ui/menudd.h>
     50#include <ui/wdecor.h>
    4951#include <ui/window.h>
    5052#include "../private/menubar.h"
    5153#include "../private/resource.h"
     54#include "../private/wdecor.h"
     55#include "../private/window.h"
    5256
    5357enum {
     
    9599        mbar->ui = ui;
    96100        mbar->window = window;
    97         list_initialize(&mbar->menus);
     101        list_initialize(&mbar->menudds);
     102
     103        if (window->mbar == NULL)
     104                window->mbar = mbar;
     105
    98106        *rmbar = mbar;
    99107        return EOK;
     
    106114void ui_menu_bar_destroy(ui_menu_bar_t *mbar)
    107115{
    108         ui_menu_t *menu;
     116        ui_menu_dd_t *mdd;
    109117
    110118        if (mbar == NULL)
    111119                return;
    112120
    113         /* Destroy menus */
    114         menu = ui_menu_first(mbar);
    115         while (menu != NULL) {
    116                 ui_menu_destroy(menu);
    117                 menu = ui_menu_first(mbar);
     121        if (mbar->window->mbar == mbar)
     122                mbar->window->mbar = NULL;
     123
     124        /* Destroy menu drop-downs */
     125        mdd = ui_menu_dd_first(mbar);
     126        while (mdd != NULL) {
     127                ui_menu_dd_destroy(mdd);
     128                mdd = ui_menu_dd_first(mbar);
    118129        }
    119130
     
    155166        gfx_rect_t rect;
    156167        gfx_color_t *bg_color;
    157         ui_menu_t *menu;
     168        ui_menu_dd_t *mdd;
    158169        const char *caption;
    159170        gfx_coord_t width;
     
    189200        fmt.valign = gfx_valign_top;
    190201
    191         menu = ui_menu_first(mbar);
    192         while (menu != NULL) {
    193                 caption = ui_menu_caption(menu);
     202        mdd = ui_menu_dd_first(mbar);
     203        while (mdd != NULL) {
     204                caption = ui_menu_dd_caption(mdd);
    194205                width = ui_text_width(res->font, caption) + 2 * hpad;
    195206                tpos.x = pos.x + hpad;
     
    200211                rect.p1.y = mbar->rect.p1.y;
    201212
    202                 if (menu == mbar->selected) {
     213                if (mdd == mbar->selected) {
    203214                        fmt.color = res->wnd_sel_text_color;
    204215                        fmt.hgl_color = res->wnd_sel_text_hgl_color;
     
    223234
    224235                pos.x += width;
    225                 menu = ui_menu_next(menu);
     236                mdd = ui_menu_dd_next(mdd);
    226237        }
    227238
     
    241252 *
    242253 * @param mbar Menu bar
    243  * @param menu Menu to select (or deselect if selected) or @c NULL
     254 * @param mdd Menu drop-down to select (or deselect if selected) or @c NULL
    244255 * @param openup Open menu even if not currently open
    245256 * @param idev_id Input device ID associated with the selecting seat
    246257 */
    247 void ui_menu_bar_select(ui_menu_bar_t *mbar, ui_menu_t *menu, bool openup,
     258void ui_menu_bar_select(ui_menu_bar_t *mbar, ui_menu_dd_t *mdd, bool openup,
    248259    sysarg_t idev_id)
    249260{
    250         ui_menu_t *old_menu;
     261        ui_menu_dd_t *old_mdd;
    251262        gfx_rect_t rect;
    252263        bool was_open;
    253264
    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)) {
     265        old_mdd = mbar->selected;
     266
     267        mbar->selected = mdd;
     268
     269        /* Close previously open menu drop-down */
     270        if (old_mdd != NULL && ui_menu_dd_is_open(old_mdd)) {
    260271                was_open = true;
    261                 (void) ui_menu_close(old_menu);
     272                (void) ui_menu_dd_close(old_mdd);
    262273        } else {
    263274                was_open = false;
     
    270281                if (openup || was_open) {
    271282                        /*
    272                          * Open the newly selected menu if either
    273                          * the old menu was open or @a openup was
     283                         * Open the newly selected menu drop-down if either
     284                         * the old menu drop-down was open or @a openup was
    274285                         * specified.
    275286                         */
    276                         (void) ui_menu_open(mbar->selected, &rect, idev_id);
     287                        (void) ui_menu_dd_open(mbar->selected, &rect, idev_id);
    277288                }
    278         }
     289
     290                mbar->active = true;
     291        } else {
     292                mbar->active = false;
     293        }
     294}
     295
     296/** Select first drop-down.
     297 *
     298 * @param mbar Menu bar
     299 * @param openup @c true to open drop-down if it was not open
     300 * @param idev_id Input device ID
     301 */
     302void ui_menu_bar_select_first(ui_menu_bar_t *mbar, bool openup,
     303    sysarg_t idev_id)
     304{
     305        ui_menu_dd_t *mdd;
     306
     307        mdd = ui_menu_dd_first(mbar);
     308        ui_menu_bar_select(mbar, mdd, openup, idev_id);
     309}
     310
     311/** Select last drop-down.
     312 *
     313 * @param mbar Menu bar
     314 * @param openup @c true to open drop-down if it was not open
     315 * @param idev_id Input device ID
     316 */
     317void ui_menu_bar_select_last(ui_menu_bar_t *mbar, bool openup,
     318    sysarg_t idev_id)
     319{
     320        ui_menu_dd_t *mdd;
     321
     322        mdd = ui_menu_dd_last(mbar);
     323        ui_menu_bar_select(mbar, mdd, openup, idev_id);
     324}
     325
     326/** Select system menu.
     327 *
     328 * @param mbar Menu bar
     329 * @param openup @c true to open drop-down if it was not open
     330 * @param idev_id Input device ID
     331 */
     332void ui_menu_bar_select_sysmenu(ui_menu_bar_t *mbar, bool openup,
     333    sysarg_t idev_id)
     334{
     335        ui_wdecor_sysmenu_hdl_set_active(mbar->window->wdecor, true);
     336
     337        if (openup)
     338                ui_window_send_sysmenu(mbar->window, idev_id);
    279339}
    280340
     
    289349void ui_menu_bar_left(ui_menu_bar_t *mbar, sysarg_t idev_id)
    290350{
    291         ui_menu_t *nmenu;
     351        ui_menu_dd_t *nmdd;
     352        bool sel_sysmenu = false;
     353        bool was_open;
    292354
    293355        if (mbar->selected == NULL)
    294356                return;
    295357
    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);
     358        nmdd = ui_menu_dd_prev(mbar->selected);
     359        if (nmdd == NULL) {
     360                if ((mbar->window->wdecor->style & ui_wds_sysmenu_hdl) != 0) {
     361                        sel_sysmenu = true;
     362                } else {
     363                        nmdd = ui_menu_dd_last(mbar);
     364                }
     365        }
     366
     367        was_open = mbar->selected != NULL &&
     368            ui_menu_dd_is_open(mbar->selected);
     369
     370        if (nmdd != mbar->selected)
     371                ui_menu_bar_select(mbar, nmdd, false, idev_id);
     372
     373        /*
     374         * Only open sysmenu *after* closing the previous menu, avoid
     375         * having multiple popup windows at the same time.
     376         */
     377        if (sel_sysmenu)
     378                ui_menu_bar_select_sysmenu(mbar, was_open, idev_id);
    302379}
    303380
     
    312389void ui_menu_bar_right(ui_menu_bar_t *mbar, sysarg_t idev_id)
    313390{
    314         ui_menu_t *nmenu;
     391        ui_menu_dd_t *nmdd;
     392        bool sel_sysmenu = false;
     393        bool was_open;
    315394
    316395        if (mbar->selected == NULL)
    317396                return;
    318397
    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);
     398        nmdd = ui_menu_dd_next(mbar->selected);
     399        if (nmdd == NULL) {
     400                if ((mbar->window->wdecor->style & ui_wds_sysmenu_hdl) != 0) {
     401                        sel_sysmenu = true;
     402                } else {
     403                        nmdd = ui_menu_dd_first(mbar);
     404                }
     405        }
     406
     407        was_open = mbar->selected != NULL &&
     408            ui_menu_dd_is_open(mbar->selected);
     409
     410        if (nmdd != mbar->selected)
     411                ui_menu_bar_select(mbar, nmdd, false, idev_id);
     412
     413        /*
     414         * Only open sysmenu *after* closing the previous menu, avoid
     415         * having multiple popup windows at the same time.
     416         */
     417        if (sel_sysmenu)
     418                ui_menu_bar_select_sysmenu(mbar, was_open, idev_id);
    325419}
    326420
     
    355449
    356450        if (event->key == KC_ENTER || event->key == KC_DOWN) {
    357                 if (mbar->selected != NULL && !ui_menu_is_open(mbar->selected)) {
     451                if (mbar->selected != NULL &&
     452                    !ui_menu_dd_is_open(mbar->selected)) {
    358453                        ui_menu_bar_entry_rect(mbar, mbar->selected,
    359454                            &rect);
    360                         ui_menu_open(mbar->selected, &rect, event->kbd_id);
     455                        ui_menu_dd_open(mbar->selected, &rect, event->kbd_id);
    361456                }
    362457
     
    364459        }
    365460
    366         if (event->c != '\0' && !ui_menu_is_open(mbar->selected)) {
     461        if (event->c != '\0' && !ui_menu_dd_is_open(mbar->selected)) {
    367462                /* Check if it is an accelerator. */
    368463                ui_menu_bar_press_accel(mbar, event->c, event->kbd_id);
     
    407502void ui_menu_bar_press_accel(ui_menu_bar_t *mbar, char32_t c, sysarg_t kbd_id)
    408503{
    409         ui_menu_t *menu;
     504        ui_menu_dd_t *mdd;
    410505        char32_t maccel;
    411506
    412         menu = ui_menu_first(mbar);
    413         while (menu != NULL) {
    414                 maccel = ui_menu_get_accel(menu);
    415                 if (c == maccel) {
    416                         ui_menu_bar_select(mbar, menu, true, kbd_id);
     507        mdd = ui_menu_dd_first(mbar);
     508        while (mdd != NULL) {
     509                maccel = ui_menu_dd_get_accel(mdd);
     510                if ((char32_t)tolower(c) == maccel) {
     511                        ui_menu_bar_select(mbar, mdd, true, kbd_id);
    417512                        return;
    418513                }
    419514
    420                 menu = ui_menu_next(menu);
     515                mdd = ui_menu_dd_next(mdd);
    421516        }
    422517}
     
    433528        gfx_coord2_t pos;
    434529        gfx_rect_t rect;
    435         ui_menu_t *menu;
     530        ui_menu_dd_t *mdd;
    436531        const char *caption;
    437532        gfx_coord_t width;
     
    454549        pos_id = event->pos_id;
    455550
    456         menu = ui_menu_first(mbar);
    457         while (menu != NULL) {
    458                 caption = ui_menu_caption(menu);
     551        mdd = ui_menu_dd_first(mbar);
     552        while (mdd != NULL) {
     553                caption = ui_menu_dd_caption(mdd);
    459554                width = ui_text_width(res->font, caption) + 2 * hpad;
    460555
     
    468563                        mbar->active = true;
    469564
    470                         /* Open the menu, close if already open. */
    471                         if (menu == mbar->selected)
    472                                 ui_menu_bar_select(mbar, NULL, false, pos_id);
    473                         else
    474                                 ui_menu_bar_select(mbar, menu, true, pos_id);
     565                        /* Open the menu, if not already open. */
     566                        if (mdd != mbar->selected)
     567                                ui_menu_bar_select(mbar, mdd, true, pos_id);
    475568
    476569                        return ui_claimed;
     
    478571
    479572                pos.x += width;
    480                 menu = ui_menu_next(menu);
     573                mdd = ui_menu_dd_next(mdd);
    481574        }
    482575
     
    487580 *
    488581 * @param mbar Menu bar
    489  * @param menu Menu whose entry's rectangle is to be returned
     582 * @param mdd Menu drop-down whose entry's rectangle is to be returned
    490583 * @param rrect Place to store entry rectangle
    491584 */
    492 void ui_menu_bar_entry_rect(ui_menu_bar_t *mbar, ui_menu_t *menu,
     585void ui_menu_bar_entry_rect(ui_menu_bar_t *mbar, ui_menu_dd_t *mdd,
    493586    gfx_rect_t *rrect)
    494587{
     
    496589        gfx_coord2_t pos;
    497590        gfx_rect_t rect;
    498         ui_menu_t *cur;
     591        ui_menu_dd_t *cur;
    499592        const char *caption;
    500593        gfx_coord_t width;
     
    511604        pos = mbar->rect.p0;
    512605
    513         cur = ui_menu_first(mbar);
     606        cur = ui_menu_dd_first(mbar);
    514607        while (cur != NULL) {
    515                 caption = ui_menu_caption(cur);
     608                caption = ui_menu_dd_caption(cur);
    516609                width = ui_text_width(res->font, caption) + 2 * hpad;
    517610
     
    520613                rect.p1.y = mbar->rect.p1.y;
    521614
    522                 if (cur == menu) {
     615                if (cur == mdd) {
    523616                        *rrect = rect;
    524617                        return;
     
    526619
    527620                pos.x += width;
    528                 cur = ui_menu_next(cur);
     621                cur = ui_menu_dd_next(cur);
    529622        }
    530623
     
    544637        mbar->active = true;
    545638        if (mbar->selected == NULL)
    546                 mbar->selected = ui_menu_first(mbar);
     639                mbar->selected = ui_menu_dd_first(mbar);
    547640
    548641        (void) ui_menu_bar_paint(mbar);
    549642}
    550643
     644/** Deactivate menu bar.
     645 *
     646 * @param mbar Menu bar
     647 */
    551648void ui_menu_bar_deactivate(ui_menu_bar_t *mbar)
    552649{
    553650        ui_menu_bar_select(mbar, NULL, false, 0);
    554         mbar->active = false;
    555651}
    556652
  • uspace/lib/ui/src/menuentry.c

    r42c2e65 rdc5c303  
    11/*
    2  * Copyright (c) 2022 Jiri Svoboda
     2 * Copyright (c) 2023 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    163163}
    164164
     165/** Set menu entry disabled flag.
     166 *
     167 * @param mentry Menu entry
     168 * @param disabled @c true iff entry is to be disabled, @c false otherwise
     169 */
     170void ui_menu_entry_set_disabled(ui_menu_entry_t *mentry, bool disabled)
     171{
     172        mentry->disabled = disabled;
     173}
     174
     175/** Get menu entry disabled flag.
     176 *
     177 * @param mentry Menu entry
     178 * @return disabled @c true iff entry is disabled, @c false otherwise
     179 */
     180bool ui_menu_entry_is_disabled(ui_menu_entry_t *mentry)
     181{
     182        return mentry->disabled;
     183}
     184
    165185/** Get first menu entry in menu.
    166186 *
     
    241261         * This needs to work even if the menu is not open, so we cannot
    242262         * 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
     263         * is open (and its window is created). Use the parent window's
    244264         * resource instead.
    245265         */
    246         res = ui_window_get_res(mentry->menu->mbar->window);
     266        res = ui_window_get_res(mentry->menu->parent);
    247267
    248268        *caption_w = ui_text_width(res->font, mentry->caption);
     
    267287         * This needs to work even if the menu is not open, so we cannot
    268288         * 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
     289         * is open (and its window is created). Use the parent window's
    270290         * resource instead.
    271291         */
    272         res = ui_window_get_res(menu->mbar->window);
     292        res = ui_window_get_res(menu->parent);
    273293
    274294        if (res->textmode)
     
    306326         * This needs to work even if the menu is not open, so we cannot
    307327         * 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
     328         * is open (and its window is created). Use the parent window's
    309329         * resource instead.
    310330         */
    311         res = ui_window_get_res(mentry->menu->mbar->window);
     331        res = ui_window_get_res(mentry->menu->parent);
    312332
    313333        if (res->textmode) {
     
    372392                fmt.hgl_color = res->wnd_sel_text_hgl_color;
    373393                bg_color = res->wnd_sel_text_bg_color;
     394        } else if (mentry->disabled) {
     395                fmt.color = res->wnd_dis_text_color;
     396                fmt.hgl_color = res->wnd_dis_text_color;
     397                bg_color = res->wnd_face_color;
    374398        } else {
    375399                fmt.color = res->wnd_text_color;
     
    445469                return;
    446470
    447         if (mentry->separator)
     471        if (mentry->separator || mentry->disabled)
    448472                return;
    449473
     
    474498void ui_menu_entry_activate(ui_menu_entry_t *mentry)
    475499{
    476         /* Deactivate menu bar, close menu */
    477         ui_menu_bar_deactivate(mentry->menu->mbar);
     500        /* Close menu */
     501        ui_menu_close_req(mentry->menu);
    478502
    479503        /* Call back */
  • uspace/lib/ui/src/popup.c

    r42c2e65 rdc5c303  
    9898        wparams.style &= ~ui_wds_decorated;
    9999        wparams.placement = ui_wnd_place_popup;
    100         wparams.flags |= ui_wndf_popup;
     100        wparams.flags |= ui_wndf_popup | ui_wndf_topmost;
    101101        wparams.idev_id = params->idev_id;
    102102
  • uspace/lib/ui/src/promptdialog.c

    r42c2e65 rdc5c303  
    327327{
    328328        ui_prompt_dialog_t *dialog = (ui_prompt_dialog_t *) arg;
    329         const char *fname;
     329        const char *text;
    330330
    331331        if (event->type == KEY_PRESS &&
     
    334334                        /* Confirm */
    335335                        if (dialog->cb != NULL && dialog->cb->bok != NULL) {
    336                                 fname = ui_entry_get_text(dialog->ename);
    337                                 dialog->cb->bok(dialog, dialog->arg, fname);
     336                                text = ui_entry_get_text(dialog->ename);
     337                                dialog->cb->bok(dialog, dialog->arg, text);
    338338                                return;
    339339                        }
     
    358358{
    359359        ui_prompt_dialog_t *dialog = (ui_prompt_dialog_t *) arg;
    360         const char *fname;
     360        const char *text;
    361361
    362362        if (dialog->cb != NULL && dialog->cb->bok != NULL) {
    363                 fname = ui_entry_get_text(dialog->ename);
    364                 dialog->cb->bok(dialog, dialog->arg, fname);
     363                text = ui_entry_get_text(dialog->ename);
     364                dialog->cb->bok(dialog, dialog->arg, text);
    365365        }
    366366}
  • uspace/lib/ui/src/resource.c

    r42c2e65 rdc5c303  
    6868        gfx_color_t *wnd_face_color = NULL;
    6969        gfx_color_t *wnd_text_color = NULL;
     70        gfx_color_t *wnd_dis_text_color = NULL;
    7071        gfx_color_t *wnd_text_hgl_color = NULL;
    7172        gfx_color_t *wnd_sel_text_color = NULL;
     
    8586        gfx_color_t *entry_sel_text_fg_color = NULL;
    8687        gfx_color_t *entry_sel_text_bg_color = NULL;
    87         gfx_color_t *sbar_through_color = NULL;
    88         gfx_color_t *sbar_act_through_color = NULL;
     88        gfx_color_t *sbar_trough_color = NULL;
     89        gfx_color_t *sbar_act_trough_color = NULL;
    8990        errno_t rc;
    9091
     
    140141                goto error;
    141142
     143        rc = gfx_color_new_rgb_i16(0x9696, 0x9696, 0x9696, &wnd_dis_text_color);
     144        if (rc != EOK)
     145                goto error;
     146
    142147        rc = gfx_color_new_rgb_i16(0, 0, 0, &wnd_text_hgl_color);
    143148        if (rc != EOK)
     
    216221
    217222        rc = gfx_color_new_rgb_i16(0xe4e4, 0xe4e4, 0xe4e4,
    218             &sbar_through_color);
     223            &sbar_trough_color);
    219224        if (rc != EOK)
    220225                goto error;
    221226
    222227        rc = gfx_color_new_rgb_i16(0x5858, 0x5858, 0x5858,
    223             &sbar_act_through_color);
     228            &sbar_act_trough_color);
    224229        if (rc != EOK)
    225230                goto error;
     
    239244        resource->wnd_face_color = wnd_face_color;
    240245        resource->wnd_text_color = wnd_text_color;
     246        resource->wnd_dis_text_color = wnd_dis_text_color;
    241247        resource->wnd_text_hgl_color = wnd_text_hgl_color;
    242248        resource->wnd_sel_text_color = wnd_sel_text_color;
     
    259265        resource->entry_sel_text_bg_color = entry_sel_text_bg_color;
    260266
    261         resource->sbar_through_color = sbar_through_color;
    262         resource->sbar_act_through_color = sbar_act_through_color;
     267        resource->sbar_trough_color = sbar_trough_color;
     268        resource->sbar_act_trough_color = sbar_act_trough_color;
    263269
    264270        *rresource = resource;
     
    282288        if (wnd_text_color != NULL)
    283289                gfx_color_delete(wnd_text_color);
     290        if (wnd_dis_text_color != NULL)
     291                gfx_color_delete(wnd_dis_text_color);
    284292        if (wnd_text_hgl_color != NULL)
    285293                gfx_color_delete(wnd_text_hgl_color);
     
    319327                gfx_color_delete(entry_act_bg_color);
    320328
    321         if (sbar_through_color != NULL)
    322                 gfx_color_delete(sbar_through_color);
    323         if (sbar_act_through_color != NULL)
    324                 gfx_color_delete(sbar_act_through_color);
     329        if (sbar_trough_color != NULL)
     330                gfx_color_delete(sbar_trough_color);
     331        if (sbar_act_trough_color != NULL)
     332                gfx_color_delete(sbar_act_trough_color);
    325333
    326334        if (tface != NULL)
     
    350358        gfx_color_t *wnd_face_color = NULL;
    351359        gfx_color_t *wnd_text_color = NULL;
     360        gfx_color_t *wnd_dis_text_color = NULL;
    352361        gfx_color_t *wnd_text_hgl_color = NULL;
    353362        gfx_color_t *wnd_sel_text_color = NULL;
     
    367376        gfx_color_t *entry_sel_text_bg_color = NULL;
    368377        gfx_color_t *entry_act_bg_color = NULL;
    369         gfx_color_t *sbar_through_color = NULL;
    370         gfx_color_t *sbar_act_through_color = NULL;
     378        gfx_color_t *sbar_trough_color = NULL;
     379        gfx_color_t *sbar_act_trough_color = NULL;
    371380        errno_t rc;
    372381
     
    416425                goto error;
    417426
     427        rc = gfx_color_new_ega(0x78, &wnd_dis_text_color);
     428        if (rc != EOK)
     429                goto error;
     430
    418431        rc = gfx_color_new_ega(0x74, &wnd_text_hgl_color);
    419432        if (rc != EOK)
     
    484497                goto error;
    485498
    486         rc = gfx_color_new_ega(0x07, &sbar_through_color);
    487         if (rc != EOK)
    488                 goto error;
    489 
    490         rc = gfx_color_new_ega(0x07, &sbar_act_through_color);
     499        rc = gfx_color_new_ega(0x07, &sbar_trough_color);
     500        if (rc != EOK)
     501                goto error;
     502
     503        rc = gfx_color_new_ega(0x07, &sbar_act_trough_color);
    491504        if (rc != EOK)
    492505                goto error;
     
    506519        resource->wnd_face_color = wnd_face_color;
    507520        resource->wnd_text_color = wnd_text_color;
     521        resource->wnd_dis_text_color = wnd_dis_text_color;
    508522        resource->wnd_text_hgl_color = wnd_text_hgl_color;
    509523        resource->wnd_sel_text_color = wnd_sel_text_color;
     
    526540        resource->entry_sel_text_bg_color = entry_sel_text_bg_color;
    527541
    528         resource->sbar_through_color = sbar_through_color;
    529         resource->sbar_act_through_color = sbar_act_through_color;
     542        resource->sbar_trough_color = sbar_trough_color;
     543        resource->sbar_act_trough_color = sbar_act_trough_color;
    530544
    531545        *rresource = resource;
     
    549563        if (wnd_text_color != NULL)
    550564                gfx_color_delete(wnd_text_color);
     565        if (wnd_dis_text_color != NULL)
     566                gfx_color_delete(wnd_dis_text_color);
    551567        if (wnd_text_hgl_color != NULL)
    552568                gfx_color_delete(wnd_text_hgl_color);
     
    585601        if (entry_sel_text_bg_color != NULL)
    586602                gfx_color_delete(entry_sel_text_bg_color);
    587         if (sbar_through_color != NULL)
    588                 gfx_color_delete(sbar_through_color);
    589         if (sbar_act_through_color != NULL)
    590                 gfx_color_delete(sbar_act_through_color);
     603        if (sbar_trough_color != NULL)
     604                gfx_color_delete(sbar_trough_color);
     605        if (sbar_act_trough_color != NULL)
     606                gfx_color_delete(sbar_act_trough_color);
    591607
    592608        if (tface != NULL)
     
    630646        gfx_color_delete(resource->wnd_face_color);
    631647        gfx_color_delete(resource->wnd_text_color);
     648        gfx_color_delete(resource->wnd_dis_text_color);
    632649        gfx_color_delete(resource->wnd_sel_text_color);
    633650        gfx_color_delete(resource->wnd_sel_text_bg_color);
     
    648665        gfx_color_delete(resource->entry_sel_text_bg_color);
    649666
    650         gfx_color_delete(resource->sbar_through_color);
    651         gfx_color_delete(resource->sbar_act_through_color);
     667        gfx_color_delete(resource->sbar_trough_color);
     668        gfx_color_delete(resource->sbar_act_trough_color);
    652669
    653670        gfx_font_close(resource->font);
  • uspace/lib/ui/src/scrollbar.c

    r42c2e65 rdc5c303  
    11/*
    2  * Copyright (c) 2022 Jiri Svoboda
     2 * Copyright (c) 2023 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3535 * Anatomy of a horizontal scrollbar:
    3636 *
    37  *       Up                Down
    38  *      through           through
    39  * +---+------+--------+---------+---+
    40  * | < |      |   |||  |         | > |
    41  * +---+------+--------+---------+---+
    42  *  Up           Thumb           Down
    43  * button                       button
    44  *
    45  *     +-------- Through --------+
     37 *        Upper             Lower
     38 *       trough            trough
     39 *  +---+------+--------+---------+---+
     40 *  | < |      |   |||  |         | > |
     41 *  +---+------+--------+---------+---+
     42 *   Up           Thumb           Down
     43 * button                        button
     44 *
     45 *     +-------- Trough --------+
    4646 *
    4747 * Scrollbar uses the same terminology whether it is running in horizontal
     
    5151 * The thumb can be dragged to a specific position, resulting in a move
    5252 * event. The up/down buttons generate up/down events. Pressing a mouse
    53  * button on the up/down through generates page up / page down events.
    54  *
    55  * Pressing and holding down mouse button on up / down button or up / down
    56  * through will auto-scroll (using clickmatic).
     53 * button on the upper/lower trough generates page up / page down events.
     54 *
     55 * Pressing and holding down mouse button on up / down button or upper /
     56 * lower trough will auto-scroll (using clickmatic).
    5757 */
    5858
     
    360360}
    361361
    362 /** Determine scrollbar through length.
     362/** Determine scrollbar trough length.
    363363 *
    364364 * Return the size of the space within which the thumb can move
     
    366366 *
    367367 * @param scrollbar Scrollbar
    368  * @return Scrollbar through length in pixels
    369  */
    370 gfx_coord_t ui_scrollbar_through_length(ui_scrollbar_t *scrollbar)
     368 * @return Scrollbar trough length in pixels
     369 */
     370gfx_coord_t ui_scrollbar_trough_length(ui_scrollbar_t *scrollbar)
    371371{
    372372        ui_resource_t *resource;
     
    396396gfx_coord_t ui_scrollbar_move_length(ui_scrollbar_t *scrollbar)
    397397{
    398         return ui_scrollbar_through_length(scrollbar) -
     398        return ui_scrollbar_trough_length(scrollbar) -
    399399            scrollbar->thumb_len;
    400400}
     
    417417            ui_scrollbar_min_thumb_len;
    418418
    419         max_len = ui_scrollbar_through_length(scrollbar);
     419        max_len = ui_scrollbar_trough_length(scrollbar);
    420420        if (len < min_len)
    421421                len = min_len;
     
    459459                scrollbar->pos = pos;
    460460                (void) ui_scrollbar_paint(scrollbar);
    461                 ui_scrollbar_throughs_update(scrollbar,
     461                ui_scrollbar_troughs_update(scrollbar,
    462462                    &scrollbar->last_curs_pos);
    463463        }
     
    487487                goto error;
    488488
    489         /* Paint scrollbar up through */
     489        /* Paint scrollbar upper trough */
    490490        rc = gfx_set_color(resource->gc,
    491             scrollbar->up_through_held && scrollbar->up_through_inside ?
    492             resource->sbar_act_through_color :
    493             resource->sbar_through_color);
    494         if (rc != EOK)
    495                 goto error;
    496 
    497         rc = gfx_fill_rect(resource->gc, &geom.up_through_rect);
    498         if (rc != EOK)
    499                 goto error;
    500 
    501         /* Paint scrollbar down through */
     491            scrollbar->upper_trough_held && scrollbar->upper_trough_inside ?
     492            resource->sbar_act_trough_color :
     493            resource->sbar_trough_color);
     494        if (rc != EOK)
     495                goto error;
     496
     497        rc = gfx_fill_rect(resource->gc, &geom.upper_trough_rect);
     498        if (rc != EOK)
     499                goto error;
     500
     501        /* Paint scrollbar lower trough */
    502502
    503503        rc = gfx_set_color(resource->gc,
    504             scrollbar->down_through_held && scrollbar->down_through_inside ?
    505             resource->sbar_act_through_color :
    506             resource->sbar_through_color);
    507         if (rc != EOK)
    508                 goto error;
    509 
    510         rc = gfx_fill_rect(resource->gc, &geom.down_through_rect);
     504            scrollbar->lower_trough_held && scrollbar->lower_trough_inside ?
     505            resource->sbar_act_trough_color :
     506            resource->sbar_trough_color);
     507        if (rc != EOK)
     508                goto error;
     509
     510        rc = gfx_fill_rect(resource->gc, &geom.lower_trough_rect);
    511511        if (rc != EOK)
    512512                goto error;
     
    561561        ui_scrollbar_get_geom(scrollbar, &geom);
    562562
    563         /* Paint scrollbar through */
    564 
    565         rc = ui_paint_text_rect(resource, &geom.through_rect,
    566             resource->sbar_through_color, "\u2592");
     563        /* Paint scrollbar trough */
     564
     565        rc = ui_paint_text_rect(resource, &geom.trough_rect,
     566            resource->sbar_trough_color, "\u2592");
    567567        if (rc != EOK)
    568568                goto error;
     
    571571
    572572        rc = ui_paint_text_rect(resource, &geom.thumb_rect,
    573             resource->sbar_through_color, "\u25a0");
     573            resource->sbar_trough_color, "\u25a0");
    574574        if (rc != EOK)
    575575                goto error;
     
    647647                geom->up_btn_rect.p1.y = orect.p1.y;
    648648
    649                 /* Through */
    650                 geom->through_rect.p0.x = geom->up_btn_rect.p1.x;
    651                 geom->through_rect.p0.y = irect.p0.y;
    652                 geom->through_rect.p1.x = orect.p1.x - btn_len;
    653                 geom->through_rect.p1.y = irect.p1.y;
     649                /* Trough */
     650                geom->trough_rect.p0.x = geom->up_btn_rect.p1.x;
     651                geom->trough_rect.p0.y = irect.p0.y;
     652                geom->trough_rect.p1.x = orect.p1.x - btn_len;
     653                geom->trough_rect.p1.y = irect.p1.y;
    654654
    655655                /* Thumb */
     
    661661                geom->thumb_rect.p1.y = orect.p1.y;
    662662
    663                 /* Up through */
    664                 geom->up_through_rect.p0 = geom->through_rect.p0;
    665                 geom->up_through_rect.p1.x = geom->thumb_rect.p0.x;
    666                 geom->up_through_rect.p1.y = geom->through_rect.p1.y;
    667 
    668                 /* Down through */
    669                 geom->down_through_rect.p0.x = geom->thumb_rect.p1.x;
    670                 geom->down_through_rect.p0.y = geom->through_rect.p0.y;
    671                 geom->down_through_rect.p1 = geom->through_rect.p1;
     663                /* Upper trough */
     664                geom->upper_trough_rect.p0 = geom->trough_rect.p0;
     665                geom->upper_trough_rect.p1.x = geom->thumb_rect.p0.x;
     666                geom->upper_trough_rect.p1.y = geom->trough_rect.p1.y;
     667
     668                /* Lower trough */
     669                geom->lower_trough_rect.p0.x = geom->thumb_rect.p1.x;
     670                geom->lower_trough_rect.p0.y = geom->trough_rect.p0.y;
     671                geom->lower_trough_rect.p1 = geom->trough_rect.p1;
    672672
    673673                /* Down button */
    674                 geom->down_btn_rect.p0.x = geom->through_rect.p1.x;
     674                geom->down_btn_rect.p0.x = geom->trough_rect.p1.x;
    675675                geom->down_btn_rect.p0.y = orect.p0.y;
    676676                geom->down_btn_rect.p1.x = orect.p1.x;
     
    683683                geom->up_btn_rect.p1.y = orect.p0.y + btn_len;
    684684
    685                 /* Through */
    686                 geom->through_rect.p0.x = irect.p0.x;
    687                 geom->through_rect.p0.y = geom->up_btn_rect.p1.y;
    688                 geom->through_rect.p1.x = irect.p1.x;
    689                 geom->through_rect.p1.y = orect.p1.y - btn_len;
     685                /* Trough */
     686                geom->trough_rect.p0.x = irect.p0.x;
     687                geom->trough_rect.p0.y = geom->up_btn_rect.p1.y;
     688                geom->trough_rect.p1.x = irect.p1.x;
     689                geom->trough_rect.p1.y = orect.p1.y - btn_len;
    690690
    691691                /* Thumb */
     
    697697                    scrollbar->thumb_len;
    698698
    699                 /* Up through */
    700                 geom->up_through_rect.p0 = geom->through_rect.p0;
    701                 geom->up_through_rect.p1.x = geom->through_rect.p1.x;
    702                 geom->up_through_rect.p1.y = geom->thumb_rect.p0.y;
    703 
    704                 /* Down through */
    705                 geom->down_through_rect.p0.x = geom->through_rect.p0.x;
    706                 geom->down_through_rect.p0.y = geom->thumb_rect.p1.y;
    707                 geom->down_through_rect.p1 = geom->through_rect.p1;
     699                /* Upper trough */
     700                geom->upper_trough_rect.p0 = geom->trough_rect.p0;
     701                geom->upper_trough_rect.p1.x = geom->trough_rect.p1.x;
     702                geom->upper_trough_rect.p1.y = geom->thumb_rect.p0.y;
     703
     704                /* Lower trough */
     705                geom->lower_trough_rect.p0.x = geom->trough_rect.p0.x;
     706                geom->lower_trough_rect.p0.y = geom->thumb_rect.p1.y;
     707                geom->lower_trough_rect.p1 = geom->trough_rect.p1;
    708708
    709709                /* Down button */
    710710                geom->down_btn_rect.p0.x = orect.p0.x;
    711                 geom->down_btn_rect.p0.y = geom->through_rect.p1.y;
     711                geom->down_btn_rect.p0.y = geom->trough_rect.p1.y;
    712712                geom->down_btn_rect.p1.x = orect.p1.x;
    713713                geom->down_btn_rect.p1.y = orect.p1.y;
     
    732732}
    733733
    734 /** Press down scrollbar up through.
    735  *
    736  * @param scrollbar Scrollbar
    737  */
    738 void ui_scrollbar_up_through_press(ui_scrollbar_t *scrollbar)
     734/** Press down scrollbar upper trough.
     735 *
     736 * @param scrollbar Scrollbar
     737 */
     738void ui_scrollbar_upper_trough_press(ui_scrollbar_t *scrollbar)
    739739{
    740740        ui_clickmatic_t *clickmatic = ui_get_clickmatic(scrollbar->ui);
    741741
    742         scrollbar->up_through_held = true;
    743         scrollbar->up_through_inside = true;
     742        scrollbar->upper_trough_held = true;
     743        scrollbar->upper_trough_inside = true;
    744744
    745745        ui_clickmatic_set_cb(clickmatic, &ui_scrollbar_clickmatic_page_up_cb,
     
    748748}
    749749
    750 /** Press down scrollbar down through.
    751  *
    752  * @param scrollbar Scrollbar
    753  */
    754 void ui_scrollbar_down_through_press(ui_scrollbar_t *scrollbar)
     750/** Press down scrollbar lower trough.
     751 *
     752 * @param scrollbar Scrollbar
     753 */
     754void ui_scrollbar_lower_trough_press(ui_scrollbar_t *scrollbar)
    755755{
    756756        ui_clickmatic_t *clickmatic = ui_get_clickmatic(scrollbar->ui);
    757757
    758         scrollbar->down_through_held = true;
    759         scrollbar->down_through_inside = true;
     758        scrollbar->lower_trough_held = true;
     759        scrollbar->lower_trough_inside = true;
    760760
    761761        ui_clickmatic_set_cb(clickmatic, &ui_scrollbar_clickmatic_page_down_cb,
     
    778778        }
    779779
    780         if (scrollbar->up_through_held || scrollbar->down_through_held) {
     780        if (scrollbar->upper_trough_held || scrollbar->lower_trough_held) {
    781781                clickmatic = ui_get_clickmatic(scrollbar->ui);
    782782                ui_clickmatic_release(clickmatic);
    783783                ui_clickmatic_set_cb(clickmatic, NULL, NULL);
    784784
    785                 scrollbar->up_through_held = false;
    786                 scrollbar->down_through_held = false;
     785                scrollbar->upper_trough_held = false;
     786                scrollbar->lower_trough_held = false;
    787787                (void) ui_scrollbar_paint(scrollbar);
    788788        }
     
    791791/** Update state of scrollbar throuhgs.
    792792 *
    793  * Update state of scrollbar throughs after mouse cursor or thumb has moved.
     793 * Update state of scrollbar troughs after mouse cursor or thumb has moved.
    794794 *
    795795 * @param scrollbar Scrollbar
    796796 * @param pos Mouse cursor position
    797797 */
    798 void ui_scrollbar_throughs_update(ui_scrollbar_t *scrollbar, gfx_coord2_t *pos)
     798void ui_scrollbar_troughs_update(ui_scrollbar_t *scrollbar, gfx_coord2_t *pos)
    799799{
    800800        ui_scrollbar_geom_t geom;
     
    804804        ui_scrollbar_get_geom(scrollbar, &geom);
    805805
    806         inside_up = gfx_pix_inside_rect(pos, &geom.up_through_rect);
    807         inside_down = gfx_pix_inside_rect(pos, &geom.down_through_rect);
    808 
    809         if (inside_up && !scrollbar->up_through_inside) {
    810                 scrollbar->up_through_inside = true;
     806        inside_up = gfx_pix_inside_rect(pos, &geom.upper_trough_rect);
     807        inside_down = gfx_pix_inside_rect(pos, &geom.lower_trough_rect);
     808
     809        if (inside_up && !scrollbar->upper_trough_inside) {
     810                scrollbar->upper_trough_inside = true;
    811811                (void) ui_scrollbar_paint(scrollbar);
    812         } else if (!inside_up && scrollbar->up_through_inside) {
    813                 scrollbar->up_through_inside = false;
     812        } else if (!inside_up && scrollbar->upper_trough_inside) {
     813                scrollbar->upper_trough_inside = false;
    814814                (void) ui_scrollbar_paint(scrollbar);
    815815        }
    816816
    817         if (inside_down && !scrollbar->down_through_inside) {
    818                 scrollbar->down_through_inside = true;
     817        if (inside_down && !scrollbar->lower_trough_inside) {
     818                scrollbar->lower_trough_inside = true;
    819819                (void) ui_scrollbar_paint(scrollbar);
    820         } else if (!inside_down && scrollbar->down_through_inside) {
    821                 scrollbar->down_through_inside = false;
     820        } else if (!inside_down && scrollbar->lower_trough_inside) {
     821                scrollbar->lower_trough_inside = false;
    822822                (void) ui_scrollbar_paint(scrollbar);
    823823        }
     
    843843        }
    844844
    845         ui_scrollbar_throughs_update(scrollbar, pos);
     845        ui_scrollbar_troughs_update(scrollbar, pos);
    846846}
    847847
     
    866866}
    867867
    868 /** Scrollbar up through was pressed.
     868/** Scrollbar upper trough was pressed.
    869869 *
    870870 * @param scrollbar Scrollbar
     
    876876}
    877877
    878 /** Scrollbar down through was pressed.
     878/** Scrollbar lower trough was pressed.
    879879 *
    880880 * @param scrollbar Scrollbar
     
    927927                        return ui_claimed;
    928928                }
    929                 if (gfx_pix_inside_rect(&pos, &geom.up_through_rect)) {
    930                         ui_scrollbar_up_through_press(scrollbar);
     929                if (gfx_pix_inside_rect(&pos, &geom.upper_trough_rect)) {
     930                        ui_scrollbar_upper_trough_press(scrollbar);
    931931                        return ui_claimed;
    932932                }
    933                 if (gfx_pix_inside_rect(&pos, &geom.down_through_rect)) {
    934                         ui_scrollbar_down_through_press(scrollbar);
     933                if (gfx_pix_inside_rect(&pos, &geom.lower_trough_rect)) {
     934                        ui_scrollbar_lower_trough_press(scrollbar);
    935935                        return ui_claimed;
    936936                }
    937937                break;
    938938        case POS_RELEASE:
    939                 if (scrollbar->thumb_held || scrollbar->up_through_held ||
    940                     scrollbar->down_through_held) {
     939                if (scrollbar->thumb_held || scrollbar->upper_trough_held ||
     940                    scrollbar->lower_trough_held) {
    941941                        ui_scrollbar_release(scrollbar, &pos);
    942942                        return ui_claimed;
     
    11181118}
    11191119
    1120 /** Scrollbar clickmatic up through click event.
     1120/** Scrollbar clickmatic upper trough click event.
    11211121 *
    11221122 * @param clickmatic Clickmatic
     
    11271127        ui_scrollbar_t *scrollbar = (ui_scrollbar_t *)arg;
    11281128
    1129         if (scrollbar->up_through_inside)
     1129        if (scrollbar->upper_trough_inside)
    11301130                ui_scrollbar_page_up(scrollbar);
    11311131}
    11321132
    1133 /** Scrollbar clickmatic down through click event.
     1133/** Scrollbar clickmatic lower trough click event.
    11341134 *
    11351135 * @param clickmatic Clickmatic
     
    11401140        ui_scrollbar_t *scrollbar = (ui_scrollbar_t *)arg;
    11411141
    1142         if (scrollbar->down_through_inside)
     1142        if (scrollbar->lower_trough_inside)
    11431143                ui_scrollbar_page_down(scrollbar);
    11441144}
  • uspace/lib/ui/src/ui.c

    r42c2e65 rdc5c303  
    338338        switch (event->type) {
    339339        case CEV_KEY:
     340                ui_lock(ui);
    340341                ui_window_send_kbd(awnd, &event->ev.key);
     342                ui_unlock(ui);
    341343                break;
    342344        case CEV_POS:
     
    348350                claim = ui_wdecor_pos_event(awnd->wdecor, &pos);
    349351                /* Note: If event is claimed, awnd might not be valid anymore */
    350                 if (claim == ui_unclaimed)
     352                if (claim == ui_unclaimed) {
     353                        ui_lock(ui);
    351354                        ui_window_send_pos(awnd, &pos);
     355                        ui_unlock(ui);
     356                }
    352357
    353358                break;
     
    454459errno_t ui_suspend(ui_t *ui)
    455460{
    456         if (ui->cgc == NULL)
     461        errno_t rc;
     462
     463        assert(!ui->suspended);
     464
     465        if (ui->cgc == NULL) {
     466                ui->suspended = true;
    457467                return EOK;
     468        }
    458469
    459470        (void) console_set_caption(ui->console, "");
    460         return console_gc_suspend(ui->cgc);
     471        rc = console_gc_suspend(ui->cgc);
     472        if (rc != EOK)
     473                return rc;
     474
     475        ui->suspended = true;
     476        return EOK;
    461477}
    462478
     
    477493        cons_event_t ev;
    478494
    479         if (ui->cgc == NULL)
     495        assert(ui->suspended);
     496
     497        if (ui->cgc == NULL) {
     498                ui->suspended = false;
    480499                return EOK;
     500        }
    481501
    482502        rc = console_get_pos(ui->console, &col, &row);
     
    510530                return rc;
    511531
     532        ui->suspended = false;
     533
    512534        awnd = ui_window_get_active(ui);
    513535        if (awnd != NULL)
    514536                (void) console_set_caption(ui->console, awnd->wdecor->caption);
    515537
    516         return gfx_cursor_set_visible(console_gc_get_ctx(ui->cgc), false);
     538        rc = gfx_cursor_set_visible(console_gc_get_ctx(ui->cgc), false);
     539        if (rc != EOK)
     540                return rc;
     541
     542        return EOK;
     543}
     544
     545/** Determine if UI is suspended.
     546 *
     547 * @param ui UI
     548 * @return @c true iff UI is suspended
     549 */
     550bool ui_is_suspended(ui_t *ui)
     551{
     552        return ui->suspended;
    517553}
    518554
  • uspace/lib/ui/src/wdecor.c

    r42c2e65 rdc5c303  
    104104        /** Window caption horizontal margin in text mode */
    105105        wdecor_cap_hmargin_text = 1,
     106        /** System menu handle width */
     107        wdecor_sysmenu_hdl_w = 20,
     108        /** System menu handle height */
     109        wdecor_sysmenu_hdl_h = 20,
     110        /** System menu handle width in text mode */
     111        wdecor_sysmenu_hdl_w_text = 3,
     112        /** System menu handle height in text mode */
     113        wdecor_sysmenu_hdl_h_text = 1,
    106114        /** Close button cross leg length */
    107115        wdecor_close_cross_n = 5,
     
    296304}
    297305
     306/** Paint system menu handle in graphics mode.
     307 *
     308 * @param wdecor Window decoration
     309 * @param rect System menu handle rectangle
     310 * @return EOK on success or an error code
     311 */
     312errno_t ui_wdecor_sysmenu_hdl_paint_gfx(ui_wdecor_t *wdecor, gfx_rect_t *rect)
     313{
     314        errno_t rc;
     315        gfx_rect_t mrect;
     316        gfx_rect_t inside;
     317        gfx_coord2_t center;
     318
     319        rc = gfx_set_color(wdecor->res->gc, wdecor->sysmenu_hdl_active ?
     320            wdecor->res->btn_shadow_color : wdecor->res->btn_face_color);
     321        if (rc != EOK)
     322                return rc;
     323
     324        rc = gfx_fill_rect(wdecor->res->gc, rect);
     325        if (rc != EOK)
     326                return rc;
     327
     328        center.x = (rect->p0.x + rect->p1.x) / 2;
     329        center.y = (rect->p0.y + rect->p1.y) / 2;
     330        mrect.p0.x = center.x - 7;
     331        mrect.p0.y = center.y - 1;
     332        mrect.p1.x = center.x + 7;
     333        mrect.p1.y = center.y + 1 + 1;
     334
     335        /* XXX Not really a bevel, just a frame */
     336        rc = ui_paint_bevel(wdecor->res->gc, &mrect,
     337            wdecor->res->btn_text_color, wdecor->res->btn_text_color, 1,
     338            &inside);
     339        if (rc != EOK)
     340                return rc;
     341
     342        rc = gfx_set_color(wdecor->res->gc, wdecor->res->btn_highlight_color);
     343        if (rc != EOK)
     344                return rc;
     345
     346        rc = gfx_fill_rect(wdecor->res->gc, &inside);
     347        if (rc != EOK)
     348                return rc;
     349
     350        return EOK;
     351}
     352
     353/** Paint system menu handle in text mode.
     354 *
     355 * @param wdecor Window decoration
     356 * @param rect System menu handle rectangle
     357 * @return EOK on success or an error code
     358 */
     359errno_t ui_wdecor_sysmenu_hdl_paint_text(ui_wdecor_t *wdecor, gfx_rect_t *rect)
     360{
     361        errno_t rc;
     362        gfx_text_fmt_t fmt;
     363
     364        rc = gfx_set_color(wdecor->res->gc, wdecor->sysmenu_hdl_active ?
     365            wdecor->res->btn_shadow_color : wdecor->res->btn_face_color);
     366
     367        gfx_text_fmt_init(&fmt);
     368        fmt.font = wdecor->res->font;
     369        fmt.color = wdecor->sysmenu_hdl_active ?
     370            wdecor->res->wnd_sel_text_color :
     371            wdecor->res->tbar_act_text_color;
     372        fmt.halign = gfx_halign_left;
     373        fmt.valign = gfx_valign_top;
     374
     375        rc = gfx_puttext(&rect->p0, &fmt, "[\u2261]");
     376        if (rc != EOK)
     377                return rc;
     378
     379        return EOK;
     380}
     381
     382/** Paint system menu handle.
     383 *
     384 * @param wdecor Window decoration
     385 * @param rect System menu handle rectangle
     386 * @return EOK on success or an error code
     387 */
     388errno_t ui_wdecor_sysmenu_hdl_paint(ui_wdecor_t *wdecor, gfx_rect_t *rect)
     389{
     390        errno_t rc;
     391
     392        if (wdecor->res->textmode)
     393                rc = ui_wdecor_sysmenu_hdl_paint_text(wdecor, rect);
     394        else
     395                rc = ui_wdecor_sysmenu_hdl_paint_gfx(wdecor, rect);
     396
     397        return rc;
     398}
     399
     400/** Set system menu handle active flag.
     401 *
     402 * @param wdecor Window decoration
     403 * @param active @c true iff handle should be active
     404 */
     405void ui_wdecor_sysmenu_hdl_set_active(ui_wdecor_t *wdecor, bool active)
     406{
     407        ui_wdecor_geom_t geom;
     408
     409        wdecor->sysmenu_hdl_active = active;
     410
     411        ui_wdecor_get_geom(wdecor, &geom);
     412        (void) ui_wdecor_sysmenu_hdl_paint(wdecor, &geom.sysmenu_hdl_rect);
     413        (void) gfx_update(wdecor->res->gc);
     414}
     415
    298416/** Paint window decoration.
    299417 *
     
    395513                        return rc;
    396514
     515                if ((wdecor->style & ui_wds_sysmenu_hdl) != 0) {
     516                        rc = ui_wdecor_sysmenu_hdl_paint(wdecor,
     517                            &geom.sysmenu_hdl_rect);
     518                        if (rc != EOK)
     519                                return rc;
     520                }
     521
    397522                if (wdecor->btn_min != NULL) {
    398523                        rc = ui_pbutton_paint(wdecor->btn_min);
     
    421546}
    422547
     548/** Send decoration sysmenu open event.
     549 *
     550 * @param wdecor Window decoration
     551 * @param idev_id Input device ID
     552 */
     553void ui_wdecor_sysmenu_open(ui_wdecor_t *wdecor, sysarg_t idev_id)
     554{
     555        if (wdecor->cb != NULL && wdecor->cb->sysmenu_open != NULL)
     556                wdecor->cb->sysmenu_open(wdecor, wdecor->arg, idev_id);
     557}
     558
     559/** Send decoration sysmenu left event.
     560 *
     561 * @param wdecor Window decoration
     562 * @param idev_id Input device ID
     563 */
     564void ui_wdecor_sysmenu_left(ui_wdecor_t *wdecor, sysarg_t idev_id)
     565{
     566        if (wdecor->cb != NULL && wdecor->cb->sysmenu_left != NULL)
     567                wdecor->cb->sysmenu_left(wdecor, wdecor->arg, idev_id);
     568}
     569
     570/** Send decoration sysmenu right event.
     571 *
     572 * @param wdecor Window decoration
     573 * @param idev_id Input device ID
     574 */
     575void ui_wdecor_sysmenu_right(ui_wdecor_t *wdecor, sysarg_t idev_id)
     576{
     577        if (wdecor->cb != NULL && wdecor->cb->sysmenu_right != NULL)
     578                wdecor->cb->sysmenu_right(wdecor, wdecor->arg, idev_id);
     579}
     580
     581/** Send decoration sysmenu accelerator event.
     582 *
     583 * @param wdecor Window decoration
     584 * @param c Accelerator character
     585 * @param idev_id Input device ID
     586 */
     587void ui_wdecor_sysmenu_accel(ui_wdecor_t *wdecor, char32_t c, sysarg_t idev_id)
     588{
     589        if (wdecor->cb != NULL && wdecor->cb->sysmenu_right != NULL)
     590                wdecor->cb->sysmenu_accel(wdecor, wdecor->arg, c, idev_id);
     591}
     592
    423593/** Send decoration minimize event.
    424594 *
     
    509679        gfx_coord_t btn_y;
    510680        gfx_coord_t cap_hmargin;
     681        gfx_coord_t cap_x;
     682        gfx_coord_t hdl_x_off;
     683        gfx_coord_t hdl_y_off;
     684        gfx_coord_t hdl_w;
     685        gfx_coord_t hdl_h;
    511686
    512687        /* Does window have a frame? */
     
    557732        }
    558733
     734        /* Does window have a sysmenu handle? */
     735        if ((wdecor->style & ui_wds_sysmenu_hdl) != 0) {
     736                if (wdecor->res->textmode) {
     737                        hdl_x_off = 2;
     738                        hdl_y_off = 0;
     739                        hdl_w = wdecor_sysmenu_hdl_w_text;
     740                        hdl_h = wdecor_sysmenu_hdl_h_text;
     741                } else {
     742                        hdl_x_off = 1;
     743                        hdl_y_off = 1;
     744                        hdl_w = wdecor_sysmenu_hdl_w;
     745                        hdl_h = wdecor_sysmenu_hdl_h;
     746                }
     747
     748                geom->sysmenu_hdl_rect.p0.x = geom->title_bar_rect.p0.x +
     749                    hdl_x_off;
     750                geom->sysmenu_hdl_rect.p0.y = geom->title_bar_rect.p0.y +
     751                    hdl_y_off;
     752                geom->sysmenu_hdl_rect.p1.x = geom->sysmenu_hdl_rect.p0.x +
     753                    hdl_w;
     754                geom->sysmenu_hdl_rect.p1.y = geom->sysmenu_hdl_rect.p0.y +
     755                    hdl_h;
     756                cap_x = hdl_w;
     757        } else {
     758                geom->sysmenu_hdl_rect.p0.x = 0;
     759                geom->sysmenu_hdl_rect.p0.y = 0;
     760                geom->sysmenu_hdl_rect.p1.x = 0;
     761                geom->sysmenu_hdl_rect.p1.y = 0;
     762                cap_x = 0;
     763        }
     764
    559765        /* Does window have a close button? */
    560766        if ((wdecor->style & ui_wds_close_btn) != 0) {
     
    629835        }
    630836
    631         if (wdecor->res->textmode == false)
    632                 cap_hmargin = wdecor_cap_hmargin;
    633         else
    634                 cap_hmargin = wdecor_cap_hmargin_text;
    635 
    636         geom->caption_rect.p0.x = geom->title_bar_rect.p0.x +
    637             cap_hmargin;
    638         geom->caption_rect.p0.y = geom->title_bar_rect.p0.y;
    639         geom->caption_rect.p1.x = btn_x - cap_hmargin;
    640         geom->caption_rect.p1.y = geom->title_bar_rect.p1.y;
     837        if ((wdecor->style & ui_wds_titlebar) != 0) {
     838                if (wdecor->res->textmode == false)
     839                        cap_hmargin = wdecor_cap_hmargin;
     840                else
     841                        cap_hmargin = wdecor_cap_hmargin_text;
     842
     843                geom->caption_rect.p0.x = geom->title_bar_rect.p0.x +
     844                    cap_hmargin + cap_x;
     845                geom->caption_rect.p0.y = geom->title_bar_rect.p0.y;
     846                geom->caption_rect.p1.x = btn_x - cap_hmargin;
     847                geom->caption_rect.p1.y = geom->title_bar_rect.p1.y;
     848        } else {
     849                geom->caption_rect.p0.x = 0;
     850                geom->caption_rect.p0.y = 0;
     851                geom->caption_rect.p1.x = 0;
     852                geom->caption_rect.p1.y = 0;
     853        }
    641854}
    642855
     
    8051018}
    8061019
     1020/** Handle window decoration keyboard event.
     1021 *
     1022 * @param wdecor Window decoration
     1023 * @param kbd_event Keyboard event
     1024 * @return @c ui_claimed iff event was claimed
     1025 */
     1026ui_evclaim_t ui_wdecor_kbd_event(ui_wdecor_t *wdecor, kbd_event_t *event)
     1027{
     1028        if (event->type == KEY_PRESS && (event->mods & (KM_CTRL | KM_ALT |
     1029            KM_SHIFT)) == 0) {
     1030                if (event->key == KC_F10) {
     1031                        ui_wdecor_sysmenu_hdl_set_active(wdecor, true);
     1032                        ui_wdecor_sysmenu_open(wdecor, event->kbd_id);
     1033                        return ui_claimed;
     1034                }
     1035        }
     1036
     1037        /* System menu handle events (if active) */
     1038        if (event->type == KEY_PRESS && (event->mods & (KM_CTRL | KM_ALT |
     1039            KM_SHIFT)) == 0 && wdecor->sysmenu_hdl_active) {
     1040                switch (event->key) {
     1041                case KC_ESCAPE:
     1042                        ui_wdecor_sysmenu_hdl_set_active(wdecor, false);
     1043                        return ui_claimed;
     1044                case KC_LEFT:
     1045                        ui_wdecor_sysmenu_left(wdecor, event->kbd_id);
     1046                        return ui_claimed;
     1047                case KC_RIGHT:
     1048                        ui_wdecor_sysmenu_right(wdecor, event->kbd_id);
     1049                        return ui_claimed;
     1050                case KC_DOWN:
     1051                        ui_wdecor_sysmenu_open(wdecor, event->kbd_id);
     1052                        return ui_claimed;
     1053                default:
     1054                        break;
     1055                }
     1056
     1057                if (event->c != '\0') {
     1058                        /* Could be an accelerator key */
     1059                        ui_wdecor_sysmenu_accel(wdecor, event->c,
     1060                            event->kbd_id);
     1061                }
     1062        }
     1063
     1064        return ui_unclaimed;
     1065}
     1066
    8071067/** Handle window frame position event.
    8081068 *
     
    8511111
    8521112        ui_wdecor_get_geom(wdecor, &geom);
     1113
     1114        if ((wdecor->style & ui_wds_titlebar) != 0 &&
     1115            (wdecor->style & ui_wds_sysmenu_hdl) != 0) {
     1116                if (event->type == POS_PRESS &&
     1117                    gfx_pix_inside_rect(&pos, &geom.sysmenu_hdl_rect)) {
     1118                        ui_wdecor_sysmenu_hdl_set_active(wdecor, true);
     1119                        ui_wdecor_sysmenu_open(wdecor, event->pos_id);
     1120                        return ui_claimed;
     1121                }
     1122        }
    8531123
    8541124        if (wdecor->btn_min != NULL) {
  • uspace/lib/ui/src/window.c

    r42c2e65 rdc5c303  
    4747#include <stdlib.h>
    4848#include <ui/control.h>
     49#include <ui/menubar.h>
     50#include <ui/menu.h>
     51#include <ui/menuentry.h>
    4952#include <ui/resource.h>
    5053#include <ui/ui.h>
     
    7477};
    7578
     79static void wd_sysmenu_open(ui_wdecor_t *, void *, sysarg_t);
     80static void wd_sysmenu_left(ui_wdecor_t *, void *, sysarg_t);
     81static void wd_sysmenu_right(ui_wdecor_t *, void *, sysarg_t);
     82static void wd_sysmenu_accel(ui_wdecor_t *, void *, char32_t, sysarg_t);
    7683static void wd_minimize(ui_wdecor_t *, void *);
    7784static void wd_maximize(ui_wdecor_t *, void *);
     
    8491
    8592static ui_wdecor_cb_t wdecor_cb = {
     93        .sysmenu_open = wd_sysmenu_open,
     94        .sysmenu_left = wd_sysmenu_left,
     95        .sysmenu_right = wd_sysmenu_right,
     96        .sysmenu_accel = wd_sysmenu_accel,
    8697        .minimize = wd_minimize,
    8798        .maximize = wd_maximize,
     
    93104};
    94105
     106static void wnd_sysmenu_left(ui_menu_t *, void *, sysarg_t);
     107static void wnd_sysmenu_right(ui_menu_t *, void *, sysarg_t);
     108static void wnd_sysmenu_close_req(ui_menu_t *, void *);
     109static void wnd_sysmenu_press_accel(ui_menu_t *, void *, char32_t, sysarg_t);
     110
     111static ui_menu_cb_t wnd_sysmenu_cb = {
     112        .left = wnd_sysmenu_left,
     113        .right = wnd_sysmenu_right,
     114        .close_req = wnd_sysmenu_close_req,
     115        .press_accel = wnd_sysmenu_press_accel
     116};
     117
     118static void wnd_sysmenu_erestore(ui_menu_entry_t *, void *);
     119static void wnd_sysmenu_eminimize(ui_menu_entry_t *, void *);
     120static void wnd_sysmenu_emaximize(ui_menu_entry_t *, void *);
     121static void wnd_sysmenu_eclose(ui_menu_entry_t *, void *);
     122
    95123static void ui_window_invalidate(void *, gfx_rect_t *);
    96124static void ui_window_update(void *);
     
    150178{
    151179        gfx_coord2_t dims;
     180        gfx_coord2_t below_pos;
     181        gfx_rect_t below_rect;
    152182
    153183        assert(params->placement != ui_wnd_place_default ||
     
    183213                break;
    184214        case ui_wnd_place_popup:
    185                 /* Place popup window below parent rectangle */
    186                 pos->x = params->prect.p0.x;
    187                 pos->y = params->prect.p1.y;
     215                /* Compute rectangle when placed below */
     216                below_pos.x = params->prect.p0.x;
     217                below_pos.y = params->prect.p1.y;
     218                gfx_rect_translate(&below_pos, &params->rect, &below_rect);
     219
     220                /* Does below_rect fit within the display? */
     221                if (gfx_rect_is_inside(&below_rect, drect)) {
     222                        /* Place popup window below parent rectangle */
     223                        pos->x = params->prect.p0.x - params->rect.p0.x;
     224                        pos->y = params->prect.p1.y - params->rect.p0.y;
     225                } else {
     226                        /* Place popup window above parent rectangle */
     227                        pos->x = params->prect.p0.x;
     228                        pos->y = params->prect.p0.y -
     229                            (params->rect.p1.y - params->rect.p0.y);
     230                }
    188231                break;
    189232        }
     233}
     234
     235/** Create window's system menu.
     236 *
     237 * @param window Window
     238 * @return EOK on success or an error code
     239 */
     240static errno_t ui_window_sysmenu_create(ui_window_t *window)
     241{
     242        errno_t rc;
     243        ui_menu_entry_t *mrestore;
     244        ui_menu_entry_t *mmin;
     245        ui_menu_entry_t *mmax;
     246        ui_menu_entry_t *msep;
     247        ui_menu_entry_t *mclose;
     248
     249        rc = ui_menu_create(window, &window->sysmenu);
     250        if (rc != EOK)
     251                goto error;
     252
     253        ui_menu_set_cb(window->sysmenu, &wnd_sysmenu_cb, (void *)window);
     254
     255        rc = ui_menu_entry_create(window->sysmenu, "~R~estore",
     256            "", &mrestore);
     257        if (rc != EOK)
     258                goto error;
     259
     260        if (!window->wdecor->maximized)
     261                ui_menu_entry_set_disabled(mrestore, true);
     262
     263        ui_menu_entry_set_cb(mrestore, wnd_sysmenu_erestore, (void *)window);
     264
     265        rc = ui_menu_entry_create(window->sysmenu, "Mi~n~imize",
     266            "", &mmin);
     267        if (rc != EOK)
     268                goto error;
     269
     270        if ((window->wdecor->style & ui_wds_minimize_btn) == 0)
     271                ui_menu_entry_set_disabled(mmin, true);
     272
     273        ui_menu_entry_set_cb(mmin, wnd_sysmenu_eminimize, (void *)window);
     274
     275        rc = ui_menu_entry_create(window->sysmenu, "Ma~x~imize",
     276            "", &mmax);
     277        if (rc != EOK)
     278                goto error;
     279
     280        if ((window->wdecor->style & ui_wds_maximize_btn) == 0 ||
     281            window->wdecor->maximized)
     282                ui_menu_entry_set_disabled(mmax, true);
     283
     284        ui_menu_entry_set_cb(mmax, wnd_sysmenu_emaximize, (void *)window);
     285
     286        rc = ui_menu_entry_sep_create(window->sysmenu, &msep);
     287        if (rc != EOK)
     288                goto error;
     289
     290        rc = ui_menu_entry_create(window->sysmenu, "~C~lose", "Alt-F4",
     291            &mclose);
     292        if (rc != EOK)
     293                goto error;
     294
     295        if ((window->wdecor->style & ui_wds_close_btn) == 0)
     296                ui_menu_entry_set_disabled(mclose, true);
     297
     298        ui_menu_entry_set_cb(mclose, wnd_sysmenu_eclose, (void *)window);
     299
     300        window->sysmenu_restore = mrestore;
     301        window->sysmenu_minimize = mmin;
     302        window->sysmenu_maximize = mmax;
     303
     304        return EOK;
     305error:
     306        return rc;
    190307}
    191308
     
    381498        window->cursor = ui_curs_arrow;
    382499        window->placement = params->placement;
     500
     501        rc = ui_window_sysmenu_create(window);
     502        if (rc != EOK)
     503                goto error;
     504
    383505        *rwindow = window;
    384506
     
    417539        list_remove(&window->lwindows);
    418540        ui_control_destroy(window->control);
     541        ui_menu_destroy(window->sysmenu);
    419542        ui_wdecor_destroy(window->wdecor);
    420543        ui_resource_destroy(window->res);
     
    9291052}
    9301053
     1054/** Window decoration requested opening of system menu.
     1055 *
     1056 * @param wdecor Window decoration
     1057 * @param arg Argument (window)
     1058 * @param idev_id Input device ID
     1059 */
     1060static void wd_sysmenu_open(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1061{
     1062        ui_window_t *window = (ui_window_t *) arg;
     1063
     1064        ui_window_send_sysmenu(window, idev_id);
     1065}
     1066
     1067/** Window decoration requested moving left from system menu handle.
     1068 *
     1069 * @param wdecor Window decoration
     1070 * @param arg Argument (window)
     1071 * @param idev_id Input device ID
     1072 */
     1073static void wd_sysmenu_left(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1074{
     1075        ui_window_t *window = (ui_window_t *) arg;
     1076
     1077        if (window->mbar != NULL) {
     1078                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1079                ui_menu_close(window->sysmenu);
     1080                ui_menu_bar_select_last(window->mbar, false, idev_id);
     1081        }
     1082}
     1083
     1084/** Window decoration requested moving right from system menu handle.
     1085 *
     1086 * @param wdecor Window decoration
     1087 * @param arg Argument (window)
     1088 * @param idev_id Input device ID
     1089 */
     1090static void wd_sysmenu_right(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1091{
     1092        ui_window_t *window = (ui_window_t *) arg;
     1093
     1094        if (window->mbar != NULL) {
     1095                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1096                ui_menu_close(window->sysmenu);
     1097                ui_menu_bar_select_first(window->mbar, false, idev_id);
     1098        }
     1099}
     1100
     1101/** Window decoration detected accelerator press from system menu handle.
     1102 *
     1103 * @param wdecor Window decoration
     1104 * @param arg Argument (window)
     1105 * @param c Accelerator key
     1106 * @param idev_id Input device ID
     1107 */
     1108static void wd_sysmenu_accel(ui_wdecor_t *wdecor, void *arg, char32_t c,
     1109    sysarg_t idev_id)
     1110{
     1111        ui_window_t *window = (ui_window_t *) arg;
     1112
     1113        if (window->mbar != NULL) {
     1114                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1115                ui_menu_close(window->sysmenu);
     1116                ui_menu_bar_press_accel(window->mbar, c, idev_id);
     1117        }
     1118}
     1119
    9311120/** Window decoration requested window minimization.
    9321121 *
     
    10071196
    10081197        if (window->dwindow != NULL) {
    1009                 (void) display_window_resize_req(window->dwindow, rsztype,
     1198                (void) display_window_resize_req(window->dwindow,
     1199                    (display_wnd_rsztype_t) rsztype, // Same constants in the enums
    10101200                    pos, pos_id);
    10111201        }
     
    10701260}
    10711261
     1262/** Send window sysmenu event.
     1263 *
     1264 * @param window Window
     1265 * @parma idev_id Input device ID
     1266 */
     1267void ui_window_send_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1268{
     1269        if (window->cb != NULL && window->cb->sysmenu != NULL)
     1270                window->cb->sysmenu(window, window->arg, idev_id);
     1271        else
     1272                ui_window_def_sysmenu(window, idev_id);
     1273}
     1274
    10721275/** Send window minimize event.
    10731276 *
     
    11741377        else
    11751378                return ui_window_def_unfocus(window, nfocus);
     1379}
     1380
     1381/** Default window sysmenu routine.
     1382 *
     1383 * @param window Window
     1384 * @param idev_id Input device ID
     1385 * @return EOK on success or an error code
     1386 */
     1387errno_t ui_window_def_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1388{
     1389        errno_t rc;
     1390        ui_wdecor_geom_t geom;
     1391
     1392        if (ui_menu_is_open(window->sysmenu)) {
     1393                ui_menu_close(window->sysmenu);
     1394        } else {
     1395                ui_wdecor_get_geom(window->wdecor, &geom);
     1396
     1397                rc = ui_menu_open(window->sysmenu, &geom.title_bar_rect,
     1398                    idev_id);
     1399                if (rc != EOK)
     1400                        goto error;
     1401        }
     1402
     1403        return EOK;
     1404error:
     1405        return rc;
    11761406}
    11771407
     
    12181448
    12191449        ui_wdecor_set_maximized(window->wdecor, true);
     1450        ui_menu_entry_set_disabled(window->sysmenu_restore, false);
     1451        ui_menu_entry_set_disabled(window->sysmenu_maximize, true);
    12201452
    12211453        rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
     
    12401472
    12411473        ui_wdecor_set_maximized(window->wdecor, false);
     1474        ui_menu_entry_set_disabled(window->sysmenu_restore, true);
     1475        ui_menu_entry_set_disabled(window->sysmenu_maximize, false);
    12421476
    12431477        rc = ui_window_size_change(window, &window->normal_rect,
     
    12601494ui_evclaim_t ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
    12611495{
     1496        ui_evclaim_t claim;
     1497
    12621498        if (window->control != NULL)
    1263                 return ui_control_kbd_event(window->control, kbd);
     1499                claim = ui_control_kbd_event(window->control, kbd);
     1500        else
     1501                claim = ui_unclaimed;
     1502
     1503        if (claim == ui_unclaimed)
     1504                return ui_wdecor_kbd_event(window->wdecor, kbd);
    12641505
    12651506        return ui_unclaimed;
     
    13161557        if (window->control != NULL)
    13171558                ui_control_unfocus(window->control, nfocus);
     1559}
     1560
     1561/** Handle system menu left event.
     1562 *
     1563 * @param sysmenu System menu
     1564 * @param arg Argument (ui_window_t *)
     1565 * @param idev_id Input device ID
     1566 */
     1567static void wnd_sysmenu_left(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1568{
     1569        ui_window_t *window = (ui_window_t *)arg;
     1570
     1571        if (window->mbar != NULL) {
     1572                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1573                ui_menu_close(sysmenu);
     1574                ui_menu_bar_select_last(window->mbar, true, idev_id);
     1575        }
     1576}
     1577
     1578/** Handle system menu right event.
     1579 *
     1580 * @param sysmenu System menu
     1581 * @param arg Argument (ui_window_t *)
     1582 * @param idev_id Input device ID
     1583 */
     1584static void wnd_sysmenu_right(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1585{
     1586        ui_window_t *window = (ui_window_t *)arg;
     1587
     1588        if (window->mbar != NULL) {
     1589                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1590                ui_menu_close(sysmenu);
     1591                ui_menu_bar_select_first(window->mbar, true, idev_id);
     1592        }
     1593}
     1594
     1595/** Handle system menu close request event.
     1596 *
     1597 * @param sysmenu System menu
     1598 * @param arg Argument (ui_window_t *)
     1599 * @param idev_id Input device ID
     1600 */
     1601static void wnd_sysmenu_close_req(ui_menu_t *sysmenu, void *arg)
     1602{
     1603        ui_window_t *window = (ui_window_t *)arg;
     1604
     1605        ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1606        ui_menu_close(sysmenu);
     1607}
     1608
     1609/** Handle system menu Restore entry activation.
     1610 *
     1611 * @param mentry Menu entry
     1612 * @param arg Argument (ui_window_t *)
     1613 */
     1614static void wnd_sysmenu_erestore(ui_menu_entry_t *mentry, void *arg)
     1615{
     1616        ui_window_t *window = (ui_window_t *)arg;
     1617
     1618        ui_window_send_unmaximize(window);
     1619}
     1620
     1621/** Handle system menu Minimize entry activation.
     1622 *
     1623 * @param mentry Menu entry
     1624 * @param arg Argument (ui_window_t *)
     1625 */
     1626static void wnd_sysmenu_eminimize(ui_menu_entry_t *mentry, void *arg)
     1627{
     1628        ui_window_t *window = (ui_window_t *)arg;
     1629
     1630        ui_window_send_minimize(window);
     1631}
     1632
     1633/** Handle system menu Maximize entry activation.
     1634 *
     1635 * @param mentry Menu entry
     1636 * @param arg Argument (ui_window_t *)
     1637 */
     1638static void wnd_sysmenu_emaximize(ui_menu_entry_t *mentry, void *arg)
     1639{
     1640        ui_window_t *window = (ui_window_t *)arg;
     1641
     1642        ui_window_send_maximize(window);
     1643}
     1644
     1645/** Handle system menu Close entry activation.
     1646 *
     1647 * @param mentry Menu entry
     1648 * @param arg Argument (ui_window_t *)
     1649 */
     1650static void wnd_sysmenu_eclose(ui_menu_entry_t *mentry, void *arg)
     1651{
     1652        ui_window_t *window = (ui_window_t *)arg;
     1653
     1654        ui_window_send_close(window);
     1655}
     1656
     1657/** Handle system menu press accelerator key event.
     1658 *
     1659 * @param sysmenu System menu
     1660 * @param arg Argument (ui_window_t *)
     1661 * @param idev_id Input device ID
     1662 */
     1663static void wnd_sysmenu_press_accel(ui_menu_t *sysmenu, void *arg,
     1664    char32_t c, sysarg_t idev_id)
     1665{
     1666        (void)sysmenu;
     1667        (void)arg;
     1668        (void)c;
     1669        (void)idev_id;
    13181670}
    13191671
Note: See TracChangeset for help on using the changeset viewer.