Changeset 35cffea in mainline for uspace/lib/ui/src


Ignore:
Timestamp:
2022-05-19T08:02:31Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ad698f4
Parents:
fd05ea6
git-author:
Jiri Svoboda <jiri@…> (2022-05-18 17:02:12)
git-committer:
Jiri Svoboda <jiri@…> (2022-05-19 08:02:31)
Message:

Maximizing/unmaximizing a window

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

Legend:

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

    rfd05ea6 r35cffea  
    529529}
    530530
     531/** Paint maximize icon.
     532 *
     533 * @param resource UI resource
     534 * @param pos Center position
     535 * @param w Icon width
     536 * @param h Icon height
     537 * @return EOK on success or an error code
     538 */
     539errno_t ui_paint_maxicon(ui_resource_t *resource, gfx_coord2_t *pos,
     540    gfx_coord_t w, gfx_coord_t h)
     541{
     542        gfx_rect_t rect;
     543        errno_t rc;
     544
     545        rc = gfx_set_color(resource->gc, resource->btn_text_color);
     546        if (rc != EOK)
     547                return rc;
     548
     549        rect.p0.x = pos->x - w / 2;
     550        rect.p0.y = pos->y - h / 2;
     551        rect.p1.x = rect.p0.x + w;
     552        rect.p1.y = rect.p0.y + h;
     553        rc = gfx_fill_rect(resource->gc, &rect);
     554        if (rc != EOK)
     555                return rc;
     556
     557        rc = gfx_set_color(resource->gc, resource->btn_face_color);
     558        if (rc != EOK)
     559                return rc;
     560
     561        rect.p0.x += 1;
     562        rect.p0.y += 2;
     563        rect.p1.x -= 1;
     564        rect.p1.y -= 1;
     565        rc = gfx_fill_rect(resource->gc, &rect);
     566        if (rc != EOK)
     567                return rc;
     568
     569        return EOK;
     570}
     571
     572/** Paint unmaximize icon.
     573 *
     574 * Unmaximize icon consists of two overlapping window icons.
     575 *
     576 * @param resource UI resource
     577 * @param pos Center position
     578 * @param w Window icon width
     579 * @param h Window icon height
     580 * @param dw Horizontal distance between window icon centers
     581 * @param dh Vertical distance between window icon centers
     582 * @return EOK on success or an error code
     583 */
     584errno_t ui_paint_unmaxicon(ui_resource_t *resource, gfx_coord2_t *pos,
     585    gfx_coord_t w, gfx_coord_t h, gfx_coord_t dw, gfx_coord_t dh)
     586{
     587        gfx_coord2_t p;
     588        errno_t rc;
     589
     590        p.x = pos->x + dw / 2;
     591        p.y = pos->y - dh / 2;
     592        rc = ui_paint_maxicon(resource, &p, w, h);
     593        if (rc != EOK)
     594                return rc;
     595
     596        p.x = pos->x - dw / 2;
     597        p.y = pos->y + dh / 2;
     598        rc = ui_paint_maxicon(resource, &p, w, h);
     599        if (rc != EOK)
     600                return rc;
     601
     602        return EOK;
     603}
     604
    531605/** Paint a text box.
    532606 *
  • uspace/lib/ui/src/wdecor.c

    rfd05ea6 r35cffea  
    4949#include "../private/wdecor.h"
    5050
    51 static void ui_wdecor_btn_clicked(ui_pbutton_t *, void *);
     51static void ui_wdecor_btn_max_clicked(ui_pbutton_t *, void *);
     52static errno_t ui_wdecor_btn_max_paint(ui_pbutton_t *, void *,
     53    gfx_coord2_t *);
     54
     55static void ui_wdecor_btn_close_clicked(ui_pbutton_t *, void *);
    5256static errno_t ui_wdecor_btn_close_paint(ui_pbutton_t *, void *,
    5357    gfx_coord2_t *);
    5458
     59static ui_pbutton_cb_t ui_wdecor_btn_max_cb = {
     60        .clicked = ui_wdecor_btn_max_clicked
     61};
     62
     63static ui_pbutton_decor_ops_t ui_wdecor_btn_max_decor_ops = {
     64        .paint = ui_wdecor_btn_max_paint
     65};
     66
    5567static ui_pbutton_cb_t ui_wdecor_btn_close_cb = {
    56         .clicked = ui_wdecor_btn_clicked
     68        .clicked = ui_wdecor_btn_close_clicked
    5769};
    5870
     
    6274
    6375enum {
     76        /** Width of corner drag area */
    6477        wdecor_corner_w = 24,
     78        /** Height of corner drag area */
    6579        wdecor_corner_h = 24,
     80        /** Window resizing edge witdth */
    6681        wdecor_edge_w = 4,
     82        /** Window resizing edge height */
    6783        wdecor_edge_h = 4,
     84        /** Title bar height */
    6885        wdecor_tbar_h = 22,
     86        /** Window width */
    6987        wdecor_frame_w = 4,
     88        /** Window frame width in text mode */
    7089        wdecor_frame_w_text = 1,
     90        /** Close button cross leg length */
    7191        wdecor_close_cross_n = 5,
     92        /** Close button cross pen width */
    7293        wdecor_close_cross_w = 2,
    73         wdecor_close_cross_h = 1
     94        /** Close button cross pen height */
     95        wdecor_close_cross_h = 1,
     96        /** Maximize icon width */
     97        wdecor_max_w = 10,
     98        /** Maximize icon height */
     99        wdecor_max_h = 10,
     100        /** Unmaximize icon window width */
     101        wdecor_unmax_w = 8,
     102        /** Unmaximize icon window height */
     103        wdecor_unmax_h = 8,
     104        /** Unmaximize icon window horizontal distance */
     105        wdecor_unmax_dw = 4,
     106        /** Unmaximize icon window vertical distance */
     107        wdecor_unmax_dh = 4
    74108};
    75109
     
    98132        }
    99133
    100         rc = ui_pbutton_create(resource, "X", &wdecor->btn_close);
    101         if (rc != EOK) {
    102                 free(wdecor->caption);
    103                 free(wdecor);
    104                 return rc;
    105         }
    106 
    107         ui_pbutton_set_cb(wdecor->btn_close, &ui_wdecor_btn_close_cb,
    108             (void *)wdecor);
    109 
    110         ui_pbutton_set_decor_ops(wdecor->btn_close,
    111             &ui_wdecor_btn_close_decor_ops, (void *)wdecor);
     134        if ((style & ui_wds_maximize_btn) != 0) {
     135                rc = ui_pbutton_create(resource, "^", &wdecor->btn_max);
     136                if (rc != EOK) {
     137                        ui_wdecor_destroy(wdecor);
     138                        return rc;
     139                }
     140
     141                ui_pbutton_set_cb(wdecor->btn_max, &ui_wdecor_btn_max_cb,
     142                    (void *)wdecor);
     143
     144                ui_pbutton_set_decor_ops(wdecor->btn_max,
     145                    &ui_wdecor_btn_max_decor_ops, (void *)wdecor);
     146        }
     147
     148        if ((style & ui_wds_close_btn) != 0) {
     149                rc = ui_pbutton_create(resource, "X", &wdecor->btn_close);
     150                if (rc != EOK) {
     151                        ui_wdecor_destroy(wdecor);
     152                        return rc;
     153                }
     154
     155                ui_pbutton_set_cb(wdecor->btn_close, &ui_wdecor_btn_close_cb,
     156                    (void *)wdecor);
     157
     158                ui_pbutton_set_decor_ops(wdecor->btn_close,
     159                    &ui_wdecor_btn_close_decor_ops, (void *)wdecor);
     160        }
    112161
    113162        wdecor->res = resource;
     
    127176                return;
    128177
     178        ui_pbutton_destroy(wdecor->btn_max);
    129179        ui_pbutton_destroy(wdecor->btn_close);
    130180        free(wdecor->caption);
     
    156206
    157207        ui_wdecor_get_geom(wdecor, &geom);
    158         ui_pbutton_set_rect(wdecor->btn_close, &geom.btn_close_rect);
     208
     209        if (wdecor->btn_max != NULL)
     210                ui_pbutton_set_rect(wdecor->btn_max, &geom.btn_max_rect);
     211        if (wdecor->btn_close != NULL)
     212                ui_pbutton_set_rect(wdecor->btn_close, &geom.btn_close_rect);
    159213}
    160214
     
    169223{
    170224        wdecor->active = active;
     225}
     226
     227/** Set maximized flag.
     228 *
     229 * Active window is the one receiving keyboard events.
     230 *
     231 * @param wdecor Window decoration
     232 * @param maximized @c true iff window is maximized
     233 */
     234void ui_wdecor_set_maximized(ui_wdecor_t *wdecor, bool maximized)
     235{
     236        wdecor->maximized = maximized;
    171237}
    172238
     
    289355                        return rc;
    290356
    291                 if ((wdecor->style & ui_wds_close_btn) != 0) {
     357                if (wdecor->btn_max != NULL) {
     358                        rc = ui_pbutton_paint(wdecor->btn_max);
     359                        if (rc != EOK)
     360                                return rc;
     361                }
     362
     363                if (wdecor->btn_close != NULL) {
    292364                        rc = ui_pbutton_paint(wdecor->btn_close);
    293365                        if (rc != EOK)
     
    303375}
    304376
     377/** Send decoration maximize event.
     378 *
     379 * @param wdecor Window decoration
     380 */
     381void ui_wdecor_maximize(ui_wdecor_t *wdecor)
     382{
     383        if (wdecor->cb != NULL && wdecor->cb->maximize != NULL)
     384                wdecor->cb->maximize(wdecor, wdecor->arg);
     385}
     386
     387/** Send decoration unmaximize event.
     388 *
     389 * @param wdecor Window decoration
     390 */
     391void ui_wdecor_unmaximize(ui_wdecor_t *wdecor)
     392{
     393        if (wdecor->cb != NULL && wdecor->cb->unmaximize != NULL)
     394                wdecor->cb->unmaximize(wdecor, wdecor->arg);
     395}
     396
    305397/** Send decoration close event.
    306398 *
     
    356448{
    357449        gfx_coord_t frame_w;
     450        gfx_coord_t btn_x;
     451        gfx_coord_t btn_y;
    358452
    359453        /* Does window have a frame? */
     
    376470                        geom->title_bar_rect.p1.x = wdecor->rect.p1.x;
    377471                        geom->title_bar_rect.p1.y = wdecor->rect.p0.y + 1;
     472
     473                        btn_x = geom->title_bar_rect.p1.x - 1;
     474                        btn_y = geom->title_bar_rect.p0.y;
    378475                } else {
    379476                        geom->title_bar_rect.p0 = geom->interior_rect.p0;
     
    381478                        geom->title_bar_rect.p1.y = geom->interior_rect.p0.y +
    382479                            wdecor_tbar_h;
     480
     481                        btn_x = geom->title_bar_rect.p1.x - 1;
     482                        btn_y = geom->title_bar_rect.p0.y + 1;
    383483                }
    384484
     
    386486                geom->app_area_rect.p0.y = geom->title_bar_rect.p1.y;
    387487                geom->app_area_rect.p1 = geom->interior_rect.p1;
     488
    388489        } else {
    389490                geom->title_bar_rect.p0.x = 0;
     
    393494
    394495                geom->app_area_rect = geom->interior_rect;
     496                btn_x = 0;
     497                btn_y = 0;
    395498        }
    396499
     
    398501        if ((wdecor->style & ui_wds_close_btn) != 0) {
    399502                if (wdecor->res->textmode == false) {
    400                         geom->btn_close_rect.p0.x =
    401                             geom->title_bar_rect.p1.x - 1 - 20;
    402                         geom->btn_close_rect.p0.y =
    403                             geom->title_bar_rect.p0.y + 1;
    404                         geom->btn_close_rect.p1.x =
    405                             geom->title_bar_rect.p1.x - 1;
    406                         geom->btn_close_rect.p1.y =
    407                             geom->title_bar_rect.p0.y + 1 + 20;
     503                        geom->btn_close_rect.p0.x = btn_x - 20;
     504                        geom->btn_close_rect.p0.y = btn_y;
     505                        geom->btn_close_rect.p1.x = btn_x;
     506                        geom->btn_close_rect.p1.y = btn_y + 20;
     507
     508                        btn_x -= 20;
    408509                } else {
    409                         geom->btn_close_rect.p0.x =
    410                             geom->title_bar_rect.p1.x - 1 - 3;
    411                         geom->btn_close_rect.p0.y =
    412                             geom->title_bar_rect.p0.y;
    413                         geom->btn_close_rect.p1.x =
    414                             geom->title_bar_rect.p1.x - 1;
    415                         geom->btn_close_rect.p1.y =
    416                             geom->title_bar_rect.p0.y + 1;
     510                        geom->btn_close_rect.p0.x = btn_x - 3;
     511                        geom->btn_close_rect.p0.y = btn_y;
     512                        geom->btn_close_rect.p1.x = btn_x;
     513                        geom->btn_close_rect.p1.y = btn_y + 1;
     514
     515                        btn_x -= 3;
    417516                }
    418517        } else {
     
    422521                geom->btn_close_rect.p1.y = 0;
    423522        }
     523
     524        /* Does window have a (un)maximize button? */
     525        if ((wdecor->style & ui_wds_maximize_btn) != 0) {
     526                if (wdecor->res->textmode == false) {
     527                        geom->btn_max_rect.p0.x = btn_x - 20;
     528                        geom->btn_max_rect.p0.y = btn_y;
     529                        geom->btn_max_rect.p1.x = btn_x;
     530                        geom->btn_max_rect.p1.y = btn_y + 20;
     531                } else {
     532                        geom->btn_max_rect.p0.x = btn_x - 3;
     533                        geom->btn_max_rect.p0.y = btn_y;
     534                        geom->btn_max_rect.p1.x = btn_x;
     535                        geom->btn_max_rect.p1.y = btn_y + 1;
     536                }
     537        } else {
     538                geom->btn_max_rect.p0.x = 0;
     539                geom->btn_max_rect.p0.y = 0;
     540                geom->btn_max_rect.p1.x = 0;
     541                geom->btn_max_rect.p1.y = 0;
     542        }
    424543}
    425544
     
    495614                return ui_wr_none;
    496615
     616        /* Window is maximized? */
     617        if (wdecor->maximized)
     618                return ui_wr_none;
     619
    497620        /* Position not inside window? */
    498621        if (!gfx_pix_inside_rect(pos, &wdecor->rect))
     
    627750        ui_wdecor_get_geom(wdecor, &geom);
    628751
    629         if ((wdecor->style & ui_wds_close_btn) != 0) {
     752        if (wdecor->btn_max != NULL) {
     753                claim = ui_pbutton_pos_event(wdecor->btn_max, event);
     754                if (claim == ui_claimed)
     755                        return ui_claimed;
     756        }
     757
     758        if (wdecor->btn_close != NULL) {
    630759                claim = ui_pbutton_pos_event(wdecor->btn_close, event);
    631760                if (claim == ui_claimed)
     
    635764        ui_wdecor_frame_pos_event(wdecor, event);
    636765
    637         if ((wdecor->style & ui_wds_titlebar) != 0) {
     766        if ((wdecor->style & ui_wds_titlebar) != 0 && !wdecor->maximized) {
    638767                if (event->type == POS_PRESS &&
    639768                    gfx_pix_inside_rect(&pos, &geom.title_bar_rect)) {
     
    646775}
    647776
    648 /** Window decoration close button was clicked.
     777/** Window decoration (un)maximize button was clicked.
    649778 *
    650779 * @param pbutton Close button
    651780 * @param arg Argument (ui_wdecor_t)
    652781 */
    653 static void ui_wdecor_btn_clicked(ui_pbutton_t *pbutton, void *arg)
     782static void ui_wdecor_btn_max_clicked(ui_pbutton_t *pbutton, void *arg)
     783{
     784        ui_wdecor_t *wdecor = (ui_wdecor_t *) arg;
     785
     786        (void) pbutton;
     787
     788        if (wdecor->maximized)
     789                ui_wdecor_unmaximize(wdecor);
     790        else
     791                ui_wdecor_maximize(wdecor);
     792}
     793
     794/** Paint (un)maximize button decoration.
     795 *
     796 * @param pbutton Push button
     797 * @param arg Argument (ui_wdecor_t *)
     798 * @param pos Center position
     799 */
     800static errno_t ui_wdecor_btn_max_paint(ui_pbutton_t *pbutton,
     801    void *arg, gfx_coord2_t *pos)
     802{
     803        ui_wdecor_t *wdecor = (ui_wdecor_t *)arg;
     804        errno_t rc;
     805
     806        if (wdecor->maximized) {
     807                rc = ui_paint_unmaxicon(wdecor->res, pos, wdecor_unmax_w,
     808                    wdecor_unmax_h, wdecor_unmax_dw, wdecor_unmax_dh);
     809        } else {
     810                rc = ui_paint_maxicon(wdecor->res, pos, wdecor_max_w,
     811                    wdecor_max_h);
     812        }
     813
     814        return rc;
     815}
     816
     817/** Window decoration close button was clicked.
     818 *
     819 * @param pbutton Close button
     820 * @param arg Argument (ui_wdecor_t)
     821 */
     822static void ui_wdecor_btn_close_clicked(ui_pbutton_t *pbutton, void *arg)
    654823{
    655824        ui_wdecor_t *wdecor = (ui_wdecor_t *) arg;
  • uspace/lib/ui/src/window.c

    rfd05ea6 r35cffea  
    7474};
    7575
     76static void wd_maximize(ui_wdecor_t *, void *);
     77static void wd_unmaximize(ui_wdecor_t *, void *);
    7678static void wd_close(ui_wdecor_t *, void *);
    7779static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *);
     
    8183
    8284static ui_wdecor_cb_t wdecor_cb = {
     85        .maximize = wd_maximize,
     86        .unmaximize = wd_unmaximize,
    8387        .close = wd_close,
    8488        .move = wd_move,
     
    469473}
    470474
    471 /** Resize/move window.
    472  *
    473  * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
    474  * the top-left corner of the window will move on the screen accordingly.
     475/** Resize or (un)maximize window.
    475476 *
    476477 * @param window Window
    477478 * @param rect Rectangle
     479 * @param scop Size change operation
    478480 *
    479481 * @return EOK on success or an error code
    480482 */
    481 errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     483errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
     484    ui_wnd_sc_op_t scop)
    482485{
    483486        gfx_coord2_t offs;
     
    545548        }
    546549
    547         /* dwindow can be NULL in case of unit tests */
     550        /* dwindow can be NULL in case of unit tests or fullscreen mode */
    548551        if (window->dwindow != NULL) {
    549                 rc = display_window_resize(window->dwindow, &offs, &nrect);
    550                 if (rc != EOK)
    551                         goto error;
     552                switch (scop) {
     553                case ui_wsc_resize:
     554                        rc = display_window_resize(window->dwindow, &offs,
     555                            &nrect);
     556                        if (rc != EOK)
     557                                goto error;
     558                        break;
     559                case ui_wsc_maximize:
     560                        rc = display_window_maximize(window->dwindow);
     561                        if (rc != EOK)
     562                                goto error;
     563                        break;
     564                case ui_wsc_unmaximize:
     565                        rc = display_window_unmaximize(window->dwindow);
     566                        if (rc != EOK)
     567                                goto error;
     568                        break;
     569                }
    552570        }
    553571
     
    597615}
    598616
     617/** Resize/move window.
     618 *
     619 * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
     620 * the top-left corner of the window will move on the screen accordingly.
     621 *
     622 * @param window Window
     623 * @param rect Rectangle
     624 *
     625 * @return EOK on success or an error code
     626 */
     627errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     628{
     629        return ui_window_size_change(window, rect, ui_wsc_resize);
     630}
     631
    599632/** Set window callbacks.
    600633 *
     
    846879        ui_window_send_unfocus(window);
    847880        ui_unlock(window->ui);
     881}
     882
     883/** Window decoration requested window maximization.
     884 *
     885 * @param wdecor Window decoration
     886 * @param arg Argument (window)
     887 */
     888static void wd_maximize(ui_wdecor_t *wdecor, void *arg)
     889{
     890        ui_window_t *window = (ui_window_t *) arg;
     891
     892        ui_window_send_maximize(window);
     893}
     894
     895/** Window decoration requested window unmaximization.
     896 *
     897 * @param wdecor Window decoration
     898 * @param arg Argument (window)
     899 */
     900static void wd_unmaximize(ui_wdecor_t *wdecor, void *arg)
     901{
     902        ui_window_t *window = (ui_window_t *) arg;
     903
     904        ui_window_send_unmaximize(window);
    848905}
    849906
     
    9481005}
    9491006
     1007/** Send window maximize event.
     1008 *
     1009 * @param window Window
     1010 */
     1011void ui_window_send_maximize(ui_window_t *window)
     1012{
     1013        if (window->cb != NULL && window->cb->maximize != NULL)
     1014                window->cb->maximize(window, window->arg);
     1015        else
     1016                ui_window_def_maximize(window);
     1017}
     1018
     1019/** Send window unmaximize event.
     1020 *
     1021 * @param window Window
     1022 */
     1023void ui_window_send_unmaximize(ui_window_t *window)
     1024{
     1025        if (window->cb != NULL && window->cb->unmaximize != NULL)
     1026                window->cb->unmaximize(window, window->arg);
     1027        else
     1028                ui_window_def_unmaximize(window);
     1029}
     1030
    9501031/** Send window close event.
    9511032 *
     
    10141095        else
    10151096                return ui_window_def_unfocus(window);
     1097}
     1098
     1099/** Default window maximize routine.
     1100 *
     1101 * @param window Window
     1102 * @return EOK on success or an error code
     1103 */
     1104errno_t ui_window_def_maximize(ui_window_t *window)
     1105{
     1106        errno_t rc;
     1107        gfx_rect_t old_rect;
     1108        gfx_rect_t rect;
     1109
     1110        old_rect = window->rect;
     1111
     1112        if (window->dwindow != NULL) {
     1113                rc = display_window_get_max_rect(window->dwindow, &rect);
     1114                if (rc != EOK)
     1115                        return rc;
     1116        } else {
     1117                rect = window->ui->rect;
     1118        }
     1119
     1120        ui_wdecor_set_maximized(window->wdecor, true);
     1121
     1122        rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
     1123        if (rc != EOK) {
     1124                ui_wdecor_set_maximized(window->wdecor, false);
     1125                return rc;
     1126        }
     1127
     1128        window->normal_rect = old_rect;
     1129        (void) ui_window_paint(window);
     1130        return EOK;
     1131}
     1132
     1133/** Default window unmaximize routine.
     1134 *
     1135 * @param window Window
     1136 * @return EOK on success or an error code
     1137 */
     1138errno_t ui_window_def_unmaximize(ui_window_t *window)
     1139{
     1140        errno_t rc;
     1141
     1142        ui_wdecor_set_maximized(window->wdecor, false);
     1143
     1144        rc = ui_window_size_change(window, &window->normal_rect,
     1145            ui_wsc_unmaximize);
     1146        if (rc != EOK) {
     1147                ui_wdecor_set_maximized(window->wdecor, true);
     1148                printf("ui_window_size_change->error\n");
     1149                return rc;
     1150        }
     1151
     1152        (void) ui_window_paint(window);
     1153        return EOK;
    10161154}
    10171155
Note: See TracChangeset for help on using the changeset viewer.