Changeset 28ca31ed in mainline


Ignore:
Timestamp:
2024-02-13T20:13:48Z (2 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
10657856
Parents:
242e3c3
Message:

Moving start menu entry up and down

Location:
uspace
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/taskbar-cfg/startmenu.c

    r242e3c3 r28ca31ed  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5454static void startmenu_delete_entry_clicked(ui_pbutton_t *, void *);
    5555static void startmenu_edit_entry_clicked(ui_pbutton_t *, void *);
     56static void startmenu_up_entry_clicked(ui_pbutton_t *, void *);
     57static void startmenu_down_entry_clicked(ui_pbutton_t *, void *);
    5658
    5759/** Entry list callbacks */
     
    7375ui_pbutton_cb_t startmenu_edit_entry_button_cb = {
    7476        .clicked = startmenu_edit_entry_clicked
     77};
     78
     79/** Move entry up button callbacks */
     80ui_pbutton_cb_t startmenu_up_entry_button_cb = {
     81        .clicked = startmenu_up_entry_clicked
     82};
     83
     84/** Move entry down button callbacks */
     85ui_pbutton_cb_t startmenu_down_entry_button_cb = {
     86        .clicked = startmenu_down_entry_clicked
    7587};
    7688
     
    151163                rect.p0.y = 5;
    152164                rect.p1.x = 56;
    153                 rect.p1.y = 10;
     165                rect.p1.y = 20;
    154166        } else {
    155167                rect.p0.x = 20;
    156168                rect.p0.y = 80;
    157169                rect.p1.x = 360;
    158                 rect.p1.y = 180;
     170                rect.p1.y = 330;
    159171        }
    160172
     
    263275            &startmenu_edit_entry_button_cb, (void *)smenu);
    264276
     277        /* Move entry up button */
     278
     279        rc = ui_pbutton_create(ui_res, "Up", &smenu->up_entry);
     280        if (rc != EOK) {
     281                printf("Error creating button.\n");
     282                goto error;
     283        }
     284
     285        if (ui_resource_is_textmode(ui_res)) {
     286                rect.p0.x = 58;
     287                rect.p0.y = 12;
     288                rect.p1.x = 68;
     289                rect.p1.y = 13;
     290        } else {
     291                rect.p0.x = 370;
     292                rect.p0.y = 190;
     293                rect.p1.x = 450;
     294                rect.p1.y = 215;
     295        }
     296
     297        ui_pbutton_set_rect(smenu->up_entry, &rect);
     298
     299        rc = ui_fixed_add(smenu->fixed, ui_pbutton_ctl(smenu->up_entry));
     300        if (rc != EOK) {
     301                printf("Error adding control to layout.\n");
     302                goto error;
     303        }
     304
     305        ui_pbutton_set_cb(smenu->up_entry,
     306            &startmenu_up_entry_button_cb, (void *)smenu);
     307
     308        /* Move entry down button */
     309
     310        rc = ui_pbutton_create(ui_res, "Down", &smenu->down_entry);
     311        if (rc != EOK) {
     312                printf("Error creating button.\n");
     313                goto error;
     314        }
     315
     316        if (ui_resource_is_textmode(ui_res)) {
     317                rect.p0.x = 58;
     318                rect.p0.y = 14;
     319                rect.p1.x = 68;
     320                rect.p1.y = 15;
     321        } else {
     322                rect.p0.x = 370;
     323                rect.p0.y = 220;
     324                rect.p1.x = 450;
     325                rect.p1.y = 245;
     326        }
     327
     328        ui_pbutton_set_rect(smenu->down_entry, &rect);
     329
     330        rc = ui_fixed_add(smenu->fixed, ui_pbutton_ctl(smenu->down_entry));
     331        if (rc != EOK) {
     332                printf("Error adding control to layout.\n");
     333                goto error;
     334        }
     335
     336        ui_pbutton_set_cb(smenu->down_entry,
     337            &startmenu_down_entry_button_cb, (void *)smenu);
     338
    265339        ui_tab_add(smenu->tab, ui_fixed_ctl(smenu->fixed));
    266340
     
    268342        return EOK;
    269343error:
     344        if (smenu->down_entry != NULL)
     345                ui_pbutton_destroy(smenu->down_entry);
     346        if (smenu->up_entry != NULL)
     347                ui_pbutton_destroy(smenu->up_entry);
    270348        if (smenu->delete_entry != NULL)
    271349                ui_pbutton_destroy(smenu->delete_entry);
     
    488566        ui_list_entry_delete(smentry->lentry);
    489567        free(smentry);
    490         (void) ui_control_paint(ui_list_ctl(smenu->entries_list));
     568        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
    491569}
    492570
     
    504582}
    505583
     584/** Up entry button clicked.
     585 *
     586 * @param pbutton Push button
     587 * @param arg Argument (startmenu_t *)
     588 */
     589static void startmenu_up_entry_clicked(ui_pbutton_t *pbutton, void *arg)
     590{
     591        startmenu_t *smenu = (startmenu_t *)arg;
     592        startmenu_entry_t *smentry;
     593        errno_t rc;
     594
     595        (void)pbutton;
     596
     597        smentry = startmenu_get_selected(smenu);
     598        if (smentry == NULL)
     599                return;
     600
     601        rc = smenu_entry_move_up(smentry->entry);
     602        if (rc != EOK)
     603                return;
     604
     605        ui_list_entry_move_up(smentry->lentry);
     606
     607        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     608}
     609
     610/** Down entry button clicked.
     611 *
     612 * @param pbutton Push button
     613 * @param arg Argument (startmenu_t *)
     614 */
     615static void startmenu_down_entry_clicked(ui_pbutton_t *pbutton, void *arg)
     616{
     617        startmenu_t *smenu = (startmenu_t *)arg;
     618        startmenu_entry_t *smentry;
     619        errno_t rc;
     620
     621        (void)pbutton;
     622
     623        smentry = startmenu_get_selected(smenu);
     624        if (smentry == NULL)
     625                return;
     626
     627        rc = smenu_entry_move_up(smentry->entry);
     628        if (rc != EOK)
     629                return;
     630
     631        ui_list_entry_move_down(smentry->lentry);
     632
     633        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     634}
     635
    506636/** @}
    507637 */
  • uspace/app/taskbar-cfg/types/startmenu.h

    r242e3c3 r28ca31ed  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6262        /** Edit entry button */
    6363        ui_pbutton_t *edit_entry;
     64        /** Move entry up button */
     65        ui_pbutton_t *up_entry;
     66        /** Move entry down button */
     67        ui_pbutton_t *down_entry;
    6468} startmenu_t;
    6569
  • uspace/lib/tbarcfg/include/tbarcfg/tbarcfg.h

    r242e3c3 r28ca31ed  
    4747extern smenu_entry_t *tbarcfg_smenu_first(tbarcfg_t *);
    4848extern smenu_entry_t *tbarcfg_smenu_next(smenu_entry_t *);
     49extern smenu_entry_t *tbarcfg_smenu_last(tbarcfg_t *);
     50extern smenu_entry_t *tbarcfg_smenu_prev(smenu_entry_t *);
    4951extern const char *smenu_entry_get_caption(smenu_entry_t *);
    5052extern const char *smenu_entry_get_cmd(smenu_entry_t *);
     
    5759    bool, smenu_entry_t **);
    5860extern errno_t smenu_entry_destroy(smenu_entry_t *);
     61extern errno_t smenu_entry_move_up(smenu_entry_t *);
     62extern errno_t smenu_entry_move_down(smenu_entry_t *);
    5963
    6064#endif
  • uspace/lib/tbarcfg/src/tbarcfg.c

    r242e3c3 r28ca31ed  
    101101 * @return EOK on success or an error code
    102102 */
    103 #include <stdio.h>
    104103errno_t tbarcfg_open(const char *repopath, tbarcfg_t **rtbcfg)
    105104{
     
    160159                        terminal = "n";
    161160
    162                 printf("terminal=%s\n", terminal);
    163 
    164161                rc = smenu_entry_new(tbcfg, nentry, caption, cmd,
    165162                    str_cmp(terminal, "y") == 0, NULL);
     
    230227}
    231228
     229/** Get last start menu entry.
     230 *
     231 * @param tbcfg Taskbar configuration
     232 * @return Previous entry or @c NULL if the menu is empty
     233 */
     234smenu_entry_t *tbarcfg_smenu_last(tbarcfg_t *tbcfg)
     235{
     236        link_t *link;
     237
     238        link = list_last(&tbcfg->entries);
     239        if (link == NULL)
     240                return NULL;
     241
     242        return list_get_instance(link, smenu_entry_t, lentries);
     243}
     244
     245/** Get previous start menu entry.
     246 *
     247 * @param cur Current entry
     248 * @return Previous entry or @c NULL if @a cur is the last entry
     249 */
     250smenu_entry_t *tbarcfg_smenu_prev(smenu_entry_t *cur)
     251{
     252        link_t *link;
     253
     254        link = list_prev(&cur->lentries, &cur->smenu->entries);
     255        if (link == NULL)
     256                return NULL;
     257
     258        return list_get_instance(link, smenu_entry_t, lentries);
     259}
     260
    232261/** Get start menu entry caption.
    233262 *
     
    317346}
    318347
    319 /** Save any changes to start menu entry.
    320  *
    321  * @param entry Start menu entry
    322  */
    323 errno_t smenu_entry_save(smenu_entry_t *entry)
    324 {
    325         sif_trans_t *trans = NULL;
    326         errno_t rc;
    327 
    328         rc = sif_trans_begin(entry->smenu->repo, &trans);
    329         if (rc != EOK)
    330                 goto error;
     348/** Save start menu entry using transaction.
     349 *
     350 * @param entry Start menu entry
     351 * @param trans Transaction
     352 */
     353static errno_t smenu_entry_save_trans(smenu_entry_t *entry, sif_trans_t *trans)
     354{
     355        errno_t rc;
    331356
    332357        rc = sif_node_set_attr(trans, entry->nentry, "cmd", entry->cmd);
     
    340365        rc = sif_node_set_attr(trans, entry->nentry, "terminal",
    341366            entry->terminal ? "y" : "n");
     367        if (rc != EOK)
     368                goto error;
     369
     370        return EOK;
     371error:
     372        return rc;
     373}
     374
     375/** Save any changes to start menu entry.
     376 *
     377 * @param entry Start menu entry
     378 */
     379errno_t smenu_entry_save(smenu_entry_t *entry)
     380{
     381        sif_trans_t *trans = NULL;
     382        errno_t rc;
     383
     384        rc = sif_trans_begin(entry->smenu->repo, &trans);
     385        if (rc != EOK)
     386                goto error;
     387
     388        rc = smenu_entry_save_trans(entry, trans);
    342389        if (rc != EOK)
    343390                goto error;
     
    463510                goto error;
    464511
    465         rc = smenu_entry_new(smenu, nentry, caption, cmd, terminal ? "y" : "n",
    466             &entry);
     512        rc = smenu_entry_new(smenu, nentry, caption, cmd, terminal, &entry);
    467513        if (rc != EOK)
    468514                goto error;
     
    481527}
    482528
    483 /** Destroy start menu entry..
     529/** Destroy start menu entry.
    484530 *
    485531 * @param entry Start menu entry
     
    509555}
    510556
     557/** Move start menu entry up.
     558 *
     559 * @param entry Start menu entry
     560 * @return EOK on success or an error code
     561 */
     562errno_t smenu_entry_move_up(smenu_entry_t *entry)
     563{
     564        errno_t rc;
     565        sif_trans_t *trans = NULL;
     566        sif_node_t *nnode = NULL;
     567        sif_node_t *old_node;
     568        smenu_entry_t *prev;
     569
     570        rc = sif_trans_begin(entry->smenu->repo, &trans);
     571        if (rc != EOK)
     572                goto error;
     573
     574        prev = tbarcfg_smenu_prev(entry);
     575        if (prev == NULL) {
     576                /* Entry is already at first position, nothing to do. */
     577                return EOK;
     578        }
     579
     580        rc = sif_node_insert_before(trans, prev->nentry, "entry", &nnode);
     581        if (rc != EOK)
     582                goto error;
     583
     584        old_node = entry->nentry;
     585        entry->nentry = nnode;
     586
     587        rc = smenu_entry_save_trans(entry, trans);
     588        if (rc != EOK) {
     589                entry->nentry = old_node;
     590                goto error;
     591        }
     592
     593        sif_node_destroy(trans, old_node);
     594
     595        rc = sif_trans_end(trans);
     596        if (rc != EOK) {
     597                entry->nentry = old_node;
     598                goto error;
     599        }
     600
     601        list_remove(&entry->lentries);
     602        list_insert_before(&entry->lentries, &prev->lentries);
     603        return EOK;
     604error:
     605        if (nnode != NULL)
     606                sif_node_destroy(trans, nnode);
     607        if (trans != NULL)
     608                sif_trans_abort(trans);
     609        return rc;
     610}
     611
     612/** Move start menu entry down.
     613 *
     614 * @param entry Start menu entry
     615 * @return EOK on success or an error code
     616 */
     617errno_t smenu_entry_move_down(smenu_entry_t *entry)
     618{
     619        errno_t rc;
     620        sif_trans_t *trans = NULL;
     621        sif_node_t *nnode = NULL;
     622        sif_node_t *old_node;
     623        smenu_entry_t *next;
     624
     625        rc = sif_trans_begin(entry->smenu->repo, &trans);
     626        if (rc != EOK)
     627                goto error;
     628
     629        next = tbarcfg_smenu_next(entry);
     630        if (next == NULL) {
     631                /* Entry is already at last position, nothing to do. */
     632                return EOK;
     633        }
     634
     635        rc = sif_node_insert_after(trans, next->nentry, "entry", &nnode);
     636        if (rc != EOK)
     637                goto error;
     638
     639        old_node = entry->nentry;
     640        entry->nentry = nnode;
     641
     642        rc = smenu_entry_save_trans(entry, trans);
     643        if (rc != EOK) {
     644                entry->nentry = old_node;
     645                goto error;
     646        }
     647
     648        sif_node_destroy(trans, old_node);
     649
     650        rc = sif_trans_end(trans);
     651        if (rc != EOK) {
     652                entry->nentry = old_node;
     653                goto error;
     654        }
     655
     656        list_remove(&entry->lentries);
     657        list_insert_after(&entry->lentries, &next->lentries);
     658        return EOK;
     659error:
     660        if (nnode != NULL)
     661                sif_node_destroy(trans, nnode);
     662        if (trans != NULL)
     663                sif_trans_abort(trans);
     664        return rc;
     665}
     666
    511667/** @}
    512668 */
  • uspace/lib/tbarcfg/test/tbarcfg.c

    r242e3c3 r28ca31ed  
    101101}
    102102
     103/** Iterating over start menu entries backwards */
     104PCUT_TEST(last_prev)
     105{
     106        errno_t rc;
     107        tbarcfg_t *tbcfg;
     108        char fname[L_tmpnam], *p;
     109        smenu_entry_t *e1 = NULL, *e2 = NULL;
     110        smenu_entry_t *e;
     111
     112        p = tmpnam(fname);
     113        PCUT_ASSERT_NOT_NULL(p);
     114
     115        rc = tbarcfg_create(fname, &tbcfg);
     116        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     117
     118        rc = smenu_entry_create(tbcfg, "A", "a", false, &e1);
     119        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     120        PCUT_ASSERT_NOT_NULL(e1);
     121
     122        rc = smenu_entry_create(tbcfg, "B", "b", false, &e2);
     123        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     124        PCUT_ASSERT_NOT_NULL(e2);
     125
     126        e = tbarcfg_smenu_last(tbcfg);
     127        PCUT_ASSERT_EQUALS(e2, e);
     128        e = tbarcfg_smenu_prev(e);
     129        PCUT_ASSERT_EQUALS(e1, e);
     130        e = tbarcfg_smenu_prev(e);
     131        PCUT_ASSERT_NULL(e);
     132
     133        tbarcfg_close(tbcfg);
     134        remove(fname);
     135}
     136
    103137/** Getting menu entry properties */
    104138PCUT_TEST(get_caption_cmd_term)
     
    274308}
    275309
     310/** Move start menu entry up */
     311PCUT_TEST(entry_move_up)
     312{
     313        errno_t rc;
     314        tbarcfg_t *tbcfg;
     315        char fname[L_tmpnam], *p;
     316        smenu_entry_t *e1, *e2, *e3;
     317        smenu_entry_t *f;
     318        const char *caption;
     319        const char *cmd;
     320
     321        p = tmpnam(fname);
     322        PCUT_ASSERT_NOT_NULL(p);
     323
     324        rc = tbarcfg_create(fname, &tbcfg);
     325        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     326
     327        rc = smenu_entry_create(tbcfg, "A", "a", false, &e1);
     328        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     329
     330        rc = smenu_entry_create(tbcfg, "B", "b", false, &e2);
     331        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     332
     333        rc = smenu_entry_create(tbcfg, "C", "c", false, &e3);
     334        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     335
     336        f = tbarcfg_smenu_first(tbcfg);
     337        PCUT_ASSERT_EQUALS(e1, f);
     338
     339        /* Moving the first entry up should have no effect */
     340
     341        rc = smenu_entry_move_up(e1);
     342        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     343
     344        f = tbarcfg_smenu_first(tbcfg);
     345        PCUT_ASSERT_EQUALS(e1, f);
     346
     347        /* Moving the second entry up should move it to first position */
     348
     349        rc = smenu_entry_move_up(e2);
     350        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     351
     352        f = tbarcfg_smenu_first(tbcfg);
     353        PCUT_ASSERT_EQUALS(e2, f);
     354
     355        /* Moving the last entry up should move it to second position */
     356
     357        rc = smenu_entry_move_up(e3);
     358        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     359
     360        f = tbarcfg_smenu_first(tbcfg);
     361        PCUT_ASSERT_EQUALS(e2, f);
     362
     363        f = tbarcfg_smenu_next(f);
     364        PCUT_ASSERT_EQUALS(e3, f);
     365
     366        f = tbarcfg_smenu_next(f);
     367        PCUT_ASSERT_EQUALS(e1, f);
     368
     369        tbarcfg_close(tbcfg);
     370
     371        /* Re-open repository */
     372
     373        rc = tbarcfg_open(fname, &tbcfg);
     374        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     375
     376        /* Check that new order of entries persisted */
     377
     378        f = tbarcfg_smenu_first(tbcfg);
     379        PCUT_ASSERT_NOT_NULL(f);
     380
     381        caption = smenu_entry_get_caption(f);
     382        PCUT_ASSERT_STR_EQUALS("B", caption);
     383        cmd = smenu_entry_get_cmd(f);
     384        PCUT_ASSERT_STR_EQUALS("b", cmd);
     385
     386        f = tbarcfg_smenu_next(f);
     387        PCUT_ASSERT_NOT_NULL(f);
     388
     389        caption = smenu_entry_get_caption(f);
     390        PCUT_ASSERT_STR_EQUALS("C", caption);
     391        cmd = smenu_entry_get_cmd(f);
     392        PCUT_ASSERT_STR_EQUALS("c", cmd);
     393
     394        f = tbarcfg_smenu_next(f);
     395        PCUT_ASSERT_NOT_NULL(f);
     396
     397        caption = smenu_entry_get_caption(f);
     398        PCUT_ASSERT_STR_EQUALS("A", caption);
     399        cmd = smenu_entry_get_cmd(f);
     400        PCUT_ASSERT_STR_EQUALS("a", cmd);
     401
     402        tbarcfg_close(tbcfg);
     403        remove(fname);
     404}
     405
     406/** Move start menu entry down */
     407PCUT_TEST(entry_move_down)
     408{
     409        errno_t rc;
     410        tbarcfg_t *tbcfg;
     411        char fname[L_tmpnam], *p;
     412        smenu_entry_t *e1, *e2, *e3;
     413        smenu_entry_t *f;
     414        const char *caption;
     415        const char *cmd;
     416
     417        p = tmpnam(fname);
     418        PCUT_ASSERT_NOT_NULL(p);
     419
     420        rc = tbarcfg_create(fname, &tbcfg);
     421        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     422
     423        rc = smenu_entry_create(tbcfg, "A", "a", false, &e1);
     424        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     425
     426        rc = smenu_entry_create(tbcfg, "B", "b", false, &e2);
     427        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     428
     429        rc = smenu_entry_create(tbcfg, "C", "c", false, &e3);
     430        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     431
     432        f = tbarcfg_smenu_last(tbcfg);
     433        PCUT_ASSERT_EQUALS(e3, f);
     434
     435        /* Moving the last entry down should have no effect */
     436
     437        rc = smenu_entry_move_down(e3);
     438        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     439
     440        f = tbarcfg_smenu_last(tbcfg);
     441        PCUT_ASSERT_EQUALS(e3, f);
     442
     443        /* Moving the second entry down should move it to last position */
     444
     445        rc = smenu_entry_move_down(e2);
     446        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     447
     448        f = tbarcfg_smenu_last(tbcfg);
     449        PCUT_ASSERT_EQUALS(e2, f);
     450
     451        /* Moving the first entry down should move it to second position */
     452
     453        rc = smenu_entry_move_down(e1);
     454        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     455
     456        f = tbarcfg_smenu_last(tbcfg);
     457        PCUT_ASSERT_EQUALS(e2, f);
     458
     459        f = tbarcfg_smenu_prev(f);
     460        PCUT_ASSERT_EQUALS(e1, f);
     461
     462        f = tbarcfg_smenu_prev(f);
     463        PCUT_ASSERT_EQUALS(e3, f);
     464
     465        tbarcfg_close(tbcfg);
     466
     467        /* Re-open repository */
     468
     469        rc = tbarcfg_open(fname, &tbcfg);
     470        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     471
     472        /* Check that new order of entries persisted */
     473
     474        f = tbarcfg_smenu_first(tbcfg);
     475        PCUT_ASSERT_NOT_NULL(f);
     476
     477        caption = smenu_entry_get_caption(f);
     478        PCUT_ASSERT_STR_EQUALS("C", caption);
     479        cmd = smenu_entry_get_cmd(f);
     480        PCUT_ASSERT_STR_EQUALS("c", cmd);
     481
     482        f = tbarcfg_smenu_next(f);
     483        PCUT_ASSERT_NOT_NULL(f);
     484
     485        caption = smenu_entry_get_caption(f);
     486        PCUT_ASSERT_STR_EQUALS("A", caption);
     487        cmd = smenu_entry_get_cmd(f);
     488        PCUT_ASSERT_STR_EQUALS("a", cmd);
     489
     490        f = tbarcfg_smenu_next(f);
     491        PCUT_ASSERT_NOT_NULL(f);
     492
     493        caption = smenu_entry_get_caption(f);
     494        PCUT_ASSERT_STR_EQUALS("B", caption);
     495        cmd = smenu_entry_get_cmd(f);
     496        PCUT_ASSERT_STR_EQUALS("b", cmd);
     497
     498        tbarcfg_close(tbcfg);
     499        remove(fname);
     500}
     501
    276502PCUT_EXPORT(tbarcfg);
  • uspace/lib/ui/include/ui/list.h

    r242e3c3 r28ca31ed  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5757extern errno_t ui_list_entry_append(ui_list_t *,
    5858    ui_list_entry_attr_t *, ui_list_entry_t **);
     59extern void ui_list_entry_move_up(ui_list_entry_t *);
     60extern void ui_list_entry_move_down(ui_list_entry_t *);
    5961extern void ui_list_entry_delete(ui_list_entry_t *);
    6062extern void *ui_list_entry_get_arg(ui_list_entry_t *);
  • uspace/lib/ui/src/list.c

    r242e3c3 r28ca31ed  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    711711}
    712712
     713/** Move UI list entry one position up.
     714 *
     715 * @parm entry UI list entry
     716 */
     717void ui_list_entry_move_up(ui_list_entry_t *entry)
     718{
     719        ui_list_t *list = entry->list;
     720        ui_list_entry_t *prev;
     721
     722        prev = ui_list_prev(entry);
     723        if (prev == NULL) {
     724                /* Entry is already on first position, nothing to do. */
     725                return;
     726        }
     727
     728        list_remove(&entry->lentries);
     729        list_insert_before(&entry->lentries, &prev->lentries);
     730
     731        /* Make sure page stays on the same position/idx as it was before */
     732        if (list->page == entry) {
     733                list->page = prev;
     734        } else if (list->page == prev) {
     735                list->page = entry;
     736        }
     737
     738        /*
     739         * Return cursor to the same position/idx as it was before,
     740         * but then move it using ui_list_cursor_move() to the new
     741         * position (this ensures scrolling when needed).
     742         */
     743        if (list->cursor == entry) {
     744                list->cursor = prev;
     745                ui_list_cursor_move(list, entry, list->cursor_idx - 1);
     746        } else if (list->cursor == prev) {
     747                list->cursor = entry;
     748                ui_list_cursor_move(list, prev, list->cursor_idx + 1);
     749        }
     750}
     751
     752/** Move UI list entry one position down.
     753 *
     754 * @parm entry UI list entry
     755 */
     756void ui_list_entry_move_down(ui_list_entry_t *entry)
     757{
     758        ui_list_t *list = entry->list;
     759        ui_list_entry_t *next;
     760
     761        next = ui_list_next(entry);
     762        if (next == NULL) {
     763                /* Entry is already on last position, nothing to do. */
     764                return;
     765        }
     766
     767        list_remove(&entry->lentries);
     768        list_insert_after(&entry->lentries, &next->lentries);
     769
     770        /* Make sure page stays on the same position/idx as it was before */
     771        if (list->page == entry) {
     772                list->page = next;
     773        } else if (list->page == next) {
     774                list->page = entry;
     775        }
     776
     777        /*
     778         * Return cursor to the same position/idx as it was before,
     779         * but then move it using ui_list_cursor_move() to the new
     780         * position (this ensures scrolling when needed).
     781         */
     782        if (list->cursor == entry) {
     783                list->cursor = next;
     784                ui_list_cursor_move(list, entry, list->cursor_idx + 1);
     785        } else if (list->cursor == next) {
     786                list->cursor = entry;
     787                ui_list_cursor_move(list, next, list->cursor_idx - 1);
     788        }
     789}
     790
    713791/** Destroy UI list entry.
    714792 *
  • uspace/lib/ui/test/list.c

    r242e3c3 r28ca31ed  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    904904}
    905905
     906/** ui_list_entry_move_up() moves entry up */
     907PCUT_TEST(entry_move_up)
     908{
     909        ui_t *ui;
     910        ui_window_t *window;
     911        ui_wnd_params_t params;
     912        ui_list_t *list;
     913        ui_list_entry_attr_t attr;
     914        ui_list_entry_t *e1, *e2, *e3;
     915        ui_list_entry_t *e;
     916        errno_t rc;
     917
     918        rc = ui_create_disp(NULL, &ui);
     919        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     920
     921        ui_wnd_params_init(&params);
     922        params.caption = "Test";
     923
     924        rc = ui_window_create(ui, &params, &window);
     925        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     926
     927        rc = ui_list_create(window, true, &list);
     928        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     929
     930        ui_list_entry_attr_init(&attr);
     931
     932        /* Create entries */
     933
     934        attr.caption = "a";
     935        attr.arg = (void *)1;
     936        rc = ui_list_entry_append(list, &attr, &e1);
     937        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     938
     939        attr.caption = "b";
     940        attr.arg = (void *)2;
     941        rc = ui_list_entry_append(list, &attr, &e2);
     942        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     943
     944        attr.caption = "c";
     945        attr.arg = (void *)3;
     946        rc = ui_list_entry_append(list, &attr, &e3);
     947        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     948
     949        e = ui_list_first(list);
     950        PCUT_ASSERT_EQUALS(e1, e);
     951
     952        /* Moving first entry up should have no effect */
     953        ui_list_entry_move_up(e1);
     954
     955        e = ui_list_first(list);
     956        PCUT_ASSERT_EQUALS(e1, e);
     957
     958        e = ui_list_next(e);
     959        PCUT_ASSERT_EQUALS(e2, e);
     960
     961        e = ui_list_next(e);
     962        PCUT_ASSERT_EQUALS(e3, e);
     963
     964        e = ui_list_next(e);
     965        PCUT_ASSERT_NULL(e);
     966
     967        /* Move second entry up */
     968        ui_list_entry_move_up(e2);
     969
     970        e = ui_list_first(list);
     971        PCUT_ASSERT_EQUALS(e2, e);
     972
     973        e = ui_list_next(e);
     974        PCUT_ASSERT_EQUALS(e1, e);
     975
     976        e = ui_list_next(e);
     977        PCUT_ASSERT_EQUALS(e3, e);
     978
     979        e = ui_list_next(e);
     980        PCUT_ASSERT_NULL(e);
     981
     982        ui_list_destroy(list);
     983        ui_window_destroy(window);
     984        ui_destroy(ui);
     985}
     986
     987/** ui_list_entry_move_down() moves entry down */
     988PCUT_TEST(entry_move_down)
     989{
     990        ui_t *ui;
     991        ui_window_t *window;
     992        ui_wnd_params_t params;
     993        ui_list_t *list;
     994        ui_list_entry_attr_t attr;
     995        ui_list_entry_t *e1, *e2, *e3;
     996        ui_list_entry_t *e;
     997        errno_t rc;
     998
     999        rc = ui_create_disp(NULL, &ui);
     1000        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1001
     1002        ui_wnd_params_init(&params);
     1003        params.caption = "Test";
     1004
     1005        rc = ui_window_create(ui, &params, &window);
     1006        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1007
     1008        rc = ui_list_create(window, true, &list);
     1009        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1010
     1011        ui_list_entry_attr_init(&attr);
     1012
     1013        /* Create entries */
     1014
     1015        attr.caption = "a";
     1016        attr.arg = (void *)1;
     1017        rc = ui_list_entry_append(list, &attr, &e1);
     1018        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1019
     1020        attr.caption = "b";
     1021        attr.arg = (void *)2;
     1022        rc = ui_list_entry_append(list, &attr, &e2);
     1023        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1024
     1025        attr.caption = "c";
     1026        attr.arg = (void *)3;
     1027        rc = ui_list_entry_append(list, &attr, &e3);
     1028        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1029
     1030        e = ui_list_first(list);
     1031        PCUT_ASSERT_EQUALS(e1, e);
     1032
     1033        /* Moving last entry down should have no effect */
     1034        ui_list_entry_move_down(e3);
     1035
     1036        e = ui_list_first(list);
     1037        PCUT_ASSERT_EQUALS(e1, e);
     1038
     1039        e = ui_list_next(e);
     1040        PCUT_ASSERT_EQUALS(e2, e);
     1041
     1042        e = ui_list_next(e);
     1043        PCUT_ASSERT_EQUALS(e3, e);
     1044
     1045        e = ui_list_next(e);
     1046        PCUT_ASSERT_NULL(e);
     1047
     1048        /* Move second-to-last entry down */
     1049        ui_list_entry_move_down(e2);
     1050
     1051        e = ui_list_first(list);
     1052        PCUT_ASSERT_EQUALS(e1, e);
     1053
     1054        e = ui_list_next(e);
     1055        PCUT_ASSERT_EQUALS(e3, e);
     1056
     1057        e = ui_list_next(e);
     1058        PCUT_ASSERT_EQUALS(e2, e);
     1059
     1060        e = ui_list_next(e);
     1061        PCUT_ASSERT_NULL(e);
     1062
     1063        ui_list_destroy(list);
     1064        ui_window_destroy(window);
     1065        ui_destroy(ui);
     1066}
     1067
    9061068/** ui_list_entry_delete() deletes entry */
    9071069PCUT_TEST(entry_delete)
Note: See TracChangeset for help on using the changeset viewer.