Ignore:
File:
1 edited

Legend:

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

    r8279aab rb979ffb  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    171171 * @param window Window
    172172 * @param drect Display rectangle
     173 * @param wrect Window rectangle
     174 * @param prect Parent rectangle for popup placement or @c NULL
     175 * @param placement Window placement
    173176 * @param params Window parameters
    174177 * @param pos Place to store position of top-left corner
    175178 */
    176179static void ui_window_place(ui_window_t *window, gfx_rect_t *drect,
    177     ui_wnd_params_t *params, gfx_coord2_t *pos)
     180    gfx_rect_t *wrect, gfx_rect_t *prect, ui_wnd_placement_t placement,
     181    gfx_coord2_t *pos)
    178182{
    179183        gfx_coord2_t dims;
     
    181185        gfx_rect_t below_rect;
    182186
    183         assert(params->placement != ui_wnd_place_default ||
     187        assert(placement != ui_wnd_place_default ||
    184188            ui_is_fullscreen(window->ui));
    185189
     
    187191        pos->y = 0;
    188192
    189         switch (params->placement) {
     193        switch (placement) {
    190194        case ui_wnd_place_default:
    191195        case ui_wnd_place_center:
    192                 assert(params->placement != ui_wnd_place_default ||
     196                assert(placement != ui_wnd_place_default ||
    193197                    ui_is_fullscreen(window->ui));
    194198                /* Center window */
    195                 gfx_rect_dims(&params->rect, &dims);
     199                gfx_rect_dims(wrect, &dims);
    196200                pos->x = (drect->p0.x + drect->p1.x) / 2 - dims.x / 2;
    197201                pos->y = (drect->p0.y + drect->p1.y) / 2 - dims.y / 2;
     
    199203        case ui_wnd_place_top_left:
    200204        case ui_wnd_place_full_screen:
    201                 pos->x = drect->p0.x - params->rect.p0.x;
    202                 pos->y = drect->p0.y - params->rect.p0.y;
     205                pos->x = drect->p0.x - wrect->p0.x;
     206                pos->y = drect->p0.y - wrect->p0.y;
    203207                break;
    204208        case ui_wnd_place_top_right:
    205                 pos->x = drect->p1.x - params->rect.p1.x;
    206                 pos->y = drect->p0.y - params->rect.p0.y;
     209                pos->x = drect->p1.x - wrect->p1.x;
     210                pos->y = drect->p0.y - wrect->p0.y;
    207211                break;
    208212        case ui_wnd_place_bottom_left:
    209                 pos->x = drect->p0.x - params->rect.p0.x;
    210                 pos->y = drect->p1.y - params->rect.p1.y;
     213                pos->x = drect->p0.x - wrect->p0.x;
     214                pos->y = drect->p1.y - wrect->p1.y;
    211215                break;
    212216        case ui_wnd_place_bottom_right:
    213                 pos->x = drect->p1.x - params->rect.p1.x;
    214                 pos->y = drect->p1.y - params->rect.p1.y;
     217                pos->x = drect->p1.x - wrect->p1.x;
     218                pos->y = drect->p1.y - wrect->p1.y;
    215219                break;
    216220        case ui_wnd_place_popup:
    217221                /* Compute rectangle when placed below */
    218                 below_pos.x = params->prect.p0.x;
    219                 below_pos.y = params->prect.p1.y;
    220                 gfx_rect_translate(&below_pos, &params->rect, &below_rect);
     222                below_pos.x = prect->p0.x;
     223                below_pos.y = prect->p1.y;
     224                gfx_rect_translate(&below_pos, wrect, &below_rect);
    221225
    222226                /* Does below_rect fit within the display? */
    223227                if (gfx_rect_is_inside(&below_rect, drect)) {
    224228                        /* Place popup window below parent rectangle */
    225                         pos->x = params->prect.p0.x - params->rect.p0.x;
    226                         pos->y = params->prect.p1.y - params->rect.p0.y;
     229                        pos->x = prect->p0.x - wrect->p0.x;
     230                        pos->y = prect->p1.y - wrect->p0.y;
    227231                } else {
    228232                        /* Place popup window above parent rectangle */
    229                         pos->x = params->prect.p0.x;
    230                         pos->y = params->prect.p0.y -
    231                             (params->rect.p1.y - params->rect.p0.y);
     233                        pos->x = prect->p0.x;
     234                        pos->y = prect->p0.y -
     235                            (wrect->p1.y - wrect->p0.y);
    232236                }
    233237                break;
    234238        }
     239}
     240
     241static void ui_window_set_dpos(ui_window_t *window, gfx_coord2_t *dpos)
     242{
     243        window->dpos = *dpos;
     244        if (window->xgc != NULL)
     245                xlate_gc_set_off(window->xgc, &window->dpos);
    235246}
    236247
     
    334345        mem_gc_t *memgc = NULL;
    335346        xlate_gc_t *xgc = NULL;
     347        gfx_coord2_t dpos;
    336348        errno_t rc;
    337349
     
    384396                if (params->placement != ui_wnd_place_default) {
    385397                        /* Set initial display window position */
    386                         ui_window_place(window, &info.rect, params,
    387                             &dparams.pos);
     398                        ui_window_place(window, &info.rect, &params->rect,
     399                            &params->prect, params->placement, &dparams.pos);
    388400
    389401                        dparams.flags |= wndf_setpos;
     
    477489#endif
    478490        if (ui->display == NULL) {
    479                 ui_window_place(window, &ui->rect, params, &window->dpos);
    480 
    481                 if (window->xgc != NULL)
    482                         xlate_gc_set_off(window->xgc, &window->dpos);
     491                ui_window_place(window, &ui->rect, &params->rect, &params->prect,
     492                    params->placement, &dpos);
     493                ui_window_set_dpos(window, &dpos);
    483494        }
    484495
     
    538549}
    539550
     551/** Update window placement after screen resize (only in fullscreen UI).
     552 *
     553 * @param window UI window
     554 */
     555void ui_window_update_placement(ui_window_t *window)
     556{
     557        if (window->placement == ui_wnd_place_full_screen ||
     558            (window->flags & uiwf_maximized) != 0) {
     559                /* Update size of fullscreen or maximized window. */
     560                (void)ui_window_resize(window, &window->ui->rect);
     561                ui_window_send_resize(window);
     562        }
     563}
     564
    540565/** Destroy window.
    541566 *
     
    572597        /* Need to repaint if windows are emulated */
    573598        if (ui_is_fullscreen(ui)) {
    574                 ui_paint(ui);
     599                (void)ui_paint(ui);
    575600                /* Send focus event to newly active window */
    576601                nwindow = ui_window_get_active(ui);
     
    615640        window->control = NULL;
    616641        control->elemp = NULL;
     642}
     643
     644/** Get first (lowermost) window (only valid in fullscreen mode).
     645 *
     646 * @param ui User interface
     647 * @return First window
     648 */
     649ui_window_t *ui_window_first(ui_t *ui)
     650{
     651        link_t *link;
     652
     653        link = list_first(&ui->windows);
     654        if (link == NULL)
     655                return NULL;
     656
     657        return list_get_instance(link, ui_window_t, lwindows);
     658}
     659
     660/** Get next window (only valid in fullscreen mode).
     661 *
     662 * @param cur Current window
     663 * @return First window
     664 */
     665ui_window_t *ui_window_next(ui_window_t *cur)
     666{
     667        link_t *link;
     668
     669        link = list_next(&cur->lwindows, &cur->ui->windows);
     670        if (link == NULL)
     671                return NULL;
     672
     673        return list_get_instance(link, ui_window_t, lwindows);
    617674}
    618675
     
    653710        gfx_bitmap_alloc_t app_alloc;
    654711        gfx_bitmap_alloc_t win_alloc;
     712        gfx_coord2_t dpos;
    655713        errno_t rc;
    656714
     
    728786                        break;
    729787                }
     788        } else {
     789                /* fullscreen mode or unit tests */
     790                switch (scop) {
     791                case ui_wsc_resize:
     792                        break;
     793                case ui_wsc_maximize:
     794                        window->normal_dpos = window->dpos;
     795                        dpos.x = 0;
     796                        dpos.y = 0;
     797                        ui_window_set_dpos(window, &dpos);
     798                        break;
     799                case ui_wsc_unmaximize:
     800                        ui_window_set_dpos(window, &window->normal_dpos);
     801                        break;
     802                }
    730803        }
    731804
     
    735808                /* Window is resized, now we can map the window bitmap again */
    736809                gfx_bitmap_params_init(&win_params);
    737                 win_params.flags |= bmpf_direct_output;
     810                if (window->ui->display != NULL)
     811                        win_params.flags |= bmpf_direct_output;
    738812                win_params.rect = nrect;
    739813
     
    764838                gfx_bitmap_destroy(window->app_bmp);
    765839                window->app_bmp = app_bmp;
     840        }
     841
     842        switch (scop) {
     843        case ui_wsc_resize:
     844                break;
     845        case ui_wsc_maximize:
     846                window->flags |= uiwf_maximized;
     847                break;
     848        case ui_wsc_unmaximize:
     849                window->flags &= ~uiwf_maximized;
     850                break;
    766851        }
    767852
     
    787872errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
    788873{
    789         return ui_window_size_change(window, rect, ui_wsc_resize);
     874        errno_t rc;
     875
     876        rc = ui_window_size_change(window, rect, ui_wsc_resize);
     877        if (rc != EOK)
     878                return rc;
     879
     880        /* Need to repaint UI if windows are emulated */
     881        if (ui_is_fullscreen(window->ui))
     882                (void)ui_paint(window->ui);
     883
     884        return EOK;
    790885}
    791886
     
    14891584
    14901585        window->normal_rect = old_rect;
    1491         (void) ui_window_paint(window);
     1586        ui_window_send_resize(window);
     1587
     1588        /* Need to repaint UI if windows are emulated */
     1589        if (ui_is_fullscreen(window->ui))
     1590                (void)ui_paint(window->ui);
     1591
    14921592        return EOK;
    14931593}
     
    15141614        }
    15151615
    1516         (void) ui_window_paint(window);
     1616        ui_window_send_resize(window);
     1617
     1618        /* Need to repaint UI if windows are emulated */
     1619        if (ui_is_fullscreen(window->ui))
     1620                (void)ui_paint(window->ui);
     1621
    15171622        return EOK;
    15181623}
Note: See TracChangeset for help on using the changeset viewer.