Ignore:
File:
1 edited

Legend:

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

    r252d03c r211fd68  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4545#include <ui/paint.h>
    4646#include <ui/pbutton.h>
     47#include <ui/ui.h>
    4748#include <ui/wdecor.h>
    4849#include "../private/resource.h"
    4950#include "../private/wdecor.h"
    5051
    51 static void ui_wdecor_btn_clicked(ui_pbutton_t *, void *);
     52static void ui_wdecor_btn_min_clicked(ui_pbutton_t *, void *);
     53static errno_t ui_wdecor_btn_min_paint(ui_pbutton_t *, void *,
     54    gfx_coord2_t *);
     55
     56static void ui_wdecor_btn_max_clicked(ui_pbutton_t *, void *);
     57static errno_t ui_wdecor_btn_max_paint(ui_pbutton_t *, void *,
     58    gfx_coord2_t *);
     59
     60static void ui_wdecor_btn_close_clicked(ui_pbutton_t *, void *);
     61static errno_t ui_wdecor_btn_close_paint(ui_pbutton_t *, void *,
     62    gfx_coord2_t *);
     63
     64static ui_pbutton_cb_t ui_wdecor_btn_min_cb = {
     65        .clicked = ui_wdecor_btn_min_clicked
     66};
     67
     68static ui_pbutton_decor_ops_t ui_wdecor_btn_min_decor_ops = {
     69        .paint = ui_wdecor_btn_min_paint
     70};
     71
     72static ui_pbutton_cb_t ui_wdecor_btn_max_cb = {
     73        .clicked = ui_wdecor_btn_max_clicked
     74};
     75
     76static ui_pbutton_decor_ops_t ui_wdecor_btn_max_decor_ops = {
     77        .paint = ui_wdecor_btn_max_paint
     78};
    5279
    5380static ui_pbutton_cb_t ui_wdecor_btn_close_cb = {
    54         .clicked = ui_wdecor_btn_clicked
     81        .clicked = ui_wdecor_btn_close_clicked
    5582};
    5683
     84static ui_pbutton_decor_ops_t ui_wdecor_btn_close_decor_ops = {
     85        .paint = ui_wdecor_btn_close_paint
     86};
     87
    5788enum {
     89        /** Width of corner drag area */
    5890        wdecor_corner_w = 24,
     91        /** Height of corner drag area */
    5992        wdecor_corner_h = 24,
     93        /** Window resizing edge witdth */
    6094        wdecor_edge_w = 4,
     95        /** Window resizing edge height */
    6196        wdecor_edge_h = 4,
     97        /** Window resizing edge witdth */
     98        wdecor_edge_w_text = 1,
     99        /** Window resizing edge height */
     100        wdecor_edge_h_text = 1,
     101        /** Title bar height */
    62102        wdecor_tbar_h = 22,
    63         wdecor_tbar_h_text = 1,
     103        /** Window width */
    64104        wdecor_frame_w = 4,
    65         wdecor_frame_w_text = 1
     105        /** Window frame width in text mode */
     106        wdecor_frame_w_text = 1,
     107        /** Window caption horizontal margin */
     108        wdecor_cap_hmargin = 4,
     109        /** Window caption horizontal margin in text mode */
     110        wdecor_cap_hmargin_text = 1,
     111        /** System menu handle width */
     112        wdecor_sysmenu_hdl_w = 20,
     113        /** System menu handle height */
     114        wdecor_sysmenu_hdl_h = 20,
     115        /** System menu handle width in text mode */
     116        wdecor_sysmenu_hdl_w_text = 3,
     117        /** System menu handle height in text mode */
     118        wdecor_sysmenu_hdl_h_text = 1,
     119        /** Close button cross leg length */
     120        wdecor_close_cross_n = 5,
     121        /** Close button cross pen width */
     122        wdecor_close_cross_w = 2,
     123        /** Close button cross pen height */
     124        wdecor_close_cross_h = 1,
     125        /** Minimize icon width */
     126        wdecor_min_w = 10,
     127        /** Minimize icon height */
     128        wdecor_min_h = 10,
     129        /** Maximize icon width */
     130        wdecor_max_w = 10,
     131        /** Maximize icon height */
     132        wdecor_max_h = 10,
     133        /** Unmaximize icon window width */
     134        wdecor_unmax_w = 8,
     135        /** Unmaximize icon window height */
     136        wdecor_unmax_h = 8,
     137        /** Unmaximize icon window horizontal distance */
     138        wdecor_unmax_dw = 4,
     139        /** Unmaximize icon window vertical distance */
     140        wdecor_unmax_dh = 4
    66141};
    67142
     
    90165        }
    91166
    92         rc = ui_pbutton_create(resource, "X", &wdecor->btn_close);
    93         if (rc != EOK) {
    94                 free(wdecor->caption);
    95                 free(wdecor);
    96                 return rc;
    97         }
    98 
    99         ui_pbutton_set_cb(wdecor->btn_close, &ui_wdecor_btn_close_cb,
    100             (void *)wdecor);
     167        if ((style & ui_wds_minimize_btn) != 0) {
     168                rc = ui_pbutton_create(resource, "_", &wdecor->btn_min);
     169                if (rc != EOK) {
     170                        ui_wdecor_destroy(wdecor);
     171                        return rc;
     172                }
     173
     174                ui_pbutton_set_cb(wdecor->btn_min, &ui_wdecor_btn_min_cb,
     175                    (void *)wdecor);
     176
     177                ui_pbutton_set_decor_ops(wdecor->btn_min,
     178                    &ui_wdecor_btn_min_decor_ops, (void *)wdecor);
     179        }
     180
     181        if ((style & ui_wds_maximize_btn) != 0) {
     182                rc = ui_pbutton_create(resource, "^", &wdecor->btn_max);
     183                if (rc != EOK) {
     184                        ui_wdecor_destroy(wdecor);
     185                        return rc;
     186                }
     187
     188                ui_pbutton_set_cb(wdecor->btn_max, &ui_wdecor_btn_max_cb,
     189                    (void *)wdecor);
     190
     191                ui_pbutton_set_decor_ops(wdecor->btn_max,
     192                    &ui_wdecor_btn_max_decor_ops, (void *)wdecor);
     193        }
     194
     195        if ((style & ui_wds_close_btn) != 0) {
     196                rc = ui_pbutton_create(resource, "X", &wdecor->btn_close);
     197                if (rc != EOK) {
     198                        ui_wdecor_destroy(wdecor);
     199                        return rc;
     200                }
     201
     202                ui_pbutton_set_cb(wdecor->btn_close, &ui_wdecor_btn_close_cb,
     203                    (void *)wdecor);
     204
     205                ui_pbutton_set_decor_ops(wdecor->btn_close,
     206                    &ui_wdecor_btn_close_decor_ops, (void *)wdecor);
     207        }
    101208
    102209        wdecor->res = resource;
     
    116223                return;
    117224
     225        ui_pbutton_destroy(wdecor->btn_min);
     226        ui_pbutton_destroy(wdecor->btn_max);
    118227        ui_pbutton_destroy(wdecor->btn_close);
    119228        free(wdecor->caption);
     
    145254
    146255        ui_wdecor_get_geom(wdecor, &geom);
    147         ui_pbutton_set_rect(wdecor->btn_close, &geom.btn_close_rect);
     256
     257        if (wdecor->btn_min != NULL)
     258                ui_pbutton_set_rect(wdecor->btn_min, &geom.btn_min_rect);
     259        if (wdecor->btn_max != NULL)
     260                ui_pbutton_set_rect(wdecor->btn_max, &geom.btn_max_rect);
     261        if (wdecor->btn_close != NULL)
     262                ui_pbutton_set_rect(wdecor->btn_close, &geom.btn_close_rect);
    148263}
    149264
     
    158273{
    159274        wdecor->active = active;
     275}
     276
     277/** Set maximized flag.
     278 *
     279 * Active window is the one receiving keyboard events.
     280 *
     281 * @param wdecor Window decoration
     282 * @param maximized @c true iff window is maximized
     283 */
     284void ui_wdecor_set_maximized(ui_wdecor_t *wdecor, bool maximized)
     285{
     286        wdecor->maximized = maximized;
     287}
     288
     289/** Change caption.
     290 *
     291 * @param wdecor Window decoration
     292 * @param caption New caption
     293 *
     294 * @return EOK on success or an error code
     295 */
     296errno_t ui_wdecor_set_caption(ui_wdecor_t *wdecor, const char *caption)
     297{
     298        char *cdup;
     299
     300        cdup = str_dup(caption);
     301        if (cdup == NULL)
     302                return ENOMEM;
     303
     304        free(wdecor->caption);
     305        wdecor->caption = cdup;
     306
     307        ui_wdecor_paint(wdecor);
     308        return EOK;
     309}
     310
     311/** Paint system menu handle in graphics mode.
     312 *
     313 * @param wdecor Window decoration
     314 * @param rect System menu handle rectangle
     315 * @return EOK on success or an error code
     316 */
     317errno_t ui_wdecor_sysmenu_hdl_paint_gfx(ui_wdecor_t *wdecor, gfx_rect_t *rect)
     318{
     319        errno_t rc;
     320        gfx_rect_t mrect;
     321        gfx_rect_t inside;
     322        gfx_coord2_t center;
     323
     324        rc = gfx_set_color(wdecor->res->gc, wdecor->sysmenu_hdl_active ?
     325            wdecor->res->btn_shadow_color : wdecor->res->btn_face_color);
     326        if (rc != EOK)
     327                return rc;
     328
     329        rc = gfx_fill_rect(wdecor->res->gc, rect);
     330        if (rc != EOK)
     331                return rc;
     332
     333        center.x = (rect->p0.x + rect->p1.x) / 2;
     334        center.y = (rect->p0.y + rect->p1.y) / 2;
     335        mrect.p0.x = center.x - 7;
     336        mrect.p0.y = center.y - 1;
     337        mrect.p1.x = center.x + 7;
     338        mrect.p1.y = center.y + 1 + 1;
     339
     340        /* XXX Not really a bevel, just a frame */
     341        rc = ui_paint_bevel(wdecor->res->gc, &mrect,
     342            wdecor->res->btn_text_color, wdecor->res->btn_text_color, 1,
     343            &inside);
     344        if (rc != EOK)
     345                return rc;
     346
     347        rc = gfx_set_color(wdecor->res->gc, wdecor->res->btn_highlight_color);
     348        if (rc != EOK)
     349                return rc;
     350
     351        rc = gfx_fill_rect(wdecor->res->gc, &inside);
     352        if (rc != EOK)
     353                return rc;
     354
     355        return EOK;
     356}
     357
     358/** Paint system menu handle in text mode.
     359 *
     360 * @param wdecor Window decoration
     361 * @param rect System menu handle rectangle
     362 * @return EOK on success or an error code
     363 */
     364errno_t ui_wdecor_sysmenu_hdl_paint_text(ui_wdecor_t *wdecor, gfx_rect_t *rect)
     365{
     366        errno_t rc;
     367        gfx_text_fmt_t fmt;
     368
     369        rc = gfx_set_color(wdecor->res->gc, wdecor->sysmenu_hdl_active ?
     370            wdecor->res->btn_shadow_color : wdecor->res->btn_face_color);
     371
     372        gfx_text_fmt_init(&fmt);
     373        fmt.font = wdecor->res->font;
     374        fmt.color = wdecor->sysmenu_hdl_active ?
     375            wdecor->res->wnd_sel_text_color :
     376            wdecor->res->tbar_act_text_color;
     377        fmt.halign = gfx_halign_left;
     378        fmt.valign = gfx_valign_top;
     379
     380        rc = gfx_puttext(&rect->p0, &fmt, "[\u2261]");
     381        if (rc != EOK)
     382                return rc;
     383
     384        return EOK;
     385}
     386
     387/** Paint system menu handle.
     388 *
     389 * @param wdecor Window decoration
     390 * @param rect System menu handle rectangle
     391 * @return EOK on success or an error code
     392 */
     393errno_t ui_wdecor_sysmenu_hdl_paint(ui_wdecor_t *wdecor, gfx_rect_t *rect)
     394{
     395        errno_t rc;
     396
     397        if (wdecor->res->textmode)
     398                rc = ui_wdecor_sysmenu_hdl_paint_text(wdecor, rect);
     399        else
     400                rc = ui_wdecor_sysmenu_hdl_paint_gfx(wdecor, rect);
     401
     402        return rc;
     403}
     404
     405/** Set system menu handle active flag.
     406 *
     407 * @param wdecor Window decoration
     408 * @param active @c true iff handle should be active
     409 */
     410void ui_wdecor_sysmenu_hdl_set_active(ui_wdecor_t *wdecor, bool active)
     411{
     412        ui_wdecor_geom_t geom;
     413
     414        wdecor->sysmenu_hdl_active = active;
     415
     416        ui_wdecor_get_geom(wdecor, &geom);
     417        (void) ui_wdecor_sysmenu_hdl_paint(wdecor, &geom.sysmenu_hdl_rect);
     418        (void) gfx_update(wdecor->res->gc);
    160419}
    161420
     
    170429        gfx_rect_t rect;
    171430        gfx_rect_t trect;
     431        gfx_rect_t text_rect;
    172432        gfx_text_fmt_t fmt;
    173433        gfx_coord2_t pos;
     
    180440
    181441                if (wdecor->res->textmode != false) {
    182                         rc = ui_paint_bevel(wdecor->res->gc, &rect,
    183                             wdecor->res->wnd_frame_hi_color,
    184                             wdecor->res->wnd_frame_sh_color, 1, &rect);
     442                        rc = ui_paint_text_box(wdecor->res, &rect,
     443                            ui_box_double, wdecor->res->wnd_face_color);
    185444                        if (rc != EOK)
    186445                                return rc;
     
    208467                        if (rc != EOK)
    209468                                return rc;
    210                 }
    211 
    212                 rc = gfx_set_color(wdecor->res->gc, wdecor->active ?
    213                     wdecor->res->tbar_act_bg_color :
    214                     wdecor->res->tbar_inact_bg_color);
    215                 if (rc != EOK)
    216                         return rc;
    217 
    218                 rc = gfx_fill_rect(wdecor->res->gc, &trect);
    219                 if (rc != EOK)
    220                         return rc;
     469
     470                        rc = gfx_set_color(wdecor->res->gc, wdecor->active ?
     471                            wdecor->res->tbar_act_bg_color :
     472                            wdecor->res->tbar_inact_bg_color);
     473                        if (rc != EOK)
     474                                return rc;
     475
     476                        rc = gfx_fill_rect(wdecor->res->gc, &trect);
     477                        if (rc != EOK)
     478                                return rc;
     479                }
    221480
    222481                gfx_text_fmt_init(&fmt);
     482                fmt.font = wdecor->res->font;
    223483                fmt.color = wdecor->active ?
    224484                    wdecor->res->tbar_act_text_color :
     
    226486                fmt.halign = gfx_halign_center;
    227487                fmt.valign = gfx_valign_center;
    228 
    229                 pos.x = (trect.p0.x + trect.p1.x) / 2;
    230                 pos.y = (trect.p0.y + trect.p1.y) / 2;
    231 
    232                 rc = gfx_puttext(wdecor->res->font, &pos, &fmt, wdecor->caption);
     488                fmt.abbreviate = true;
     489                fmt.width = geom.caption_rect.p1.x -
     490                    geom.caption_rect.p0.x;
     491
     492                pos.x = (geom.caption_rect.p0.x + geom.caption_rect.p1.x) / 2;
     493                pos.y = (geom.caption_rect.p0.y + geom.caption_rect.p1.y) / 2;
     494
     495                if (wdecor->res->textmode) {
     496                        /* Make space around caption text */
     497                        gfx_text_rect(&pos, &fmt, wdecor->caption, &text_rect);
     498
     499                        /* Only make space if caption is non-empty */
     500                        if (text_rect.p0.x < text_rect.p1.x) {
     501                                text_rect.p0.x -= 1;
     502                                text_rect.p1.x += 1;
     503                        }
     504
     505                        rc = gfx_set_color(wdecor->res->gc, wdecor->active ?
     506                            wdecor->res->tbar_act_bg_color :
     507                            wdecor->res->tbar_inact_bg_color);
     508                        if (rc != EOK)
     509                                return rc;
     510
     511                        rc = gfx_fill_rect(wdecor->res->gc, &text_rect);
     512                        if (rc != EOK)
     513                                return rc;
     514                }
     515
     516                rc = gfx_puttext(&pos, &fmt, wdecor->caption);
    233517                if (rc != EOK)
    234518                        return rc;
    235519
    236                 if ((wdecor->style & ui_wds_close_btn) != 0) {
     520                if ((wdecor->style & ui_wds_sysmenu_hdl) != 0) {
     521                        rc = ui_wdecor_sysmenu_hdl_paint(wdecor,
     522                            &geom.sysmenu_hdl_rect);
     523                        if (rc != EOK)
     524                                return rc;
     525                }
     526
     527                if (wdecor->btn_min != NULL) {
     528                        rc = ui_pbutton_paint(wdecor->btn_min);
     529                        if (rc != EOK)
     530                                return rc;
     531                }
     532
     533                if (wdecor->btn_max != NULL) {
     534                        rc = ui_pbutton_paint(wdecor->btn_max);
     535                        if (rc != EOK)
     536                                return rc;
     537                }
     538
     539                if (wdecor->btn_close != NULL) {
    237540                        rc = ui_pbutton_paint(wdecor->btn_close);
    238541                        if (rc != EOK)
     
    248551}
    249552
     553/** Send decoration sysmenu open event.
     554 *
     555 * @param wdecor Window decoration
     556 * @param idev_id Input device ID
     557 */
     558void ui_wdecor_sysmenu_open(ui_wdecor_t *wdecor, sysarg_t idev_id)
     559{
     560        if (wdecor->cb != NULL && wdecor->cb->sysmenu_open != NULL)
     561                wdecor->cb->sysmenu_open(wdecor, wdecor->arg, idev_id);
     562}
     563
     564/** Send decoration sysmenu left event.
     565 *
     566 * @param wdecor Window decoration
     567 * @param idev_id Input device ID
     568 */
     569void ui_wdecor_sysmenu_left(ui_wdecor_t *wdecor, sysarg_t idev_id)
     570{
     571        if (wdecor->cb != NULL && wdecor->cb->sysmenu_left != NULL)
     572                wdecor->cb->sysmenu_left(wdecor, wdecor->arg, idev_id);
     573}
     574
     575/** Send decoration sysmenu right event.
     576 *
     577 * @param wdecor Window decoration
     578 * @param idev_id Input device ID
     579 */
     580void ui_wdecor_sysmenu_right(ui_wdecor_t *wdecor, sysarg_t idev_id)
     581{
     582        if (wdecor->cb != NULL && wdecor->cb->sysmenu_right != NULL)
     583                wdecor->cb->sysmenu_right(wdecor, wdecor->arg, idev_id);
     584}
     585
     586/** Send decoration sysmenu accelerator event.
     587 *
     588 * @param wdecor Window decoration
     589 * @param c Accelerator character
     590 * @param idev_id Input device ID
     591 */
     592void ui_wdecor_sysmenu_accel(ui_wdecor_t *wdecor, char32_t c, sysarg_t idev_id)
     593{
     594        if (wdecor->cb != NULL && wdecor->cb->sysmenu_right != NULL)
     595                wdecor->cb->sysmenu_accel(wdecor, wdecor->arg, c, idev_id);
     596}
     597
     598/** Send decoration minimize event.
     599 *
     600 * @param wdecor Window decoration
     601 */
     602void ui_wdecor_minimize(ui_wdecor_t *wdecor)
     603{
     604        if (wdecor->cb != NULL && wdecor->cb->minimize != NULL)
     605                wdecor->cb->minimize(wdecor, wdecor->arg);
     606}
     607
     608/** Send decoration maximize event.
     609 *
     610 * @param wdecor Window decoration
     611 */
     612void ui_wdecor_maximize(ui_wdecor_t *wdecor)
     613{
     614        if (wdecor->cb != NULL && wdecor->cb->maximize != NULL)
     615                wdecor->cb->maximize(wdecor, wdecor->arg);
     616}
     617
     618/** Send decoration unmaximize event.
     619 *
     620 * @param wdecor Window decoration
     621 */
     622void ui_wdecor_unmaximize(ui_wdecor_t *wdecor)
     623{
     624        if (wdecor->cb != NULL && wdecor->cb->unmaximize != NULL)
     625                wdecor->cb->unmaximize(wdecor, wdecor->arg);
     626}
     627
    250628/** Send decoration close event.
    251629 *
     
    262640 * @param wdecor Window decoration
    263641 * @param pos Position where the title bar was pressed
    264  */
    265 void ui_wdecor_move(ui_wdecor_t *wdecor, gfx_coord2_t *pos)
     642 * @param pos_id Positioning device ID
     643 */
     644void ui_wdecor_move(ui_wdecor_t *wdecor, gfx_coord2_t *pos, sysarg_t pos_id)
    266645{
    267646        if (wdecor->cb != NULL && wdecor->cb->move != NULL)
    268                 wdecor->cb->move(wdecor, wdecor->arg, pos);
     647                wdecor->cb->move(wdecor, wdecor->arg, pos, pos_id);
    269648}
    270649
     
    274653 * @param rsztype Resize type
    275654 * @param pos Position where the button was pressed
     655 * @param pos_id Positioning device ID
    276656 */
    277657void ui_wdecor_resize(ui_wdecor_t *wdecor, ui_wdecor_rsztype_t rsztype,
    278     gfx_coord2_t *pos)
     658    gfx_coord2_t *pos, sysarg_t pos_id)
    279659{
    280660        if (wdecor->cb != NULL && wdecor->cb->resize != NULL)
    281                 wdecor->cb->resize(wdecor, wdecor->arg, rsztype, pos);
     661                wdecor->cb->resize(wdecor, wdecor->arg, rsztype, pos, pos_id);
    282662}
    283663
     
    301681{
    302682        gfx_coord_t frame_w;
    303         gfx_coord_t tbar_h;
     683        gfx_coord_t btn_x;
     684        gfx_coord_t btn_y;
     685        gfx_coord_t cap_hmargin;
     686        gfx_coord_t cap_x;
     687        gfx_coord_t hdl_x_off;
     688        gfx_coord_t hdl_y_off;
     689        gfx_coord_t hdl_w;
     690        gfx_coord_t hdl_h;
    304691
    305692        /* Does window have a frame? */
     
    318705        /* Does window have a title bar? */
    319706        if ((wdecor->style & ui_wds_titlebar) != 0) {
    320                 tbar_h = wdecor->res->textmode ?
    321                     wdecor_tbar_h_text : wdecor_tbar_h;
    322 
    323                 geom->title_bar_rect.p0 = geom->interior_rect.p0;
    324                 geom->title_bar_rect.p1.x = geom->interior_rect.p1.x;
    325                 geom->title_bar_rect.p1.y = geom->interior_rect.p0.y + tbar_h;
     707                if (wdecor->res->textmode) {
     708                        geom->title_bar_rect.p0 = wdecor->rect.p0;
     709                        geom->title_bar_rect.p1.x = wdecor->rect.p1.x;
     710                        geom->title_bar_rect.p1.y = wdecor->rect.p0.y + 1;
     711
     712                        btn_x = geom->title_bar_rect.p1.x - 1;
     713                        btn_y = geom->title_bar_rect.p0.y;
     714                } else {
     715                        geom->title_bar_rect.p0 = geom->interior_rect.p0;
     716                        geom->title_bar_rect.p1.x = geom->interior_rect.p1.x;
     717                        geom->title_bar_rect.p1.y = geom->interior_rect.p0.y +
     718                            wdecor_tbar_h;
     719
     720                        btn_x = geom->title_bar_rect.p1.x - 1;
     721                        btn_y = geom->title_bar_rect.p0.y + 1;
     722                }
    326723
    327724                geom->app_area_rect.p0.x = geom->interior_rect.p0.x;
    328725                geom->app_area_rect.p0.y = geom->title_bar_rect.p1.y;
    329726                geom->app_area_rect.p1 = geom->interior_rect.p1;
     727
    330728        } else {
    331729                geom->title_bar_rect.p0.x = 0;
     
    335733
    336734                geom->app_area_rect = geom->interior_rect;
     735                btn_x = 0;
     736                btn_y = 0;
     737        }
     738
     739        /* Does window have a sysmenu handle? */
     740        if ((wdecor->style & ui_wds_sysmenu_hdl) != 0) {
     741                if (wdecor->res->textmode) {
     742                        hdl_x_off = 2;
     743                        hdl_y_off = 0;
     744                        hdl_w = wdecor_sysmenu_hdl_w_text;
     745                        hdl_h = wdecor_sysmenu_hdl_h_text;
     746                } else {
     747                        hdl_x_off = 1;
     748                        hdl_y_off = 1;
     749                        hdl_w = wdecor_sysmenu_hdl_w;
     750                        hdl_h = wdecor_sysmenu_hdl_h;
     751                }
     752
     753                geom->sysmenu_hdl_rect.p0.x = geom->title_bar_rect.p0.x +
     754                    hdl_x_off;
     755                geom->sysmenu_hdl_rect.p0.y = geom->title_bar_rect.p0.y +
     756                    hdl_y_off;
     757                geom->sysmenu_hdl_rect.p1.x = geom->sysmenu_hdl_rect.p0.x +
     758                    hdl_w;
     759                geom->sysmenu_hdl_rect.p1.y = geom->sysmenu_hdl_rect.p0.y +
     760                    hdl_h;
     761                cap_x = hdl_w;
     762        } else {
     763                geom->sysmenu_hdl_rect.p0.x = 0;
     764                geom->sysmenu_hdl_rect.p0.y = 0;
     765                geom->sysmenu_hdl_rect.p1.x = 0;
     766                geom->sysmenu_hdl_rect.p1.y = 0;
     767                cap_x = 0;
    337768        }
    338769
     
    340771        if ((wdecor->style & ui_wds_close_btn) != 0) {
    341772                if (wdecor->res->textmode == false) {
    342                         geom->btn_close_rect.p0.x =
    343                             geom->title_bar_rect.p1.x - 1 - 20;
    344                         geom->btn_close_rect.p0.y =
    345                             geom->title_bar_rect.p0.y + 1;
    346                         geom->btn_close_rect.p1.x =
    347                             geom->title_bar_rect.p1.x - 1;
    348                         geom->btn_close_rect.p1.y =
    349                             geom->title_bar_rect.p0.y + 1 + 20;
     773                        geom->btn_close_rect.p0.x = btn_x - 20;
     774                        geom->btn_close_rect.p0.y = btn_y;
     775                        geom->btn_close_rect.p1.x = btn_x;
     776                        geom->btn_close_rect.p1.y = btn_y + 20;
     777
     778                        btn_x -= 20;
    350779                } else {
    351                         geom->btn_close_rect.p0.x =
    352                             geom->title_bar_rect.p1.x - 1 - 3;
    353                         geom->btn_close_rect.p0.y =
    354                             geom->title_bar_rect.p0.y;
    355                         geom->btn_close_rect.p1.x =
    356                             geom->title_bar_rect.p1.x - 1;
    357                         geom->btn_close_rect.p1.y =
    358                             geom->title_bar_rect.p0.y + 1;
     780                        geom->btn_close_rect.p0.x = btn_x - 3;
     781                        geom->btn_close_rect.p0.y = btn_y;
     782                        geom->btn_close_rect.p1.x = btn_x;
     783                        geom->btn_close_rect.p1.y = btn_y + 1;
     784
     785                        btn_x -= 3;
    359786                }
    360787        } else {
     
    364791                geom->btn_close_rect.p1.y = 0;
    365792        }
     793
     794        /* Does window have a (un)maximize button? */
     795        if ((wdecor->style & ui_wds_maximize_btn) != 0) {
     796                if (wdecor->res->textmode == false) {
     797                        geom->btn_max_rect.p0.x = btn_x - 20;
     798                        geom->btn_max_rect.p0.y = btn_y;
     799                        geom->btn_max_rect.p1.x = btn_x;
     800                        geom->btn_max_rect.p1.y = btn_y + 20;
     801
     802                        btn_x -= 20;
     803                } else {
     804                        geom->btn_max_rect.p0.x = btn_x - 3;
     805                        geom->btn_max_rect.p0.y = btn_y;
     806                        geom->btn_max_rect.p1.x = btn_x;
     807                        geom->btn_max_rect.p1.y = btn_y + 1;
     808
     809                        btn_x -= 3;
     810                }
     811        } else {
     812                geom->btn_max_rect.p0.x = 0;
     813                geom->btn_max_rect.p0.y = 0;
     814                geom->btn_max_rect.p1.x = 0;
     815                geom->btn_max_rect.p1.y = 0;
     816        }
     817
     818        /* Does window have a minimize button? */
     819        if ((wdecor->style & ui_wds_minimize_btn) != 0) {
     820                if (wdecor->res->textmode == false) {
     821                        geom->btn_min_rect.p0.x = btn_x - 20;
     822                        geom->btn_min_rect.p0.y = btn_y;
     823                        geom->btn_min_rect.p1.x = btn_x;
     824                        geom->btn_min_rect.p1.y = btn_y + 20;
     825
     826                        btn_x -= 20;
     827                } else {
     828                        geom->btn_min_rect.p0.x = btn_x - 3;
     829                        geom->btn_min_rect.p0.y = btn_y;
     830                        geom->btn_min_rect.p1.x = btn_x;
     831                        geom->btn_min_rect.p1.y = btn_y + 1;
     832
     833                        btn_x -= 3;
     834                }
     835        } else {
     836                geom->btn_min_rect.p0.x = 0;
     837                geom->btn_min_rect.p0.y = 0;
     838                geom->btn_min_rect.p1.x = 0;
     839                geom->btn_min_rect.p1.y = 0;
     840        }
     841
     842        if ((wdecor->style & ui_wds_titlebar) != 0) {
     843                if (wdecor->res->textmode == false)
     844                        cap_hmargin = wdecor_cap_hmargin;
     845                else
     846                        cap_hmargin = wdecor_cap_hmargin_text;
     847
     848                geom->caption_rect.p0.x = geom->title_bar_rect.p0.x +
     849                    cap_hmargin + cap_x;
     850                geom->caption_rect.p0.y = geom->title_bar_rect.p0.y;
     851                geom->caption_rect.p1.x = btn_x - cap_hmargin;
     852                geom->caption_rect.p1.y = geom->title_bar_rect.p1.y;
     853        } else {
     854                geom->caption_rect.p0.x = 0;
     855                geom->caption_rect.p0.y = 0;
     856                geom->caption_rect.p1.x = 0;
     857                geom->caption_rect.p1.y = 0;
     858        }
    366859}
    367860
     
    372865 * and its decoration.
    373866 *
     867 * @param ui UI
    374868 * @param style Decoration style
    375869 * @param app Application area rectangle
    376870 * @param rect Place to store (outer) window decoration rectangle
    377871 */
    378 void ui_wdecor_rect_from_app(ui_wdecor_style_t style, gfx_rect_t *app,
    379     gfx_rect_t *rect)
    380 {
     872void ui_wdecor_rect_from_app(ui_t *ui, ui_wdecor_style_t style,
     873    gfx_rect_t *app, gfx_rect_t *rect)
     874{
     875        bool textmode;
     876        gfx_coord_t edge_w, edge_h;
    381877        *rect = *app;
    382878
     879        textmode = ui_is_textmode(ui);
     880        if (textmode) {
     881                edge_w = wdecor_edge_w_text;
     882                edge_h = wdecor_edge_h_text;
     883        } else {
     884                edge_w = wdecor_edge_w;
     885                edge_h = wdecor_edge_h;
     886        }
     887
    383888        if ((style & ui_wds_frame) != 0) {
    384                 rect->p0.x -= wdecor_edge_w;
    385                 rect->p0.y -= wdecor_edge_h;
    386                 rect->p1.x += wdecor_edge_w;
    387                 rect->p1.y += wdecor_edge_h;
    388         }
    389 
    390         if ((style & ui_wds_titlebar) != 0)
    391                 rect->p0.y -= 22;
     889                rect->p0.x -= edge_w;
     890                rect->p0.y -= edge_h;
     891                rect->p1.x += edge_w;
     892                rect->p1.y += edge_h;
     893        }
     894
     895        if ((style & ui_wds_titlebar) != 0 && !textmode)
     896                rect->p0.y -= wdecor_tbar_h;
    392897}
    393898
     
    437942                return ui_wr_none;
    438943
     944        /* Window is maximized? */
     945        if (wdecor->maximized)
     946                return ui_wr_none;
     947
    439948        /* Position not inside window? */
    440949        if (!gfx_pix_inside_rect(pos, &wdecor->rect))
     
    5261035}
    5271036
     1037/** Handle window decoration keyboard event.
     1038 *
     1039 * @param wdecor Window decoration
     1040 * @param kbd_event Keyboard event
     1041 * @return @c ui_claimed iff event was claimed
     1042 */
     1043ui_evclaim_t ui_wdecor_kbd_event(ui_wdecor_t *wdecor, kbd_event_t *event)
     1044{
     1045        if (event->type == KEY_PRESS && (event->mods & (KM_CTRL | KM_ALT |
     1046            KM_SHIFT)) == 0) {
     1047                if (event->key == KC_F10) {
     1048                        ui_wdecor_sysmenu_hdl_set_active(wdecor, true);
     1049                        ui_wdecor_sysmenu_open(wdecor, event->kbd_id);
     1050                        return ui_claimed;
     1051                }
     1052        }
     1053
     1054        /* System menu handle events (if active) */
     1055        if (event->type == KEY_PRESS && (event->mods & (KM_CTRL | KM_ALT |
     1056            KM_SHIFT)) == 0 && wdecor->sysmenu_hdl_active) {
     1057                switch (event->key) {
     1058                case KC_ESCAPE:
     1059                        ui_wdecor_sysmenu_hdl_set_active(wdecor, false);
     1060                        return ui_claimed;
     1061                case KC_LEFT:
     1062                        ui_wdecor_sysmenu_left(wdecor, event->kbd_id);
     1063                        return ui_claimed;
     1064                case KC_RIGHT:
     1065                        ui_wdecor_sysmenu_right(wdecor, event->kbd_id);
     1066                        return ui_claimed;
     1067                case KC_DOWN:
     1068                        ui_wdecor_sysmenu_open(wdecor, event->kbd_id);
     1069                        return ui_claimed;
     1070                default:
     1071                        break;
     1072                }
     1073
     1074                if (event->c != '\0') {
     1075                        /* Could be an accelerator key */
     1076                        ui_wdecor_sysmenu_accel(wdecor, event->c,
     1077                            event->kbd_id);
     1078                }
     1079        }
     1080
     1081        return ui_unclaimed;
     1082}
     1083
    5281084/** Handle window frame position event.
    5291085 *
     
    5341090{
    5351091        gfx_coord2_t pos;
     1092        sysarg_t pos_id;
    5361093        ui_wdecor_rsztype_t rsztype;
    5371094        ui_stock_cursor_t cursor;
     
    5391096        pos.x = event->hpos;
    5401097        pos.y = event->vpos;
     1098        pos_id = event->pos_id;
    5411099
    5421100        /* Set appropriate resizing cursor, or set arrow cursor */
     
    5491107        /* Press on window border? */
    5501108        if (rsztype != ui_wr_none && event->type == POS_PRESS)
    551                 ui_wdecor_resize(wdecor, rsztype, &pos);
     1109                ui_wdecor_resize(wdecor, rsztype, &pos, pos_id);
    5521110}
    5531111
     
    5611119{
    5621120        gfx_coord2_t pos;
     1121        sysarg_t pos_id;
    5631122        ui_wdecor_geom_t geom;
    5641123        ui_evclaim_t claim;
     
    5661125        pos.x = event->hpos;
    5671126        pos.y = event->vpos;
     1127        pos_id = event->pos_id;
    5681128
    5691129        ui_wdecor_get_geom(wdecor, &geom);
    5701130
    571         if ((wdecor->style & ui_wds_close_btn) != 0) {
     1131        if ((wdecor->style & ui_wds_titlebar) != 0 &&
     1132            (wdecor->style & ui_wds_sysmenu_hdl) != 0) {
     1133                if (event->type == POS_PRESS &&
     1134                    gfx_pix_inside_rect(&pos, &geom.sysmenu_hdl_rect)) {
     1135                        ui_wdecor_sysmenu_hdl_set_active(wdecor, true);
     1136                        ui_wdecor_sysmenu_open(wdecor, event->pos_id);
     1137                        return ui_claimed;
     1138                }
     1139        }
     1140
     1141        if (wdecor->btn_min != NULL) {
     1142                claim = ui_pbutton_pos_event(wdecor->btn_min, event);
     1143                if (claim == ui_claimed)
     1144                        return ui_claimed;
     1145        }
     1146
     1147        if (wdecor->btn_max != NULL) {
     1148                claim = ui_pbutton_pos_event(wdecor->btn_max, event);
     1149                if (claim == ui_claimed)
     1150                        return ui_claimed;
     1151        }
     1152
     1153        if (wdecor->btn_close != NULL) {
    5721154                claim = ui_pbutton_pos_event(wdecor->btn_close, event);
    5731155                if (claim == ui_claimed)
     
    5771159        ui_wdecor_frame_pos_event(wdecor, event);
    5781160
    579         if ((wdecor->style & ui_wds_titlebar) != 0) {
     1161        if ((wdecor->style & ui_wds_titlebar) != 0 && !wdecor->maximized) {
    5801162                if (event->type == POS_PRESS &&
    5811163                    gfx_pix_inside_rect(&pos, &geom.title_bar_rect)) {
    582                         ui_wdecor_move(wdecor, &pos);
     1164                        ui_wdecor_move(wdecor, &pos, pos_id);
    5831165                        return ui_claimed;
    5841166                }
     
    5861168
    5871169        return ui_unclaimed;
     1170}
     1171
     1172/** Window decoration minimize button was clicked.
     1173 *
     1174 * @param pbutton Minimize button
     1175 * @param arg Argument (ui_wdecor_t)
     1176 */
     1177static void ui_wdecor_btn_min_clicked(ui_pbutton_t *pbutton, void *arg)
     1178{
     1179        ui_wdecor_t *wdecor = (ui_wdecor_t *) arg;
     1180
     1181        (void) pbutton;
     1182
     1183        ui_wdecor_minimize(wdecor);
     1184}
     1185
     1186/** Window decoration (un)maximize button was clicked.
     1187 *
     1188 * @param pbutton (Un)maximize button
     1189 * @param arg Argument (ui_wdecor_t)
     1190 */
     1191static void ui_wdecor_btn_max_clicked(ui_pbutton_t *pbutton, void *arg)
     1192{
     1193        ui_wdecor_t *wdecor = (ui_wdecor_t *) arg;
     1194
     1195        (void) pbutton;
     1196
     1197        if (wdecor->maximized)
     1198                ui_wdecor_unmaximize(wdecor);
     1199        else
     1200                ui_wdecor_maximize(wdecor);
     1201}
     1202
     1203/** Paint minimize button decoration.
     1204 *
     1205 * @param pbutton Push button
     1206 * @param arg Argument (ui_wdecor_t *)
     1207 * @param pos Center position
     1208 */
     1209static errno_t ui_wdecor_btn_min_paint(ui_pbutton_t *pbutton,
     1210    void *arg, gfx_coord2_t *pos)
     1211{
     1212        ui_wdecor_t *wdecor = (ui_wdecor_t *)arg;
     1213        errno_t rc;
     1214
     1215        rc = ui_paint_minicon(wdecor->res, pos, wdecor_min_w,
     1216            wdecor_min_h);
     1217
     1218        return rc;
     1219}
     1220
     1221/** Paint (un)maximize button decoration.
     1222 *
     1223 * @param pbutton Push button
     1224 * @param arg Argument (ui_wdecor_t *)
     1225 * @param pos Center position
     1226 */
     1227static errno_t ui_wdecor_btn_max_paint(ui_pbutton_t *pbutton,
     1228    void *arg, gfx_coord2_t *pos)
     1229{
     1230        ui_wdecor_t *wdecor = (ui_wdecor_t *)arg;
     1231        errno_t rc;
     1232
     1233        if (wdecor->maximized) {
     1234                rc = ui_paint_unmaxicon(wdecor->res, pos, wdecor_unmax_w,
     1235                    wdecor_unmax_h, wdecor_unmax_dw, wdecor_unmax_dh);
     1236        } else {
     1237                rc = ui_paint_maxicon(wdecor->res, pos, wdecor_max_w,
     1238                    wdecor_max_h);
     1239        }
     1240
     1241        return rc;
    5881242}
    5891243
     
    5931247 * @param arg Argument (ui_wdecor_t)
    5941248 */
    595 static void ui_wdecor_btn_clicked(ui_pbutton_t *pbutton, void *arg)
     1249static void ui_wdecor_btn_close_clicked(ui_pbutton_t *pbutton, void *arg)
    5961250{
    5971251        ui_wdecor_t *wdecor = (ui_wdecor_t *) arg;
     
    6011255}
    6021256
     1257/** Paint close button decoration.
     1258 *
     1259 * @param pbutton Push button
     1260 * @param arg Argument (ui_wdecor_t *)
     1261 * @param pos Center position
     1262 */
     1263static errno_t ui_wdecor_btn_close_paint(ui_pbutton_t *pbutton,
     1264    void *arg, gfx_coord2_t *pos)
     1265{
     1266        ui_wdecor_t *wdecor = (ui_wdecor_t *)arg;
     1267        gfx_coord2_t p;
     1268        errno_t rc;
     1269
     1270        rc = gfx_set_color(wdecor->res->gc, wdecor->res->btn_text_color);
     1271        if (rc != EOK)
     1272                return rc;
     1273
     1274        p.x = pos->x - 1;
     1275        p.y = pos->y - 1;
     1276        return ui_paint_cross(wdecor->res->gc, &p, wdecor_close_cross_n,
     1277            wdecor_close_cross_w, wdecor_close_cross_h);
     1278}
     1279
    6031280/** @}
    6041281 */
Note: See TracChangeset for help on using the changeset viewer.