Changeset 453f9645 in mainline for uspace/lib/ui/src/filelist.c


Ignore:
Timestamp:
2022-06-16T10:05:17Z (22 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
54ddb59
Parents:
fdf55a3
git-author:
Jiri Svoboda <jiri@…> (2022-06-15 17:05:06)
git-committer:
Jiri Svoboda <jiri@…> (2022-06-16 10:05:17)
Message:

Add scroll bar to file list control

File:
1 edited

Legend:

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

    rfdf55a3 r453f9645  
    4545#include <ui/paint.h>
    4646#include <ui/resource.h>
     47#include <ui/scrollbar.h>
    4748#include <vfs/vfs.h>
    4849#include <qsort.h>
     
    7071};
    7172
     73static void ui_file_list_scrollbar_up(ui_scrollbar_t *, void *);
     74static void ui_file_list_scrollbar_down(ui_scrollbar_t *, void *);
     75static void ui_file_list_scrollbar_page_up(ui_scrollbar_t *, void *);
     76static void ui_file_list_scrollbar_page_down(ui_scrollbar_t *, void *);
     77static void ui_file_list_scrollbar_moved(ui_scrollbar_t *, void *, gfx_coord_t);
     78
     79/** File list scrollbar callbacks */
     80static ui_scrollbar_cb_t ui_file_list_scrollbar_cb = {
     81        .up = ui_file_list_scrollbar_up,
     82        .down = ui_file_list_scrollbar_down,
     83        .page_up = ui_file_list_scrollbar_page_up,
     84        .page_down = ui_file_list_scrollbar_page_down,
     85        .moved = ui_file_list_scrollbar_moved
     86};
     87
    7288/** Create file list.
    7389 *
     
    101117        if (rc != EOK)
    102118                goto error;
     119
     120        rc = ui_scrollbar_create(ui_window_get_ui(window), window,
     121            ui_sbd_vert, &flist->scrollbar);
     122        if (rc != EOK)
     123                goto error;
     124
     125        ui_scrollbar_set_cb(flist->scrollbar, &ui_file_list_scrollbar_cb,
     126            (void *) flist);
    103127
    104128        flist->window = window;
     
    341365                entry = ui_file_list_next(entry);
    342366        }
     367
     368        rc = ui_scrollbar_paint(flist->scrollbar);
     369        if (rc != EOK)
     370                return rc;
    343371
    344372        rc = gfx_update(gc);
     
    406434        gfx_coord_t line_height;
    407435        size_t entry_idx;
     436        ui_evclaim_t claim;
    408437        int n;
     438
     439        claim = ui_scrollbar_pos_event(flist->scrollbar, event);
     440        if (claim == ui_claimed)
     441                return ui_claimed;
    409442
    410443        line_height = ui_file_list_entry_height(flist);
     
    470503void ui_file_list_set_rect(ui_file_list_t *flist, gfx_rect_t *rect)
    471504{
     505        gfx_rect_t srect;
     506
    472507        flist->rect = *rect;
     508
     509        ui_file_list_scrollbar_rect(flist, &srect);
     510        ui_scrollbar_set_rect(flist->scrollbar, &srect);
    473511}
    474512
     
    488526}
    489527
     528/** Get file list interior rectangle.
     529 *
     530 * @param flist File list
     531 * @param irect Place to store interior rectangle
     532 */
    490533void ui_file_list_inside_rect(ui_file_list_t *flist, gfx_rect_t *irect)
    491534{
    492535        ui_resource_t *res = ui_window_get_res(flist->window);
     536        gfx_rect_t rect;
     537        gfx_coord_t width;
    493538
    494539        if (res->textmode) {
    495                 *irect = flist->rect;
     540                rect = flist->rect;
    496541        } else {
    497                 ui_paint_get_inset_frame_inside(res, &flist->rect, irect);
    498         }
     542                ui_paint_get_inset_frame_inside(res, &flist->rect, &rect);
     543        }
     544
     545        if (res->textmode) {
     546                width = 1;
     547        } else {
     548                width = 23;
     549        }
     550
     551        irect->p0 = rect.p0;
     552        irect->p1.x = rect.p1.x - width;
     553        irect->p1.y = rect.p1.y;
     554}
     555
     556/** Get file list scrollbar rectangle.
     557 *
     558 * @param flist File list
     559 * @param irect Place to store interior rectangle
     560 */
     561void ui_file_list_scrollbar_rect(ui_file_list_t *flist, gfx_rect_t *srect)
     562{
     563        ui_resource_t *res = ui_window_get_res(flist->window);
     564        gfx_rect_t rect;
     565        gfx_coord_t width;
     566
     567        if (res->textmode) {
     568                rect = flist->rect;
     569        } else {
     570                ui_paint_get_inset_frame_inside(res, &flist->rect, &rect);
     571        }
     572
     573        if (res->textmode) {
     574                width = 1;
     575        } else {
     576                width = 23;
     577        }
     578
     579        srect->p0.x = rect.p1.x - width;
     580        srect->p0.y = rect.p0.y;
     581        srect->p1 = rect.p1;
     582}
     583
     584/** Compute new position for file list scrollbar thumb.
     585 *
     586 * @param flist File list
     587 * @return New position
     588 */
     589gfx_coord_t ui_file_list_scrollbar_pos(ui_file_list_t *flist)
     590{
     591        size_t entries;
     592        size_t pglen;
     593        size_t sbar_len;
     594
     595        entries = list_count(&flist->entries);
     596        pglen = ui_file_list_page_size(flist);
     597        sbar_len = ui_scrollbar_move_length(flist->scrollbar);
     598
     599        if (entries > pglen)
     600                return sbar_len * flist->page_idx / (entries - pglen);
     601        else
     602                return 0;
     603}
     604
     605/** Update file list scrollbar position.
     606 *
     607 * @param flist File list
     608 */
     609void ui_file_list_scrollbar_update(ui_file_list_t *flist)
     610{
     611        ui_scrollbar_set_pos(flist->scrollbar,
     612            ui_file_list_scrollbar_pos(flist));
    499613}
    500614
     
    10301144                }
    10311145
     1146                ui_file_list_scrollbar_update(flist);
    10321147                (void) ui_file_list_paint(flist);
    10331148        }
     
    10831198}
    10841199
    1085 /** Move one page up.
     1200/** Move cursor one page up.
    10861201 *
    10871202 * @param flist File list
     
    11241239        if (flist->page != old_page) {
    11251240                /* We have scrolled. Need to repaint all entries */
     1241                ui_file_list_scrollbar_update(flist);
    11261242                (void) ui_file_list_paint(flist);
    11271243        } else if (flist->cursor != old_cursor) {
     
    11341250}
    11351251
    1136 /** Move one page down.
     1252/** Move cursor one page down.
    11371253 *
    11381254 * @param flist File list
     
    11821298        if (flist->page != old_page) {
    11831299                /* We have scrolled. Need to repaint all entries */
     1300                ui_file_list_scrollbar_update(flist);
    11841301                (void) ui_file_list_paint(flist);
    11851302        } else if (flist->cursor != old_cursor) {
     
    11901307                (void) gfx_update(gc);
    11911308        }
     1309}
     1310
     1311/** Scroll one entry up.
     1312 *
     1313 * @param flist File list
     1314 */
     1315void ui_file_list_scroll_up(ui_file_list_t *flist)
     1316{
     1317        ui_file_list_entry_t *prev;
     1318
     1319        prev = ui_file_list_prev(flist->page);
     1320        if (prev == NULL)
     1321                return;
     1322
     1323        flist->page = prev;
     1324        assert(flist->page_idx > 0);
     1325        --flist->page_idx;
     1326
     1327        ui_file_list_scrollbar_update(flist);
     1328        (void) ui_file_list_paint(flist);
     1329}
     1330
     1331/** Scroll one entry down.
     1332 *
     1333 * @param flist File list
     1334 */
     1335void ui_file_list_scroll_down(ui_file_list_t *flist)
     1336{
     1337        ui_file_list_entry_t *next;
     1338        ui_file_list_entry_t *pgend;
     1339        size_t i;
     1340        size_t rows;
     1341
     1342        next = ui_file_list_next(flist->page);
     1343        if (next == NULL)
     1344                return;
     1345
     1346        rows = ui_file_list_page_size(flist);
     1347
     1348        /* Find last page entry */
     1349        pgend = flist->page;
     1350        for (i = 0; i < rows && pgend != NULL; i++) {
     1351                pgend = ui_file_list_next(pgend);
     1352        }
     1353
     1354        /* Scroll down by one entry, if the page remains full */
     1355        if (pgend != NULL) {
     1356                flist->page = next;
     1357                ++flist->page_idx;
     1358        }
     1359
     1360        ui_file_list_scrollbar_update(flist);
     1361        (void) ui_file_list_paint(flist);
     1362}
     1363
     1364/** Scroll one page up.
     1365 *
     1366 * @param flist File list
     1367 */
     1368void ui_file_list_scroll_page_up(ui_file_list_t *flist)
     1369{
     1370        ui_file_list_entry_t *prev;
     1371        size_t i;
     1372        size_t rows;
     1373
     1374        prev = ui_file_list_prev(flist->page);
     1375        if (prev == NULL)
     1376                return;
     1377
     1378        rows = ui_file_list_page_size(flist);
     1379
     1380        for (i = 0; i < rows && prev != NULL; i++) {
     1381                flist->page = prev;
     1382                assert(flist->page_idx > 0);
     1383                --flist->page_idx;
     1384                prev = ui_file_list_prev(prev);
     1385        }
     1386
     1387        ui_file_list_scrollbar_update(flist);
     1388        (void) ui_file_list_paint(flist);
     1389}
     1390
     1391/** Scroll one page down.
     1392 *
     1393 * @param flist File list
     1394 */
     1395void ui_file_list_scroll_page_down(ui_file_list_t *flist)
     1396{
     1397        ui_file_list_entry_t *next;
     1398        ui_file_list_entry_t *pgend;
     1399        size_t i;
     1400        size_t rows;
     1401
     1402        next = ui_file_list_next(flist->page);
     1403        if (next == NULL)
     1404                return;
     1405
     1406        rows = ui_file_list_page_size(flist);
     1407
     1408        /* Find last page entry */
     1409        pgend = flist->page;
     1410        for (i = 0; i < rows && pgend != NULL; i++) {
     1411                pgend = ui_file_list_next(pgend);
     1412        }
     1413
     1414        /* Scroll by up to 'rows' entries, keeping the page full */
     1415        for (i = 0; i < rows && pgend != NULL; i++) {
     1416                flist->page = next;
     1417                ++flist->page_idx;
     1418                next = ui_file_list_next(next);
     1419                pgend = ui_file_list_next(pgend);
     1420        }
     1421
     1422        ui_file_list_scrollbar_update(flist);
     1423        (void) ui_file_list_paint(flist);
     1424}
     1425
     1426/** Scroll to a specific entry
     1427 *
     1428 * @param flist File list
     1429 * @param page_idx New index of first entry on the page
     1430 */
     1431void ui_file_list_scroll_pos(ui_file_list_t *flist, size_t page_idx)
     1432{
     1433        ui_file_list_entry_t *entry;
     1434        size_t i;
     1435
     1436        entry = ui_file_list_first(flist);
     1437        for (i = 0; i < page_idx; i++) {
     1438                entry = ui_file_list_next(entry);
     1439                assert(entry != NULL);
     1440        }
     1441
     1442        flist->page = entry;
     1443        flist->page_idx = page_idx;
     1444
     1445        (void) ui_file_list_paint(flist);
    11921446}
    11931447
     
    12931547}
    12941548
     1549/** File list scrollbar up button pressed.
     1550 *
     1551 * @param scrollbar Scrollbar
     1552 * @param arg Argument (ui_file_list_t *)
     1553 */
     1554static void ui_file_list_scrollbar_up(ui_scrollbar_t *scrollbar, void *arg)
     1555{
     1556        ui_file_list_t *flist = (ui_file_list_t *)arg;
     1557        ui_file_list_scroll_up(flist);
     1558}
     1559
     1560/** File list scrollbar down button pressed.
     1561 *
     1562 * @param scrollbar Scrollbar
     1563 * @param arg Argument (ui_file_list_t *)
     1564 */
     1565static void ui_file_list_scrollbar_down(ui_scrollbar_t *scrollbar, void *arg)
     1566{
     1567        ui_file_list_t *flist = (ui_file_list_t *)arg;
     1568        ui_file_list_scroll_down(flist);
     1569}
     1570
     1571/** File list scrollbar page up pressed.
     1572 *
     1573 * @param scrollbar Scrollbar
     1574 * @param arg Argument (ui_file_list_t *)
     1575 */
     1576static void ui_file_list_scrollbar_page_up(ui_scrollbar_t *scrollbar, void *arg)
     1577{
     1578        ui_file_list_t *flist = (ui_file_list_t *)arg;
     1579        ui_file_list_scroll_page_up(flist);
     1580}
     1581
     1582/** File list scrollbar page down pressed.
     1583 *
     1584 * @param scrollbar Scrollbar
     1585 * @param arg Argument (ui_file_list_t *)
     1586 */
     1587static void ui_file_list_scrollbar_page_down(ui_scrollbar_t *scrollbar,
     1588    void *arg)
     1589{
     1590        ui_file_list_t *flist = (ui_file_list_t *)arg;
     1591        ui_file_list_scroll_page_down(flist);
     1592}
     1593
     1594/** File list scrollbar moved.
     1595 *
     1596 * @param scrollbar Scrollbar
     1597 * @param arg Argument (ui_file_list_t *)
     1598 */
     1599static void ui_file_list_scrollbar_moved(ui_scrollbar_t *scrollbar, void *arg,
     1600    gfx_coord_t pos)
     1601{
     1602        ui_file_list_t *flist = (ui_file_list_t *)arg;
     1603        size_t entries;
     1604        size_t pglen;
     1605        size_t sbar_len;
     1606        size_t pgstart;
     1607
     1608        entries = list_count(&flist->entries);
     1609        pglen = ui_file_list_page_size(flist);
     1610        sbar_len = ui_scrollbar_move_length(flist->scrollbar);
     1611
     1612        if (entries > pglen)
     1613                pgstart = (entries - pglen) * pos / (sbar_len - 1);
     1614        else
     1615                pgstart = 0;
     1616
     1617        ui_file_list_scroll_pos(flist, pgstart);
     1618}
     1619
    12951620/** @}
    12961621 */
Note: See TracChangeset for help on using the changeset viewer.