Changeset 2d879f7 in mainline for uspace/lib/ui/src/wdecor.c


Ignore:
Timestamp:
2020-11-26T11:59:59Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
554a5f1
Parents:
d8ddf7a
git-author:
Jiri Svoboda <jiri@…> (2020-11-25 18:46:07)
git-committer:
Jiri Svoboda <jiri@…> (2020-11-26 11:59:59)
Message:

Basic support for window resizing

File:
1 edited

Legend:

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

    rd8ddf7a r2d879f7  
    3434 */
    3535
     36#include <assert.h>
    3637#include <errno.h>
    3738#include <gfx/color.h>
     
    5455};
    5556
     57enum {
     58        wdecor_corner_w = 24,
     59        wdecor_corner_h = 24,
     60        wdecor_edge_w = 4,
     61        wdecor_edge_h = 4
     62};
     63
    5664/** Create new window decoration.
    5765 *
    5866 * @param resource UI resource
    5967 * @param caption Window caption
     68 * @param style Style
    6069 * @param rwdecor Place to store pointer to new window decoration
    6170 * @return EOK on success, ENOMEM if out of memory
    6271 */
    6372errno_t ui_wdecor_create(ui_resource_t *resource, const char *caption,
    64     ui_wdecor_t **rwdecor)
     73    ui_wdecor_style_t style, ui_wdecor_t **rwdecor)
    6574{
    6675        ui_wdecor_t *wdecor;
     
    8998        wdecor->res = resource;
    9099        wdecor->active = true;
     100        wdecor->style = style;
    91101        *rwdecor = wdecor;
    92102        return EOK;
     
    244254}
    245255
     256/** Send decoration resize event.
     257 *
     258 * @param wdecor Window decoration
     259 * @param rsztype Resize type
     260 * @param pos Position where the button was pressed
     261 */
     262void ui_wdecor_resize(ui_wdecor_t *wdecor, ui_wdecor_rsztype_t rsztype,
     263    gfx_coord2_t *pos)
     264{
     265        if (wdecor->cb != NULL && wdecor->cb->resize != NULL)
     266                wdecor->cb->resize(wdecor, wdecor->arg, rsztype, pos);
     267}
     268
     269/** Send cursor change event.
     270 *
     271 * @param wdecor Window decoration
     272 * @param cursor Cursor
     273 */
     274void ui_wdecor_set_cursor(ui_wdecor_t *wdecor, ui_stock_cursor_t cursor)
     275{
     276        if (wdecor->cb != NULL && wdecor->cb->set_cursor != NULL)
     277                wdecor->cb->set_cursor(wdecor, wdecor->arg, cursor);
     278}
     279
    246280/** Get window decoration geometry.
    247281 *
     
    287321}
    288322
     323/** Get resize type for pointer at the specified position.
     324 *
     325 * @param wdecor Window decoration
     326 * @param pos Pointer position
     327 * @return Resize type
     328 */
     329ui_wdecor_rsztype_t ui_wdecor_get_rsztype(ui_wdecor_t *wdecor,
     330    gfx_coord2_t *pos)
     331{
     332        bool eleft, eright;
     333        bool etop, ebottom;
     334        bool edge;
     335        bool cleft, cright;
     336        bool ctop, cbottom;
     337
     338        /* Window not resizable? */
     339        if ((wdecor->style & ui_wds_resizable) == 0)
     340                return ui_wr_none;
     341
     342        /* Position not inside window? */
     343        if (!gfx_pix_inside_rect(pos, &wdecor->rect))
     344                return ui_wr_none;
     345
     346        /* Position is within edge width from the outside */
     347        eleft = (pos->x < wdecor->rect.p0.x + wdecor_edge_w);
     348        eright = (pos->x >= wdecor->rect.p1.x - wdecor_edge_w);
     349        etop = (pos->y < wdecor->rect.p0.y + wdecor_edge_h);
     350        ebottom = (pos->y >= wdecor->rect.p1.y - wdecor_edge_h);
     351
     352        /* Position is on one of the four edges */
     353        edge = eleft || eright || etop || ebottom;
     354
     355        /* Position is within resize-corner distance from the outside */
     356        cleft = (pos->x < wdecor->rect.p0.x + wdecor_corner_w);
     357        cright = (pos->x >= wdecor->rect.p1.x - wdecor_corner_w);
     358        ctop = (pos->y < wdecor->rect.p0.y + wdecor_corner_h);
     359        cbottom = (pos->y >= wdecor->rect.p1.y - wdecor_corner_h);
     360
     361        /* Top-left corner */
     362        if (edge && cleft && ctop)
     363                return ui_wr_top_left;
     364
     365        /* Top-right corner */
     366        if (edge && cright && ctop)
     367                return ui_wr_top_right;
     368
     369        /* Bottom-left corner */
     370        if (edge && cleft && cbottom)
     371                return ui_wr_bottom_left;
     372
     373        /* Bottom-right corner */
     374        if (edge && cright && cbottom)
     375                return ui_wr_bottom_right;
     376
     377        /* Left edge */
     378        if (eleft)
     379                return ui_wr_left;
     380
     381        /* Right edge */
     382        if (eright)
     383                return ui_wr_right;
     384
     385        /* Top edge */
     386        if (etop)
     387                return ui_wr_top;
     388
     389        /* Bottom edge */
     390        if (ebottom)
     391                return ui_wr_bottom;
     392
     393        return ui_wr_none;
     394}
     395
     396/** Get stock cursor to use for the specified window resize type.
     397 *
     398 * The resize type must be valid, otherwise behavior is undefined.
     399 *
     400 * @param rsztype Resize type
     401 * @return Cursor to use for this resize type
     402 */
     403ui_stock_cursor_t ui_wdecor_cursor_from_rsztype(ui_wdecor_rsztype_t rsztype)
     404{
     405        switch (rsztype) {
     406        case ui_wr_none:
     407                return ui_curs_arrow;
     408
     409        case ui_wr_top:
     410        case ui_wr_bottom:
     411                return ui_curs_size_ud;
     412
     413        case ui_wr_left:
     414        case ui_wr_right:
     415                return ui_curs_size_lr;
     416
     417        case ui_wr_top_left:
     418        case ui_wr_bottom_right:
     419                return ui_curs_size_uldr;
     420
     421        case ui_wr_top_right:
     422        case ui_wr_bottom_left:
     423                return ui_curs_size_urdl;
     424
     425        default:
     426                assert(false);
     427                return ui_curs_arrow;
     428        }
     429}
     430
     431/** Handle window frame position event.
     432 *
     433 * @param wdecor Window decoration
     434 * @param pos_event Position event
     435 */
     436void ui_wdecor_frame_pos_event(ui_wdecor_t *wdecor, pos_event_t *event)
     437{
     438        gfx_coord2_t pos;
     439        ui_wdecor_rsztype_t rsztype;
     440        ui_stock_cursor_t cursor;
     441
     442        pos.x = event->hpos;
     443        pos.y = event->vpos;
     444
     445        /* Set appropriate resizing cursor, or set arrow cursor */
     446
     447        rsztype = ui_wdecor_get_rsztype(wdecor, &pos);
     448        cursor = ui_wdecor_cursor_from_rsztype(rsztype);
     449
     450        ui_wdecor_set_cursor(wdecor, cursor);
     451
     452        /* Press on window border? */
     453        if (rsztype != ui_wr_none && event->type == POS_PRESS)
     454                ui_wdecor_resize(wdecor, rsztype, &pos);
     455}
     456
    289457/** Handle window decoration position event.
    290458 *
     
    307475                return;
    308476
     477        ui_wdecor_frame_pos_event(wdecor, event);
     478
    309479        if (event->type == POS_PRESS &&
    310480            gfx_pix_inside_rect(&pos, &geom.title_bar_rect))
Note: See TracChangeset for help on using the changeset viewer.