Changeset 54ddb59 in mainline
- Timestamp:
- 2022-06-20T13:10:08Z (3 years ago)
- Branches:
- master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 52214a2
- Parents:
- 453f9645
- git-author:
- Jiri Svoboda <jiri@…> (2022-06-19 18:09:49)
- git-committer:
- Jiri Svoboda <jiri@…> (2022-06-20 13:10:08)
- Location:
- uspace
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/nav/nav.c
r453f9645 r54ddb59 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2022 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 40 40 #include <str.h> 41 41 #include <ui/fixed.h> 42 #include <ui/filelist.h> 42 43 #include <ui/resource.h> 43 44 #include <ui/ui.h> … … 314 315 315 316 panel = navigator_get_active_panel(navigator); 316 panel_open(panel, panel->cursor);317 ui_file_list_open(panel->flist, ui_file_list_get_cursor(panel->flist)); 317 318 } 318 319 -
uspace/app/nav/panel.c
r453f9645 r54ddb59 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2022 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 35 35 */ 36 36 37 #include <dirent.h>38 37 #include <errno.h> 39 38 #include <gfx/render.h> 40 39 #include <gfx/text.h> 41 40 #include <stdlib.h> 42 #include <str.h>43 41 #include <task.h> 44 42 #include <ui/control.h> 43 #include <ui/filelist.h> 45 44 #include <ui/paint.h> 46 45 #include <ui/resource.h> 47 #include <vfs/vfs.h>48 #include <qsort.h>49 46 #include "panel.h" 50 47 #include "nav.h" … … 56 53 57 54 /** Panel control ops */ 58 ui_control_ops_t panel_ctl_ops = {55 static ui_control_ops_t panel_ctl_ops = { 59 56 .destroy = panel_ctl_destroy, 60 57 .paint = panel_ctl_paint, … … 63 60 }; 64 61 62 static void panel_flist_selected(ui_file_list_t *, void *, const char *); 63 64 /** Panel file list callbacks */ 65 static ui_file_list_cb_t panel_flist_cb = { 66 .selected = panel_flist_selected 67 }; 68 65 69 /** Create panel. 66 70 * … … 90 94 goto error; 91 95 92 rc = gfx_color_new_ega(0x 30, &panel->curs_color);96 rc = gfx_color_new_ega(0x0f, &panel->act_border_color); 93 97 if (rc != EOK) 94 98 goto error; 95 99 96 rc = gfx_color_new_ega(0x0f, &panel->act_border_color);100 rc = ui_file_list_create(window, active, &panel->flist); 97 101 if (rc != EOK) 98 102 goto error; 99 103 100 rc = gfx_color_new_ega(0x0f, &panel->dir_color); 101 if (rc != EOK) 102 goto error; 103 104 rc = gfx_color_new_ega(0x0a, &panel->svc_color); 105 if (rc != EOK) 106 goto error; 104 ui_file_list_set_cb(panel->flist, &panel_flist_cb, (void *)panel); 107 105 108 106 panel->window = window; 109 list_initialize(&panel->entries);110 panel->entries_cnt = 0;111 107 panel->active = active; 112 108 *rpanel = panel; … … 115 111 if (panel->color != NULL) 116 112 gfx_color_delete(panel->color); 117 if (panel->curs_color != NULL)118 gfx_color_delete(panel->curs_color);119 113 if (panel->act_border_color != NULL) 120 114 gfx_color_delete(panel->act_border_color); 121 if (panel->dir_color != NULL) 122 gfx_color_delete(panel->dir_color); 123 if (panel->svc_color != NULL) 124 gfx_color_delete(panel->svc_color); 115 if (panel->flist != NULL) 116 ui_file_list_destroy(panel->flist); 125 117 ui_control_delete(panel->control); 126 118 free(panel); … … 135 127 { 136 128 gfx_color_delete(panel->color); 137 gfx_color_delete(panel->curs_color);138 129 gfx_color_delete(panel->act_border_color); 139 gfx_color_delete(panel->dir_color);140 gfx_color_delete(panel->svc_color);141 panel_clear_entries(panel);142 130 ui_control_delete(panel->control); 143 131 free(panel); … … 156 144 } 157 145 158 /** Paint panel entry. 159 * 160 * @param entry Panel entry 161 * @param entry_idx Entry index (within list of entries) 162 * @return EOK on success or an error code 163 */ 164 errno_t panel_entry_paint(panel_entry_t *entry, size_t entry_idx) 165 { 166 panel_t *panel = entry->panel; 146 /** Paint panel. 147 * 148 * @param panel Panel 149 */ 150 errno_t panel_paint(panel_t *panel) 151 { 167 152 gfx_context_t *gc = ui_window_get_gc(panel->window); 168 153 ui_resource_t *res = ui_window_get_res(panel->window); 169 gfx_font_t *font = ui_resource_get_font(res);170 gfx_text_fmt_t fmt;171 gfx_coord2_t pos;172 gfx_rect_t rect;173 size_t rows;174 errno_t rc;175 176 gfx_text_fmt_init(&fmt);177 fmt.font = font;178 rows = panel_page_size(panel);179 180 /* Do not display entry outside of current page */181 if (entry_idx < panel->page_idx ||182 entry_idx >= panel->page_idx + rows)183 return EOK;184 185 pos.x = panel->rect.p0.x + 1;186 pos.y = panel->rect.p0.y + 1 + entry_idx - panel->page_idx;187 188 if (entry == panel->cursor && panel->active)189 fmt.color = panel->curs_color;190 else if (entry->isdir)191 fmt.color = panel->dir_color;192 else if (entry->svc != 0)193 fmt.color = panel->svc_color;194 else195 fmt.color = panel->color;196 197 /* Draw entry background */198 rect.p0 = pos;199 rect.p1.x = panel->rect.p1.x - 1;200 rect.p1.y = rect.p0.y + 1;201 202 rc = gfx_set_color(gc, fmt.color);203 if (rc != EOK)204 return rc;205 206 rc = gfx_fill_rect(gc, &rect);207 if (rc != EOK)208 return rc;209 210 /*211 * Make sure name does not overflow the entry rectangle.212 *213 * XXX We probably want to measure the text width, and,214 * if it's too long, use gfx_text_find_pos() to find where215 * it should be cut off (and append some sort of overflow216 * marker.217 */218 rc = gfx_set_clip_rect(gc, &rect);219 if (rc != EOK)220 return rc;221 222 rc = gfx_puttext(&pos, &fmt, entry->name);223 if (rc != EOK) {224 (void) gfx_set_clip_rect(gc, NULL);225 return rc;226 }227 228 return gfx_set_clip_rect(gc, NULL);229 }230 231 /** Paint panel.232 *233 * @param panel Panel234 */235 errno_t panel_paint(panel_t *panel)236 {237 gfx_context_t *gc = ui_window_get_gc(panel->window);238 ui_resource_t *res = ui_window_get_res(panel->window);239 panel_entry_t *entry;240 154 ui_box_style_t bstyle; 241 155 gfx_color_t *bcolor; 242 int i, lines;156 ui_control_t *ctl; 243 157 errno_t rc; 244 158 … … 263 177 return rc; 264 178 265 lines = panel_page_size(panel); 266 i = 0; 267 268 entry = panel->page; 269 while (entry != NULL && i < lines) { 270 rc = panel_entry_paint(entry, panel->page_idx + i); 271 if (rc != EOK) 272 return rc; 273 274 ++i; 275 entry = panel_next(entry); 276 } 179 ctl = ui_file_list_ctl(panel->flist); 180 rc = ui_control_paint(ctl); 181 if (rc != EOK) 182 return rc; 277 183 278 184 rc = gfx_update(gc); … … 291 197 ui_evclaim_t panel_kbd_event(panel_t *panel, kbd_event_t *event) 292 198 { 199 ui_control_t *ctl; 200 293 201 if (!panel->active) 294 202 return ui_unclaimed; 295 203 296 if (event->type == KEY_PRESS) { 297 if ((event->mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) { 298 switch (event->key) { 299 case KC_UP: 300 panel_cursor_up(panel); 301 break; 302 case KC_DOWN: 303 panel_cursor_down(panel); 304 break; 305 case KC_HOME: 306 panel_cursor_top(panel); 307 break; 308 case KC_END: 309 panel_cursor_bottom(panel); 310 break; 311 case KC_PAGE_UP: 312 panel_page_up(panel); 313 break; 314 case KC_PAGE_DOWN: 315 panel_page_down(panel); 316 break; 317 case KC_ENTER: 318 panel_open(panel, panel->cursor); 319 break; 320 default: 321 break; 322 } 323 } 324 } 325 326 return ui_claimed; 204 ctl = ui_file_list_ctl(panel->flist); 205 return ui_control_kbd_event(ctl, event); 327 206 } 328 207 … … 336 215 { 337 216 gfx_coord2_t pos; 338 gfx_rect_t irect; 339 panel_entry_t *entry; 340 size_t entry_idx; 341 int n; 217 ui_control_t *ctl; 342 218 343 219 pos.x = event->hpos; … … 349 225 panel_activate_req(panel); 350 226 227 ctl = ui_file_list_ctl(panel->flist); 228 return ui_control_pos_event(ctl, event); 229 } 230 231 /** Get base control for panel. 232 * 233 * @param panel Panel 234 * @return Base UI control 235 */ 236 ui_control_t *panel_ctl(panel_t *panel) 237 { 238 return panel->control; 239 } 240 241 /** Set panel rectangle. 242 * 243 * @param panel Panel 244 * @param rect Rectangle 245 */ 246 void panel_set_rect(panel_t *panel, gfx_rect_t *rect) 247 { 248 gfx_rect_t irect; 249 250 panel->rect = *rect; 251 351 252 irect.p0.x = panel->rect.p0.x + 1; 352 253 irect.p0.y = panel->rect.p0.y + 1; 353 irect.p1.x = panel->rect.p1.x - 1;254 irect.p1.x = panel->rect.p1.x; 354 255 irect.p1.y = panel->rect.p1.y - 1; 355 256 356 if (event->type == POS_PRESS || event->type == POS_DCLICK) { 357 /* Did we click on one of the entries? */ 358 if (gfx_pix_inside_rect(&pos, &irect)) { 359 /* Index within page */ 360 n = pos.y - irect.p0.y; 361 362 /* Entry and its index within entire listing */ 363 entry = panel_page_nth_entry(panel, n, &entry_idx); 364 365 if (event->type == POS_PRESS) { 366 /* Move to the entry found */ 367 panel_cursor_move(panel, entry, entry_idx); 368 } else { 369 /* event->type == POS_DCLICK */ 370 panel_open(panel, entry); 371 } 372 } else { 373 /* It's in the border. */ 374 if (event->type == POS_PRESS) { 375 /* Top or bottom half? */ 376 if (pos.y >= (irect.p0.y + irect.p1.y) / 2) 377 panel_page_down(panel); 378 else 379 panel_page_up(panel); 380 } 381 } 382 } 383 384 return ui_claimed; 385 } 386 387 /** Get base control for panel. 388 * 389 * @param panel Panel 390 * @return Base UI control 391 */ 392 ui_control_t *panel_ctl(panel_t *panel) 393 { 394 return panel->control; 395 } 396 397 /** Set panel rectangle. 398 * 399 * @param panel Panel 400 * @param rect Rectangle 401 */ 402 void panel_set_rect(panel_t *panel, gfx_rect_t *rect) 403 { 404 panel->rect = *rect; 405 } 406 407 /** Get panel page size. 408 * 409 * @param panel Panel 410 * @return Number of entries that fit in panel at the same time. 411 */ 412 unsigned panel_page_size(panel_t *panel) 413 { 414 return panel->rect.p1.y - panel->rect.p0.y - 2; 257 ui_file_list_set_rect(panel->flist, &irect); 415 258 } 416 259 … … 435 278 errno_t rc; 436 279 437 if (panel->dir != NULL) { 438 rc = vfs_cwd_set(panel->dir); 439 if (rc != EOK) 440 return rc; 441 } 280 rc = ui_file_list_activate(panel->flist); 281 if (rc != EOK) 282 return rc; 442 283 443 284 panel->active = true; … … 452 293 void panel_deactivate(panel_t *panel) 453 294 { 295 ui_file_list_deactivate(panel->flist); 454 296 panel->active = false; 455 297 (void) panel_paint(panel); 456 }457 458 /** Initialize panel entry attributes.459 *460 * @param attr Attributes461 */462 void panel_entry_attr_init(panel_entry_attr_t *attr)463 {464 memset(attr, 0, sizeof(*attr));465 298 } 466 299 … … 514 347 } 515 348 516 /** Append new panel entry.517 *518 * @param panel Panel519 * @param attr Entry attributes520 * @return EOK on success or an error code521 */522 errno_t panel_entry_append(panel_t *panel, panel_entry_attr_t *attr)523 {524 panel_entry_t *entry;525 526 entry = calloc(1, sizeof(panel_entry_t));527 if (entry == NULL)528 return ENOMEM;529 530 entry->panel = panel;531 entry->name = str_dup(attr->name);532 if (entry->name == NULL) {533 free(entry);534 return ENOMEM;535 }536 537 entry->size = attr->size;538 entry->isdir = attr->isdir;539 entry->svc = attr->svc;540 link_initialize(&entry->lentries);541 list_append(&entry->lentries, &panel->entries);542 ++panel->entries_cnt;543 return EOK;544 }545 546 /** Delete panel entry.547 *548 * @param entry Panel entry549 */550 void panel_entry_delete(panel_entry_t *entry)551 {552 if (entry->panel->cursor == entry)553 entry->panel->cursor = NULL;554 if (entry->panel->page == entry)555 entry->panel->page = NULL;556 557 list_remove(&entry->lentries);558 --entry->panel->entries_cnt;559 free((char *) entry->name);560 free(entry);561 }562 563 /** Clear panel entry list.564 *565 * @param panel Panel566 */567 void panel_clear_entries(panel_t *panel)568 {569 panel_entry_t *entry;570 571 entry = panel_first(panel);572 while (entry != NULL) {573 panel_entry_delete(entry);574 entry = panel_first(panel);575 }576 }577 578 349 /** Read directory into panel entry list. 579 350 * … … 584 355 errno_t panel_read_dir(panel_t *panel, const char *dirname) 585 356 { 586 DIR *dir; 587 struct dirent *dirent; 588 vfs_stat_t finfo; 589 char newdir[256]; 590 char *ndir = NULL; 591 panel_entry_attr_t attr; 592 panel_entry_t *next; 593 panel_entry_t *prev; 594 char *olddn; 595 size_t pg_size; 596 size_t max_idx; 597 size_t i; 598 errno_t rc; 599 600 rc = vfs_cwd_set(dirname); 601 if (rc != EOK) 602 return rc; 603 604 rc = vfs_cwd_get(newdir, sizeof(newdir)); 605 if (rc != EOK) 606 return rc; 607 608 ndir = str_dup(newdir); 609 if (ndir == NULL) 610 return ENOMEM; 611 612 dir = opendir("."); 613 if (dir == NULL) { 614 rc = errno; 615 goto error; 616 } 617 618 if (str_cmp(ndir, "/") != 0) { 619 /* Need to add a synthetic up-dir entry */ 620 panel_entry_attr_init(&attr); 621 attr.name = ".."; 622 attr.isdir = true; 623 624 rc = panel_entry_append(panel, &attr); 625 if (rc != EOK) 626 goto error; 627 } 628 629 dirent = readdir(dir); 630 while (dirent != NULL) { 631 rc = vfs_stat_path(dirent->d_name, &finfo); 632 if (rc != EOK) { 633 /* Possibly a stale entry */ 634 dirent = readdir(dir); 635 continue; 636 } 637 638 panel_entry_attr_init(&attr); 639 attr.name = dirent->d_name; 640 attr.size = finfo.size; 641 attr.isdir = finfo.is_directory; 642 attr.svc = finfo.service; 643 644 rc = panel_entry_append(panel, &attr); 645 if (rc != EOK) 646 goto error; 647 648 dirent = readdir(dir); 649 } 650 651 closedir(dir); 652 653 rc = panel_sort(panel); 654 if (rc != EOK) 655 goto error; 656 657 panel->cursor = panel_first(panel); 658 panel->cursor_idx = 0; 659 panel->page = panel_first(panel); 660 panel->page_idx = 0; 661 662 /* Moving up? */ 663 if (str_cmp(dirname, "..") == 0) { 664 /* Get the last component of old path */ 665 olddn = str_rchr(panel->dir, '/'); 666 if (olddn != NULL && *olddn != '\0') { 667 /* Find corresponding entry */ 668 ++olddn; 669 next = panel_next(panel->cursor); 670 while (next != NULL && str_cmp(next->name, olddn) <= 0 && 671 next->isdir) { 672 panel->cursor = next; 673 ++panel->cursor_idx; 674 next = panel_next(panel->cursor); 675 } 676 677 /* Move page so that cursor is in the center */ 678 panel->page = panel->cursor; 679 panel->page_idx = panel->cursor_idx; 680 681 pg_size = panel_page_size(panel); 682 683 for (i = 0; i < pg_size / 2; i++) { 684 prev = panel_prev(panel->page); 685 if (prev == NULL) 686 break; 687 688 panel->page = prev; 689 --panel->page_idx; 690 } 691 692 /* Make sure page is not beyond the end if possible */ 693 if (panel->entries_cnt > pg_size) 694 max_idx = panel->entries_cnt - pg_size; 695 else 696 max_idx = 0; 697 698 while (panel->page_idx > 0 && panel->page_idx > max_idx) { 699 prev = panel_prev(panel->page); 700 if (prev == NULL) 701 break; 702 703 panel->page = prev; 704 --panel->page_idx; 705 } 706 } 707 } 708 709 free(panel->dir); 710 panel->dir = ndir; 711 712 return EOK; 713 error: 714 (void) vfs_cwd_set(panel->dir); 715 if (ndir != NULL) 716 free(ndir); 717 if (dir != NULL) 718 closedir(dir); 719 return rc; 720 } 721 722 /** Sort panel entries. 723 * 724 * @param panel Panel 725 * @return EOK on success, ENOMEM if out of memory 726 */ 727 errno_t panel_sort(panel_t *panel) 728 { 729 panel_entry_t **emap; 730 panel_entry_t *entry; 731 size_t i; 732 733 /* Create an array to hold pointer to each entry */ 734 emap = calloc(panel->entries_cnt, sizeof(panel_entry_t *)); 735 if (emap == NULL) 736 return ENOMEM; 737 738 /* Write entry pointers to array */ 739 entry = panel_first(panel); 740 i = 0; 741 while (entry != NULL) { 742 assert(i < panel->entries_cnt); 743 emap[i++] = entry; 744 entry = panel_next(entry); 745 } 746 747 /* Sort the array of pointers */ 748 qsort(emap, panel->entries_cnt, sizeof(panel_entry_t *), 749 panel_entry_ptr_cmp); 750 751 /* Unlink entries from entry list */ 752 entry = panel_first(panel); 753 while (entry != NULL) { 754 list_remove(&entry->lentries); 755 entry = panel_first(panel); 756 } 757 758 /* Add entries back to entry list sorted */ 759 for (i = 0; i < panel->entries_cnt; i++) 760 list_append(&emap[i]->lentries, &panel->entries); 761 762 free(emap); 763 return EOK; 764 } 765 766 /** Compare two panel entries indirectly referenced by pointers. 767 * 768 * @param pa Pointer to pointer to first entry 769 * @param pb Pointer to pointer to second entry 770 * @return <0, =0, >=0 if pa < b, pa == pb, pa > pb, resp. 771 */ 772 int panel_entry_ptr_cmp(const void *pa, const void *pb) 773 { 774 panel_entry_t *a = *(panel_entry_t **)pa; 775 panel_entry_t *b = *(panel_entry_t **)pb; 776 int dcmp; 777 778 /* Sort directories first */ 779 dcmp = b->isdir - a->isdir; 780 if (dcmp != 0) 781 return dcmp; 782 783 return str_cmp(a->name, b->name); 784 } 785 786 /** Return first panel entry. 787 * 788 * @panel Panel 789 * @return First panel entry or @c NULL if there are no entries 790 */ 791 panel_entry_t *panel_first(panel_t *panel) 792 { 793 link_t *link; 794 795 link = list_first(&panel->entries); 796 if (link == NULL) 797 return NULL; 798 799 return list_get_instance(link, panel_entry_t, lentries); 800 } 801 802 /** Return last panel entry. 803 * 804 * @panel Panel 805 * @return Last panel entry or @c NULL if there are no entries 806 */ 807 panel_entry_t *panel_last(panel_t *panel) 808 { 809 link_t *link; 810 811 link = list_last(&panel->entries); 812 if (link == NULL) 813 return NULL; 814 815 return list_get_instance(link, panel_entry_t, lentries); 816 } 817 818 /** Return next panel entry. 819 * 820 * @param cur Current entry 821 * @return Next entry or @c NULL if @a cur is the last entry 822 */ 823 panel_entry_t *panel_next(panel_entry_t *cur) 824 { 825 link_t *link; 826 827 link = list_next(&cur->lentries, &cur->panel->entries); 828 if (link == NULL) 829 return NULL; 830 831 return list_get_instance(link, panel_entry_t, lentries); 832 } 833 834 /** Return previous panel entry. 835 * 836 * @param cur Current entry 837 * @return Previous entry or @c NULL if @a cur is the first entry 838 */ 839 panel_entry_t *panel_prev(panel_entry_t *cur) 840 { 841 link_t *link; 842 843 link = list_prev(&cur->lentries, &cur->panel->entries); 844 if (link == NULL) 845 return NULL; 846 847 return list_get_instance(link, panel_entry_t, lentries); 848 } 849 850 /** Find the n-th entry of the current panel page. 851 * 852 * If the page is short and has less than n+1 entries, return the last entry. 853 * 854 * @param panel Panel 855 * @param n Which entry to get (starting from 0) 856 * @param ridx Place to store index (within listing) of the entry 857 * @return n-th entry of the page 858 */ 859 panel_entry_t *panel_page_nth_entry(panel_t *panel, size_t n, size_t *ridx) 860 { 861 panel_entry_t *entry; 862 panel_entry_t *next; 863 size_t i; 864 size_t idx; 865 866 assert(n < panel_page_size(panel)); 867 868 entry = panel->page; 869 idx = panel->page_idx; 870 for (i = 0; i < n; i++) { 871 next = panel_next(entry); 872 if (next == NULL) 873 break; 874 875 entry = next; 876 ++idx; 877 } 878 879 *ridx = idx; 880 return entry; 881 } 882 883 /** Move cursor to a new position, possibly scrolling. 884 * 885 * @param panel Panel 886 * @param entry New entry under cursor 887 * @param entry_idx Index of new entry under cursor 888 */ 889 void panel_cursor_move(panel_t *panel, panel_entry_t *entry, size_t entry_idx) 890 { 891 gfx_context_t *gc = ui_window_get_gc(panel->window); 892 panel_entry_t *old_cursor; 893 size_t old_idx; 894 size_t rows; 895 panel_entry_t *e; 896 size_t i; 897 898 rows = panel_page_size(panel); 899 900 old_cursor = panel->cursor; 901 old_idx = panel->cursor_idx; 902 903 panel->cursor = entry; 904 panel->cursor_idx = entry_idx; 905 906 if (entry_idx >= panel->page_idx && 907 entry_idx < panel->page_idx + rows) { 908 /* 909 * If cursor is still on the current page, we're not 910 * scrolling. Just unpaint old cursor and paint new 911 * cursor. 912 */ 913 panel_entry_paint(old_cursor, old_idx); 914 panel_entry_paint(panel->cursor, panel->cursor_idx); 915 916 (void) gfx_update(gc); 917 } else { 918 /* 919 * Need to scroll and update all rows. 920 */ 921 922 /* Scrolling up */ 923 if (entry_idx < panel->page_idx) { 924 panel->page = entry; 925 panel->page_idx = entry_idx; 926 } 927 928 /* Scrolling down */ 929 if (entry_idx >= panel->page_idx + rows) { 930 if (entry_idx >= rows) { 931 panel->page_idx = entry_idx - rows + 1; 932 /* Find first page entry (go back rows - 1) */ 933 e = entry; 934 for (i = 0; i < rows - 1; i++) { 935 e = panel_prev(e); 936 } 937 938 /* Should be valid */ 939 assert(e != NULL); 940 panel->page = e; 941 } else { 942 panel->page = panel_first(panel); 943 panel->page_idx = 0; 944 } 945 } 946 947 (void) panel_paint(panel); 948 } 949 } 950 951 /** Move cursor one entry up. 952 * 953 * @param panel Panel 954 */ 955 void panel_cursor_up(panel_t *panel) 956 { 957 panel_entry_t *prev; 958 size_t prev_idx; 959 960 prev = panel_prev(panel->cursor); 961 prev_idx = panel->cursor_idx - 1; 962 if (prev != NULL) 963 panel_cursor_move(panel, prev, prev_idx); 964 } 965 966 /** Move cursor one entry down. 967 * 968 * @param panel Panel 969 */ 970 void panel_cursor_down(panel_t *panel) 971 { 972 panel_entry_t *next; 973 size_t next_idx; 974 975 next = panel_next(panel->cursor); 976 next_idx = panel->cursor_idx + 1; 977 if (next != NULL) 978 panel_cursor_move(panel, next, next_idx); 979 } 980 981 /** Move cursor to top. 982 * 983 * @param panel Panel 984 */ 985 void panel_cursor_top(panel_t *panel) 986 { 987 panel_cursor_move(panel, panel_first(panel), 0); 988 } 989 990 /** Move cursor to bottom. 991 * 992 * @param panel Panel 993 */ 994 void panel_cursor_bottom(panel_t *panel) 995 { 996 panel_cursor_move(panel, panel_last(panel), panel->entries_cnt - 1); 997 } 998 999 /** Move one page up. 1000 * 1001 * @param panel Panel 1002 */ 1003 void panel_page_up(panel_t *panel) 1004 { 1005 gfx_context_t *gc = ui_window_get_gc(panel->window); 1006 panel_entry_t *old_page; 1007 panel_entry_t *old_cursor; 1008 size_t old_idx; 1009 size_t rows; 1010 panel_entry_t *entry; 1011 size_t i; 1012 1013 rows = panel_page_size(panel); 1014 1015 old_page = panel->page; 1016 old_cursor = panel->cursor; 1017 old_idx = panel->cursor_idx; 1018 1019 /* Move page by rows entries up (if possible) */ 1020 for (i = 0; i < rows; i++) { 1021 entry = panel_prev(panel->page); 1022 if (entry != NULL) { 1023 panel->page = entry; 1024 --panel->page_idx; 1025 } 1026 } 1027 1028 /* Move cursor by rows entries up (if possible) */ 1029 1030 for (i = 0; i < rows; i++) { 1031 entry = panel_prev(panel->cursor); 1032 if (entry != NULL) { 1033 panel->cursor = entry; 1034 --panel->cursor_idx; 1035 } 1036 } 1037 1038 if (panel->page != old_page) { 1039 /* We have scrolled. Need to repaint all entries */ 1040 (void) panel_paint(panel); 1041 } else if (panel->cursor != old_cursor) { 1042 /* No scrolling, but cursor has moved */ 1043 panel_entry_paint(old_cursor, old_idx); 1044 panel_entry_paint(panel->cursor, panel->cursor_idx); 1045 1046 (void) gfx_update(gc); 1047 } 1048 } 1049 1050 /** Move one page down. 1051 * 1052 * @param panel Panel 1053 */ 1054 void panel_page_down(panel_t *panel) 1055 { 1056 gfx_context_t *gc = ui_window_get_gc(panel->window); 1057 panel_entry_t *old_page; 1058 panel_entry_t *old_cursor; 1059 size_t old_idx; 1060 size_t max_idx; 1061 size_t rows; 1062 panel_entry_t *entry; 1063 size_t i; 1064 1065 rows = panel_page_size(panel); 1066 1067 old_page = panel->page; 1068 old_cursor = panel->cursor; 1069 old_idx = panel->cursor_idx; 1070 1071 if (panel->entries_cnt > rows) 1072 max_idx = panel->entries_cnt - rows; 1073 else 1074 max_idx = 0; 1075 1076 /* Move page by rows entries down (if possible) */ 1077 for (i = 0; i < rows; i++) { 1078 entry = panel_next(panel->page); 1079 /* Do not scroll that results in a short page */ 1080 if (entry != NULL && panel->page_idx < max_idx) { 1081 panel->page = entry; 1082 ++panel->page_idx; 1083 } 1084 } 1085 1086 /* Move cursor by rows entries down (if possible) */ 1087 1088 for (i = 0; i < rows; i++) { 1089 entry = panel_next(panel->cursor); 1090 if (entry != NULL) { 1091 panel->cursor = entry; 1092 ++panel->cursor_idx; 1093 } 1094 } 1095 1096 if (panel->page != old_page) { 1097 /* We have scrolled. Need to repaint all entries */ 1098 (void) panel_paint(panel); 1099 } else if (panel->cursor != old_cursor) { 1100 /* No scrolling, but cursor has moved */ 1101 panel_entry_paint(old_cursor, old_idx); 1102 panel_entry_paint(panel->cursor, panel->cursor_idx); 1103 1104 (void) gfx_update(gc); 1105 } 1106 } 1107 1108 /** Open panel entry. 1109 * 1110 * Perform Open action on a panel entry (e.g. switch to a subdirectory). 1111 * 1112 * @param panel Panel 1113 * @param entry Panel entry 357 return ui_file_list_read_dir(panel->flist, dirname); 358 } 359 360 /** Request panel activation. 361 * 362 * Call back to request panel activation. 363 * 364 * @param panel Panel 365 */ 366 void panel_activate_req(panel_t *panel) 367 { 368 if (panel->cb != NULL && panel->cb->activate_req != NULL) 369 panel->cb->activate_req(panel->cb_arg, panel); 370 } 371 372 /** Open panel file entry. 373 * 374 * Perform Open action on a file entry (i.e. try running it). 375 * 376 * @param panel Panel 377 * @param fname File name 1114 378 * 1115 379 * @return EOK on success or an error code 1116 380 */ 1117 errno_t panel_open(panel_t *panel, panel_entry_t *entry) 1118 { 1119 if (entry->isdir) 1120 return panel_open_dir(panel, entry); 1121 else if (entry->svc == 0) 1122 return panel_open_file(panel, entry); 1123 else 1124 return EOK; 1125 } 1126 1127 /** Open panel directory entry. 1128 * 1129 * Perform Open action on a directory entry (i.e. switch to the directory). 1130 * 1131 * @param panel Panel 1132 * @param entry Panel entry (which is a directory) 1133 * 1134 * @return EOK on success or an error code 1135 */ 1136 errno_t panel_open_dir(panel_t *panel, panel_entry_t *entry) 1137 { 1138 gfx_context_t *gc = ui_window_get_gc(panel->window); 1139 char *dirname; 1140 errno_t rc; 1141 1142 assert(entry->isdir); 1143 1144 /* 1145 * Need to copy out name before we free the entry below 1146 * via panel_clear_entries(). 1147 */ 1148 dirname = str_dup(entry->name); 1149 if (dirname == NULL) 1150 return ENOMEM; 1151 1152 panel_clear_entries(panel); 1153 1154 rc = panel_read_dir(panel, dirname); 1155 if (rc != EOK) { 1156 free(dirname); 1157 return rc; 1158 } 1159 1160 free(dirname); 1161 1162 rc = panel_paint(panel); 1163 if (rc != EOK) 1164 return rc; 1165 1166 return gfx_update(gc); 1167 } 1168 1169 /** Open panel file entry. 1170 * 1171 * Perform Open action on a file entry (i.e. try running it). 1172 * 1173 * @param panel Panel 1174 * @param entry Panel entry (which is a file) 1175 * 1176 * @return EOK on success or an error code 1177 */ 1178 errno_t panel_open_file(panel_t *panel, panel_entry_t *entry) 381 static errno_t panel_open_file(panel_t *panel, const char *fname) 1179 382 { 1180 383 task_id_t id; … … 1185 388 ui_t *ui; 1186 389 1187 /* It's not a directory */1188 assert(!entry->isdir);1189 /* It's not a service-special file */1190 assert(entry->svc == 0);1191 1192 390 ui = ui_window_get_ui(panel->window); 1193 391 … … 1197 395 return rc; 1198 396 1199 rc = task_spawnl(&id, &wait, entry->name, entry->name, NULL);397 rc = task_spawnl(&id, &wait, fname, fname, NULL); 1200 398 if (rc != EOK) 1201 399 goto error; … … 1218 416 } 1219 417 1220 /** Request panel activation. 1221 * 1222 * Call back to request panel activation. 1223 * 1224 * @param panel Panel 1225 */ 1226 void panel_activate_req(panel_t *panel) 1227 { 1228 if (panel->cb != NULL && panel->cb->activate_req != NULL) 1229 panel->cb->activate_req(panel->cb_arg, panel); 418 /** File in panel file list was selected. 419 * 420 * @param flist File list 421 * @param arg Argument (panel_t *) 422 * @param fname File name 423 */ 424 static void panel_flist_selected(ui_file_list_t *flist, void *arg, 425 const char *fname) 426 { 427 panel_t *panel = (panel_t *)arg; 428 429 (void) panel_open_file(panel, fname); 1230 430 } 1231 431 -
uspace/app/nav/panel.h
r453f9645 r54ddb59 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2022 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 49 49 extern void panel_destroy(panel_t *); 50 50 extern void panel_set_cb(panel_t *, panel_cb_t *, void *); 51 extern errno_t panel_entry_paint(panel_entry_t *, size_t);52 51 extern errno_t panel_paint(panel_t *); 53 52 extern ui_evclaim_t panel_kbd_event(panel_t *, kbd_event_t *); … … 55 54 extern ui_control_t *panel_ctl(panel_t *); 56 55 extern void panel_set_rect(panel_t *, gfx_rect_t *); 57 extern unsigned panel_page_size(panel_t *);58 56 extern bool panel_is_active(panel_t *); 59 57 extern errno_t panel_activate(panel_t *); 60 58 extern void panel_deactivate(panel_t *); 61 extern void panel_entry_attr_init(panel_entry_attr_t *);62 extern errno_t panel_entry_append(panel_t *, panel_entry_attr_t *);63 extern void panel_entry_delete(panel_entry_t *);64 extern void panel_clear_entries(panel_t *);65 59 extern errno_t panel_read_dir(panel_t *, const char *); 66 extern errno_t panel_sort(panel_t *);67 extern int panel_entry_ptr_cmp(const void *, const void *);68 extern panel_entry_t *panel_first(panel_t *);69 extern panel_entry_t *panel_last(panel_t *);70 extern panel_entry_t *panel_next(panel_entry_t *);71 extern panel_entry_t *panel_prev(panel_entry_t *);72 extern panel_entry_t *panel_page_nth_entry(panel_t *, size_t, size_t *);73 extern void panel_cursor_move(panel_t *, panel_entry_t *, size_t);74 extern void panel_cursor_up(panel_t *);75 extern void panel_cursor_down(panel_t *);76 extern void panel_cursor_top(panel_t *);77 extern void panel_cursor_bottom(panel_t *);78 extern void panel_page_up(panel_t *);79 extern void panel_page_down(panel_t *);80 extern errno_t panel_open(panel_t *, panel_entry_t *);81 extern errno_t panel_open_dir(panel_t *, panel_entry_t *);82 extern errno_t panel_open_file(panel_t *, panel_entry_t *);83 60 extern void panel_activate_req(panel_t *); 84 61 -
uspace/app/nav/test/panel.c
r453f9645 r54ddb59 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2022 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 81 81 } 82 82 83 /** Test panel_entry_paint() */84 PCUT_TEST(entry_paint)85 {86 ui_t *ui;87 ui_window_t *window;88 ui_wnd_params_t params;89 panel_t *panel;90 panel_entry_attr_t attr;91 errno_t rc;92 93 rc = ui_create_disp(NULL, &ui);94 PCUT_ASSERT_ERRNO_VAL(EOK, rc);95 96 ui_wnd_params_init(¶ms);97 params.caption = "Test";98 99 rc = ui_window_create(ui, ¶ms, &window);100 PCUT_ASSERT_ERRNO_VAL(EOK, rc);101 102 rc = panel_create(window, true, &panel);103 PCUT_ASSERT_ERRNO_VAL(EOK, rc);104 105 panel_entry_attr_init(&attr);106 attr.name = "a";107 attr.size = 1;108 109 rc = panel_entry_append(panel, &attr);110 PCUT_ASSERT_ERRNO_VAL(EOK, rc);111 112 rc = panel_entry_paint(panel_first(panel), 0);113 PCUT_ASSERT_ERRNO_VAL(EOK, rc);114 115 panel_destroy(panel);116 ui_window_destroy(window);117 ui_destroy(ui);118 }119 120 83 /** Test panel_paint() */ 121 84 PCUT_TEST(paint) … … 205 168 PCUT_TEST(pos_event) 206 169 { 207 ui_t *ui;208 ui_window_t *window;209 ui_wnd_params_t params;210 panel_t *panel;211 ui_evclaim_t claimed;212 pos_event_t event;213 gfx_rect_t rect;214 panel_entry_attr_t attr;215 errno_t rc;216 217 rc = ui_create_disp(NULL, &ui);218 PCUT_ASSERT_ERRNO_VAL(EOK, rc);219 220 ui_wnd_params_init(¶ms);221 params.caption = "Test";222 223 rc = ui_window_create(ui, ¶ms, &window);224 PCUT_ASSERT_ERRNO_VAL(EOK, rc);225 226 rc = panel_create(window, true, &panel);227 PCUT_ASSERT_ERRNO_VAL(EOK, rc);228 229 rect.p0.x = 0;230 rect.p0.y = 0;231 rect.p1.x = 10;232 rect.p1.y = 10;233 panel_set_rect(panel, &rect);234 235 panel_entry_attr_init(&attr);236 attr.name = "a";237 attr.size = 1;238 rc = panel_entry_append(panel, &attr);239 PCUT_ASSERT_ERRNO_VAL(EOK, rc);240 241 attr.name = "b";242 attr.size = 2;243 rc = panel_entry_append(panel, &attr);244 PCUT_ASSERT_ERRNO_VAL(EOK, rc);245 246 attr.name = "c";247 attr.size = 3;248 rc = panel_entry_append(panel, &attr);249 PCUT_ASSERT_ERRNO_VAL(EOK, rc);250 251 panel->cursor = panel_first(panel);252 panel->cursor_idx = 0;253 panel->page = panel_first(panel);254 panel->page_idx = 0;255 256 event.pos_id = 0;257 event.type = POS_PRESS;258 event.btn_num = 1;259 260 /* Clicking on the middle entry should select it */261 event.hpos = 1;262 event.vpos = 2;263 264 claimed = panel_pos_event(panel, &event);265 PCUT_ASSERT_EQUALS(ui_claimed, claimed);266 267 PCUT_ASSERT_NOT_NULL(panel->cursor);268 PCUT_ASSERT_STR_EQUALS("b", panel->cursor->name);269 PCUT_ASSERT_INT_EQUALS(2, panel->cursor->size);270 271 /* Clicking below the last entry should select it */272 event.hpos = 1;273 event.vpos = 4;274 claimed = panel_pos_event(panel, &event);275 PCUT_ASSERT_EQUALS(ui_claimed, claimed);276 277 PCUT_ASSERT_NOT_NULL(panel->cursor);278 PCUT_ASSERT_STR_EQUALS("c", panel->cursor->name);279 PCUT_ASSERT_INT_EQUALS(3, panel->cursor->size);280 281 /* Clicking on the top edge should do a page-up */282 event.hpos = 1;283 event.vpos = 0;284 claimed = panel_pos_event(panel, &event);285 PCUT_ASSERT_EQUALS(ui_claimed, claimed);286 287 PCUT_ASSERT_NOT_NULL(panel->cursor);288 PCUT_ASSERT_STR_EQUALS("a", panel->cursor->name);289 PCUT_ASSERT_INT_EQUALS(1, panel->cursor->size);290 291 panel_destroy(panel);292 ui_window_destroy(window);293 ui_destroy(ui);294 170 } 295 171 … … 318 194 } 319 195 320 /** panel_page_size() returns correct size */321 PCUT_TEST(page_size)322 {323 panel_t *panel;324 gfx_rect_t rect;325 errno_t rc;326 327 rc = panel_create(NULL, true, &panel);328 PCUT_ASSERT_ERRNO_VAL(EOK, rc);329 330 rect.p0.x = 10;331 rect.p0.y = 20;332 rect.p1.x = 30;333 rect.p1.y = 40;334 335 panel_set_rect(panel, &rect);336 337 /* NOTE If page size changes, we have problems elsewhere in the tests */338 PCUT_ASSERT_INT_EQUALS(18, panel_page_size(panel));339 340 panel_destroy(panel);341 }342 343 196 /** panel_is_active() returns panel activity state */ 344 197 PCUT_TEST(is_active) … … 419 272 } 420 273 421 /** panel_entry_append() appends new entry */422 PCUT_TEST(entry_append)423 {424 panel_t *panel;425 panel_entry_attr_t attr;426 errno_t rc;427 428 rc = panel_create(NULL, true, &panel);429 PCUT_ASSERT_ERRNO_VAL(EOK, rc);430 431 panel_entry_attr_init(&attr);432 433 attr.name = "a";434 attr.size = 1;435 rc = panel_entry_append(panel, &attr);436 PCUT_ASSERT_ERRNO_VAL(EOK, rc);437 438 PCUT_ASSERT_INT_EQUALS(1, list_count(&panel->entries));439 440 attr.name = "b";441 attr.size = 2;442 rc = panel_entry_append(panel, &attr);443 PCUT_ASSERT_ERRNO_VAL(EOK, rc);444 445 PCUT_ASSERT_INT_EQUALS(2, list_count(&panel->entries));446 447 panel_destroy(panel);448 }449 450 /** panel_entry_delete() deletes entry */451 PCUT_TEST(entry_delete)452 {453 panel_t *panel;454 panel_entry_t *entry;455 panel_entry_attr_t attr;456 errno_t rc;457 458 rc = panel_create(NULL, true, &panel);459 PCUT_ASSERT_ERRNO_VAL(EOK, rc);460 461 attr.name = "a";462 attr.size = 1;463 rc = panel_entry_append(panel, &attr);464 PCUT_ASSERT_ERRNO_VAL(EOK, rc);465 466 attr.name = "b";467 attr.size = 2;468 rc = panel_entry_append(panel, &attr);469 PCUT_ASSERT_ERRNO_VAL(EOK, rc);470 471 PCUT_ASSERT_INT_EQUALS(2, list_count(&panel->entries));472 473 entry = panel_first(panel);474 panel_entry_delete(entry);475 476 PCUT_ASSERT_INT_EQUALS(1, list_count(&panel->entries));477 478 entry = panel_first(panel);479 panel_entry_delete(entry);480 481 PCUT_ASSERT_INT_EQUALS(0, list_count(&panel->entries));482 483 panel_destroy(panel);484 }485 486 /** panel_clear_entries() removes all entries from panel */487 PCUT_TEST(clear_entries)488 {489 panel_t *panel;490 panel_entry_attr_t attr;491 errno_t rc;492 493 rc = panel_create(NULL, true, &panel);494 PCUT_ASSERT_ERRNO_VAL(EOK, rc);495 496 panel_entry_attr_init(&attr);497 attr.name = "a";498 attr.size = 1;499 rc = panel_entry_append(panel, &attr);500 PCUT_ASSERT_ERRNO_VAL(EOK, rc);501 502 attr.name = "a";503 attr.size = 2;504 rc = panel_entry_append(panel, &attr);505 PCUT_ASSERT_ERRNO_VAL(EOK, rc);506 507 PCUT_ASSERT_INT_EQUALS(2, list_count(&panel->entries));508 509 panel_clear_entries(panel);510 PCUT_ASSERT_INT_EQUALS(0, list_count(&panel->entries));511 512 panel_destroy(panel);513 }514 515 /** panel_read_dir() reads the contents of a directory */516 PCUT_TEST(read_dir)517 {518 panel_t *panel;519 panel_entry_t *entry;520 char buf[L_tmpnam];521 char *fname;522 char *p;523 errno_t rc;524 FILE *f;525 int rv;526 527 /* Create name for temporary directory */528 p = tmpnam(buf);529 PCUT_ASSERT_NOT_NULL(p);530 531 /* Create temporary directory */532 rc = vfs_link_path(p, KIND_DIRECTORY, NULL);533 PCUT_ASSERT_ERRNO_VAL(EOK, rc);534 535 rv = asprintf(&fname, "%s/%s", p, "a");536 PCUT_ASSERT_TRUE(rv >= 0);537 538 f = fopen(fname, "wb");539 PCUT_ASSERT_NOT_NULL(f);540 541 rv = fprintf(f, "X");542 PCUT_ASSERT_TRUE(rv >= 0);543 544 rv = fclose(f);545 PCUT_ASSERT_INT_EQUALS(0, rv);546 547 rc = panel_create(NULL, true, &panel);548 PCUT_ASSERT_ERRNO_VAL(EOK, rc);549 550 rc = panel_read_dir(panel, p);551 PCUT_ASSERT_ERRNO_VAL(EOK, rc);552 553 PCUT_ASSERT_INT_EQUALS(2, list_count(&panel->entries));554 555 entry = panel_first(panel);556 PCUT_ASSERT_NOT_NULL(entry);557 PCUT_ASSERT_STR_EQUALS("..", entry->name);558 559 entry = panel_next(entry);560 PCUT_ASSERT_NOT_NULL(entry);561 PCUT_ASSERT_STR_EQUALS("a", entry->name);562 PCUT_ASSERT_INT_EQUALS(1, entry->size);563 564 panel_destroy(panel);565 566 rv = remove(fname);567 PCUT_ASSERT_INT_EQUALS(0, rv);568 569 rv = remove(p);570 PCUT_ASSERT_INT_EQUALS(0, rv);571 572 free(fname);573 }574 575 /** When moving to parent directory from a subdir, we seek to the576 * coresponding entry577 */578 PCUT_TEST(read_dir_up)579 {580 panel_t *panel;581 char buf[L_tmpnam];582 char *subdir_a;583 char *subdir_b;584 char *subdir_c;585 char *p;586 errno_t rc;587 int rv;588 589 /* Create name for temporary directory */590 p = tmpnam(buf);591 PCUT_ASSERT_NOT_NULL(p);592 593 /* Create temporary directory */594 rc = vfs_link_path(p, KIND_DIRECTORY, NULL);595 PCUT_ASSERT_ERRNO_VAL(EOK, rc);596 597 /* Create some subdirectories */598 599 rv = asprintf(&subdir_a, "%s/%s", p, "a");600 PCUT_ASSERT_TRUE(rv >= 0);601 rc = vfs_link_path(subdir_a, KIND_DIRECTORY, NULL);602 PCUT_ASSERT_ERRNO_VAL(EOK, rc);603 604 rv = asprintf(&subdir_b, "%s/%s", p, "b");605 PCUT_ASSERT_TRUE(rv >= 0);606 rc = vfs_link_path(subdir_b, KIND_DIRECTORY, NULL);607 PCUT_ASSERT_ERRNO_VAL(EOK, rc);608 609 rv = asprintf(&subdir_c, "%s/%s", p, "c");610 PCUT_ASSERT_TRUE(rv >= 0);611 rc = vfs_link_path(subdir_c, KIND_DIRECTORY, NULL);612 PCUT_ASSERT_ERRNO_VAL(EOK, rc);613 614 rc = panel_create(NULL, true, &panel);615 PCUT_ASSERT_ERRNO_VAL(EOK, rc);616 617 /* Start in subdirectory "b" */618 rc = panel_read_dir(panel, subdir_b);619 PCUT_ASSERT_ERRNO_VAL(EOK, rc);620 621 /* Now go up (into p) */622 623 rc = panel_read_dir(panel, "..");624 PCUT_ASSERT_ERRNO_VAL(EOK, rc);625 626 PCUT_ASSERT_NOT_NULL(panel->cursor);627 PCUT_ASSERT_STR_EQUALS("b", panel->cursor->name);628 629 panel_destroy(panel);630 631 rv = remove(subdir_a);632 PCUT_ASSERT_INT_EQUALS(0, rv);633 634 rv = remove(subdir_b);635 PCUT_ASSERT_INT_EQUALS(0, rv);636 637 rv = remove(subdir_c);638 PCUT_ASSERT_INT_EQUALS(0, rv);639 640 rv = remove(p);641 PCUT_ASSERT_INT_EQUALS(0, rv);642 643 free(subdir_a);644 free(subdir_b);645 free(subdir_c);646 }647 648 /** panel_sort() sorts panel entries */649 PCUT_TEST(sort)650 {651 panel_t *panel;652 panel_entry_t *entry;653 panel_entry_attr_t attr;654 errno_t rc;655 656 rc = panel_create(NULL, true, &panel);657 PCUT_ASSERT_ERRNO_VAL(EOK, rc);658 659 panel_entry_attr_init(&attr);660 661 attr.name = "b";662 attr.size = 1;663 rc = panel_entry_append(panel, &attr);664 PCUT_ASSERT_ERRNO_VAL(EOK, rc);665 666 attr.name = "c";667 attr.size = 3;668 rc = panel_entry_append(panel, &attr);669 PCUT_ASSERT_ERRNO_VAL(EOK, rc);670 671 attr.name = "a";672 attr.size = 2;673 rc = panel_entry_append(panel, &attr);674 PCUT_ASSERT_ERRNO_VAL(EOK, rc);675 676 rc = panel_sort(panel);677 PCUT_ASSERT_ERRNO_VAL(EOK, rc);678 679 entry = panel_first(panel);680 PCUT_ASSERT_STR_EQUALS("a", entry->name);681 PCUT_ASSERT_INT_EQUALS(2, entry->size);682 683 entry = panel_next(entry);684 PCUT_ASSERT_STR_EQUALS("b", entry->name);685 PCUT_ASSERT_INT_EQUALS(1, entry->size);686 687 entry = panel_next(entry);688 PCUT_ASSERT_STR_EQUALS("c", entry->name);689 PCUT_ASSERT_INT_EQUALS(3, entry->size);690 691 panel_destroy(panel);692 }693 694 /** panel_entry_ptr_cmp compares two indirectly referenced entries */695 PCUT_TEST(entry_ptr_cmp)696 {697 panel_t *panel;698 panel_entry_t *a, *b;699 panel_entry_attr_t attr;700 int rel;701 errno_t rc;702 703 rc = panel_create(NULL, true, &panel);704 PCUT_ASSERT_ERRNO_VAL(EOK, rc);705 706 panel_entry_attr_init(&attr);707 708 attr.name = "a";709 attr.size = 2;710 rc = panel_entry_append(panel, &attr);711 PCUT_ASSERT_ERRNO_VAL(EOK, rc);712 713 attr.name = "b";714 attr.size = 1;715 rc = panel_entry_append(panel, &attr);716 PCUT_ASSERT_ERRNO_VAL(EOK, rc);717 718 a = panel_first(panel);719 PCUT_ASSERT_NOT_NULL(a);720 b = panel_next(a);721 PCUT_ASSERT_NOT_NULL(b);722 723 /* a < b */724 rel = panel_entry_ptr_cmp(&a, &b);725 PCUT_ASSERT_TRUE(rel < 0);726 727 /* b > a */728 rel = panel_entry_ptr_cmp(&b, &a);729 PCUT_ASSERT_TRUE(rel > 0);730 731 /* a == a */732 rel = panel_entry_ptr_cmp(&a, &a);733 PCUT_ASSERT_INT_EQUALS(0, rel);734 735 panel_destroy(panel);736 }737 738 /** panel_first() returns valid entry or @c NULL as appropriate */739 PCUT_TEST(first)740 {741 panel_t *panel;742 panel_entry_t *entry;743 panel_entry_attr_t attr;744 errno_t rc;745 746 rc = panel_create(NULL, true, &panel);747 PCUT_ASSERT_ERRNO_VAL(EOK, rc);748 749 panel_entry_attr_init(&attr);750 751 entry = panel_first(panel);752 PCUT_ASSERT_NULL(entry);753 754 /* Add one entry */755 attr.name = "a";756 attr.size = 1;757 rc = panel_entry_append(panel, &attr);758 PCUT_ASSERT_ERRNO_VAL(EOK, rc);759 760 /* Now try getting it */761 entry = panel_first(panel);762 PCUT_ASSERT_NOT_NULL(entry);763 PCUT_ASSERT_STR_EQUALS("a", entry->name);764 PCUT_ASSERT_INT_EQUALS(1, entry->size);765 766 /* Add another entry */767 attr.name = "b";768 attr.size = 2;769 rc = panel_entry_append(panel, &attr);770 PCUT_ASSERT_ERRNO_VAL(EOK, rc);771 772 /* We should still get the first entry */773 entry = panel_first(panel);774 PCUT_ASSERT_NOT_NULL(entry);775 PCUT_ASSERT_STR_EQUALS("a", entry->name);776 PCUT_ASSERT_INT_EQUALS(1, entry->size);777 778 panel_destroy(panel);779 }780 781 /** panel_last() returns valid entry or @c NULL as appropriate */782 PCUT_TEST(last)783 {784 panel_t *panel;785 panel_entry_t *entry;786 panel_entry_attr_t attr;787 errno_t rc;788 789 rc = panel_create(NULL, true, &panel);790 PCUT_ASSERT_ERRNO_VAL(EOK, rc);791 792 panel_entry_attr_init(&attr);793 794 entry = panel_last(panel);795 PCUT_ASSERT_NULL(entry);796 797 /* Add one entry */798 attr.name = "a";799 attr.size = 1;800 rc = panel_entry_append(panel, &attr);801 PCUT_ASSERT_ERRNO_VAL(EOK, rc);802 803 /* Now try getting it */804 entry = panel_last(panel);805 PCUT_ASSERT_NOT_NULL(entry);806 PCUT_ASSERT_STR_EQUALS("a", entry->name);807 PCUT_ASSERT_INT_EQUALS(1, entry->size);808 809 /* Add another entry */810 attr.name = "b";811 attr.size = 2;812 rc = panel_entry_append(panel, &attr);813 PCUT_ASSERT_ERRNO_VAL(EOK, rc);814 815 /* We should get new entry now */816 entry = panel_last(panel);817 PCUT_ASSERT_NOT_NULL(entry);818 attr.name = "b";819 attr.size = 2;820 PCUT_ASSERT_STR_EQUALS("b", entry->name);821 PCUT_ASSERT_INT_EQUALS(2, entry->size);822 823 panel_destroy(panel);824 }825 826 /** panel_next() returns the next entry or @c NULL as appropriate */827 PCUT_TEST(next)828 {829 panel_t *panel;830 panel_entry_t *entry;831 panel_entry_attr_t attr;832 errno_t rc;833 834 rc = panel_create(NULL, true, &panel);835 PCUT_ASSERT_ERRNO_VAL(EOK, rc);836 837 panel_entry_attr_init(&attr);838 839 /* Add one entry */840 attr.name = "a";841 attr.size = 1;842 rc = panel_entry_append(panel, &attr);843 PCUT_ASSERT_ERRNO_VAL(EOK, rc);844 845 /* Now try getting its successor */846 entry = panel_first(panel);847 PCUT_ASSERT_NOT_NULL(entry);848 849 entry = panel_next(entry);850 PCUT_ASSERT_NULL(entry);851 852 /* Add another entry */853 attr.name = "b";854 attr.size = 2;855 rc = panel_entry_append(panel, &attr);856 PCUT_ASSERT_ERRNO_VAL(EOK, rc);857 858 /* Try getting the successor of first entry again */859 entry = panel_first(panel);860 PCUT_ASSERT_NOT_NULL(entry);861 862 entry = panel_next(entry);863 PCUT_ASSERT_NOT_NULL(entry);864 PCUT_ASSERT_STR_EQUALS("b", entry->name);865 PCUT_ASSERT_INT_EQUALS(2, entry->size);866 867 panel_destroy(panel);868 }869 870 /** panel_prev() returns the previous entry or @c NULL as appropriate */871 PCUT_TEST(prev)872 {873 panel_t *panel;874 panel_entry_t *entry;875 panel_entry_attr_t attr;876 errno_t rc;877 878 rc = panel_create(NULL, true, &panel);879 PCUT_ASSERT_ERRNO_VAL(EOK, rc);880 881 panel_entry_attr_init(&attr);882 883 /* Add one entry */884 attr.name = "a";885 attr.size = 1;886 rc = panel_entry_append(panel, &attr);887 PCUT_ASSERT_ERRNO_VAL(EOK, rc);888 889 /* Now try getting its predecessor */890 entry = panel_last(panel);891 PCUT_ASSERT_NOT_NULL(entry);892 893 entry = panel_prev(entry);894 PCUT_ASSERT_NULL(entry);895 896 /* Add another entry */897 attr.name = "b";898 attr.size = 2;899 rc = panel_entry_append(panel, &attr);900 PCUT_ASSERT_ERRNO_VAL(EOK, rc);901 902 /* Try getting the predecessor of the new entry */903 entry = panel_last(panel);904 PCUT_ASSERT_NOT_NULL(entry);905 906 entry = panel_prev(entry);907 PCUT_ASSERT_NOT_NULL(entry);908 PCUT_ASSERT_STR_EQUALS("a", entry->name);909 PCUT_ASSERT_INT_EQUALS(1, entry->size);910 911 panel_destroy(panel);912 }913 914 /** panel_page_nth_entry() .. */915 PCUT_TEST(page_nth_entry)916 {917 panel_t *panel;918 panel_entry_t *entry;919 panel_entry_attr_t attr;920 size_t idx;921 errno_t rc;922 923 rc = panel_create(NULL, true, &panel);924 PCUT_ASSERT_ERRNO_VAL(EOK, rc);925 926 panel_entry_attr_init(&attr);927 928 /* Add some entries */929 attr.name = "a";930 attr.size = 1;931 rc = panel_entry_append(panel, &attr);932 PCUT_ASSERT_ERRNO_VAL(EOK, rc);933 934 attr.name = "b";935 attr.size = 2;936 rc = panel_entry_append(panel, &attr);937 PCUT_ASSERT_ERRNO_VAL(EOK, rc);938 939 attr.name = "c";940 attr.size = 3;941 rc = panel_entry_append(panel, &attr);942 PCUT_ASSERT_ERRNO_VAL(EOK, rc);943 944 panel->page = panel_next(panel_first(panel));945 panel->page_idx = 1;946 947 entry = panel_page_nth_entry(panel, 0, &idx);948 PCUT_ASSERT_STR_EQUALS("b", entry->name);949 PCUT_ASSERT_INT_EQUALS(1, idx);950 951 entry = panel_page_nth_entry(panel, 1, &idx);952 PCUT_ASSERT_STR_EQUALS("c", entry->name);953 PCUT_ASSERT_INT_EQUALS(2, idx);954 955 entry = panel_page_nth_entry(panel, 2, &idx);956 PCUT_ASSERT_STR_EQUALS("c", entry->name);957 PCUT_ASSERT_INT_EQUALS(2, idx);958 959 entry = panel_page_nth_entry(panel, 3, &idx);960 PCUT_ASSERT_STR_EQUALS("c", entry->name);961 PCUT_ASSERT_INT_EQUALS(2, idx);962 963 panel_destroy(panel);964 }965 966 /** panel_cursor_move() ... */967 PCUT_TEST(cursor_move)968 {969 }970 971 /** panel_cursor_up() moves cursor one entry up */972 PCUT_TEST(cursor_up)973 {974 ui_t *ui;975 ui_window_t *window;976 ui_wnd_params_t params;977 panel_t *panel;978 panel_entry_attr_t attr;979 gfx_rect_t rect;980 errno_t rc;981 982 rc = ui_create_disp(NULL, &ui);983 PCUT_ASSERT_ERRNO_VAL(EOK, rc);984 985 ui_wnd_params_init(¶ms);986 params.caption = "Test";987 988 rc = ui_window_create(ui, ¶ms, &window);989 PCUT_ASSERT_ERRNO_VAL(EOK, rc);990 991 rc = panel_create(window, true, &panel);992 PCUT_ASSERT_ERRNO_VAL(EOK, rc);993 994 rect.p0.x = 0;995 rect.p0.y = 0;996 rect.p1.x = 10;997 rect.p1.y = 4; // XXX Assuming this makes page size 2998 panel_set_rect(panel, &rect);999 1000 PCUT_ASSERT_INT_EQUALS(2, panel_page_size(panel));1001 1002 /* Add tree entries (more than page size, which is 2) */1003 1004 panel_entry_attr_init(&attr);1005 1006 attr.name = "a";1007 attr.size = 1;1008 rc = panel_entry_append(panel, &attr);1009 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1010 1011 attr.name = "b";1012 attr.size = 2;1013 rc = panel_entry_append(panel, &attr);1014 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1015 1016 attr.name = "c";1017 attr.size = 3;1018 rc = panel_entry_append(panel, &attr);1019 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1020 1021 /* Cursor to the last entry and page start to the next-to-last entry */1022 panel->cursor = panel_last(panel);1023 panel->cursor_idx = 2;1024 panel->page = panel_prev(panel->cursor);1025 panel->page_idx = 1;1026 1027 /* Move cursor one entry up */1028 panel_cursor_up(panel);1029 1030 /* Cursor and page start should now both be at the second entry */1031 PCUT_ASSERT_STR_EQUALS("b", panel->cursor->name);1032 PCUT_ASSERT_INT_EQUALS(2, panel->cursor->size);1033 PCUT_ASSERT_INT_EQUALS(1, panel->cursor_idx);1034 PCUT_ASSERT_EQUALS(panel->cursor, panel->page);1035 PCUT_ASSERT_INT_EQUALS(1, panel->page_idx);1036 1037 /* Move cursor one entry up. This should scroll up. */1038 panel_cursor_up(panel);1039 1040 /* Cursor and page start should now both be at the first entry */1041 PCUT_ASSERT_STR_EQUALS("a", panel->cursor->name);1042 PCUT_ASSERT_INT_EQUALS(1, panel->cursor->size);1043 PCUT_ASSERT_INT_EQUALS(0, panel->cursor_idx);1044 PCUT_ASSERT_EQUALS(panel->cursor, panel->page);1045 PCUT_ASSERT_INT_EQUALS(0, panel->page_idx);1046 1047 /* Moving further up should do nothing (we are at the top). */1048 panel_cursor_up(panel);1049 1050 /* Cursor and page start should still be at the first entry */1051 PCUT_ASSERT_STR_EQUALS("a", panel->cursor->name);1052 PCUT_ASSERT_INT_EQUALS(1, panel->cursor->size);1053 PCUT_ASSERT_INT_EQUALS(0, panel->cursor_idx);1054 PCUT_ASSERT_EQUALS(panel->cursor, panel->page);1055 PCUT_ASSERT_INT_EQUALS(0, panel->page_idx);1056 1057 panel_destroy(panel);1058 ui_window_destroy(window);1059 ui_destroy(ui);1060 }1061 1062 /** panel_cursor_down() moves cursor one entry down */1063 PCUT_TEST(cursor_down)1064 {1065 ui_t *ui;1066 ui_window_t *window;1067 ui_wnd_params_t params;1068 panel_t *panel;1069 panel_entry_attr_t attr;1070 gfx_rect_t rect;1071 errno_t rc;1072 1073 rc = ui_create_disp(NULL, &ui);1074 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1075 1076 ui_wnd_params_init(¶ms);1077 params.caption = "Test";1078 1079 rc = ui_window_create(ui, ¶ms, &window);1080 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1081 1082 rc = panel_create(window, true, &panel);1083 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1084 1085 rect.p0.x = 0;1086 rect.p0.y = 0;1087 rect.p1.x = 10;1088 rect.p1.y = 4; // XXX Assuming this makes page size 21089 panel_set_rect(panel, &rect);1090 1091 PCUT_ASSERT_INT_EQUALS(2, panel_page_size(panel));1092 1093 /* Add tree entries (more than page size, which is 2) */1094 1095 panel_entry_attr_init(&attr);1096 1097 attr.name = "a";1098 attr.size = 1;1099 rc = panel_entry_append(panel, &attr);1100 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1101 1102 attr.name = "b";1103 attr.size = 2;1104 rc = panel_entry_append(panel, &attr);1105 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1106 1107 attr.name = "c";1108 attr.size = 3;1109 rc = panel_entry_append(panel, &attr);1110 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1111 1112 /* Cursor and page start to the first entry */1113 panel->cursor = panel_first(panel);1114 panel->cursor_idx = 0;1115 panel->page = panel->cursor;1116 panel->page_idx = 0;1117 1118 /* Move cursor one entry down */1119 panel_cursor_down(panel);1120 1121 /* Cursor should now be at the second entry, page stays the same */1122 PCUT_ASSERT_STR_EQUALS("b", panel->cursor->name);1123 PCUT_ASSERT_INT_EQUALS(2, panel->cursor->size);1124 PCUT_ASSERT_INT_EQUALS(1, panel->cursor_idx);1125 PCUT_ASSERT_EQUALS(panel_first(panel), panel->page);1126 PCUT_ASSERT_INT_EQUALS(0, panel->page_idx);1127 1128 /* Move cursor one entry down. This should scroll down. */1129 panel_cursor_down(panel);1130 1131 /* Cursor should now be at the third and page at the second entry. */1132 PCUT_ASSERT_STR_EQUALS("c", panel->cursor->name);1133 PCUT_ASSERT_INT_EQUALS(3, panel->cursor->size);1134 PCUT_ASSERT_INT_EQUALS(2, panel->cursor_idx);1135 PCUT_ASSERT_STR_EQUALS("b", panel->page->name);1136 PCUT_ASSERT_INT_EQUALS(2, panel->page->size);1137 PCUT_ASSERT_INT_EQUALS(1, panel->page_idx);1138 1139 /* Moving further down should do nothing (we are at the bottom). */1140 panel_cursor_down(panel);1141 1142 /* Cursor should still be at the third and page at the second entry. */1143 PCUT_ASSERT_STR_EQUALS("c", panel->cursor->name);1144 PCUT_ASSERT_INT_EQUALS(3, panel->cursor->size);1145 PCUT_ASSERT_INT_EQUALS(2, panel->cursor_idx);1146 PCUT_ASSERT_STR_EQUALS("b", panel->page->name);1147 PCUT_ASSERT_INT_EQUALS(2, panel->page->size);1148 PCUT_ASSERT_INT_EQUALS(1, panel->page_idx);1149 1150 panel_destroy(panel);1151 ui_window_destroy(window);1152 ui_destroy(ui);1153 }1154 1155 /** panel_cursor_top() moves cursor to the first entry */1156 PCUT_TEST(cursor_top)1157 {1158 ui_t *ui;1159 ui_window_t *window;1160 ui_wnd_params_t params;1161 panel_t *panel;1162 panel_entry_attr_t attr;1163 gfx_rect_t rect;1164 errno_t rc;1165 1166 rc = ui_create_disp(NULL, &ui);1167 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1168 1169 ui_wnd_params_init(¶ms);1170 params.caption = "Test";1171 1172 rc = ui_window_create(ui, ¶ms, &window);1173 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1174 1175 rc = panel_create(window, true, &panel);1176 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1177 1178 rect.p0.x = 0;1179 rect.p0.y = 0;1180 rect.p1.x = 10;1181 rect.p1.y = 4; // XXX Assuming this makes page size 21182 panel_set_rect(panel, &rect);1183 1184 PCUT_ASSERT_INT_EQUALS(2, panel_page_size(panel));1185 1186 /* Add tree entries (more than page size, which is 2) */1187 1188 panel_entry_attr_init(&attr);1189 1190 attr.name = "a";1191 attr.size = 1;1192 rc = panel_entry_append(panel, &attr);1193 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1194 1195 attr.name = "b";1196 attr.size = 2;1197 rc = panel_entry_append(panel, &attr);1198 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1199 1200 attr.name = "c";1201 attr.size = 3;1202 rc = panel_entry_append(panel, &attr);1203 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1204 1205 /* Cursor to the last entry and page start to the next-to-last entry */1206 panel->cursor = panel_last(panel);1207 panel->cursor_idx = 2;1208 panel->page = panel_prev(panel->cursor);1209 panel->page_idx = 1;1210 1211 /* Move cursor to the top. This should scroll up. */1212 panel_cursor_top(panel);1213 1214 /* Cursor and page start should now both be at the first entry */1215 PCUT_ASSERT_STR_EQUALS("a", panel->cursor->name);1216 PCUT_ASSERT_INT_EQUALS(1, panel->cursor->size);1217 PCUT_ASSERT_INT_EQUALS(0, panel->cursor_idx);1218 PCUT_ASSERT_EQUALS(panel->cursor, panel->page);1219 PCUT_ASSERT_INT_EQUALS(0, panel->page_idx);1220 1221 panel_destroy(panel);1222 ui_window_destroy(window);1223 ui_destroy(ui);1224 }1225 1226 /** panel_cursor_bottom() moves cursor to the last entry */1227 PCUT_TEST(cursor_bottom)1228 {1229 ui_t *ui;1230 ui_window_t *window;1231 ui_wnd_params_t params;1232 panel_t *panel;1233 panel_entry_attr_t attr;1234 gfx_rect_t rect;1235 errno_t rc;1236 1237 rc = ui_create_disp(NULL, &ui);1238 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1239 1240 ui_wnd_params_init(¶ms);1241 params.caption = "Test";1242 1243 rc = ui_window_create(ui, ¶ms, &window);1244 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1245 1246 rc = panel_create(window, true, &panel);1247 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1248 1249 rect.p0.x = 0;1250 rect.p0.y = 0;1251 rect.p1.x = 10;1252 rect.p1.y = 4; // XXX Assuming this makes page size 21253 panel_set_rect(panel, &rect);1254 1255 PCUT_ASSERT_INT_EQUALS(2, panel_page_size(panel));1256 1257 /* Add tree entries (more than page size, which is 2) */1258 1259 panel_entry_attr_init(&attr);1260 1261 attr.name = "a";1262 attr.size = 1;1263 rc = panel_entry_append(panel, &attr);1264 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1265 1266 attr.name = "b";1267 attr.size = 2;1268 rc = panel_entry_append(panel, &attr);1269 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1270 1271 attr.name = "c";1272 attr.size = 3;1273 rc = panel_entry_append(panel, &attr);1274 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1275 1276 /* Cursor and page start to the first entry */1277 panel->cursor = panel_first(panel);1278 panel->cursor_idx = 0;1279 panel->page = panel->cursor;1280 panel->page_idx = 0;1281 1282 /* Move cursor to the bottom. This should scroll down. */1283 panel_cursor_bottom(panel);1284 1285 /* Cursor should now be at the third and page at the second entry. */1286 PCUT_ASSERT_STR_EQUALS("c", panel->cursor->name);1287 PCUT_ASSERT_INT_EQUALS(3, panel->cursor->size);1288 PCUT_ASSERT_INT_EQUALS(2, panel->cursor_idx);1289 PCUT_ASSERT_STR_EQUALS("b", panel->page->name);1290 PCUT_ASSERT_INT_EQUALS(2, panel->page->size);1291 PCUT_ASSERT_INT_EQUALS(1, panel->page_idx);1292 1293 panel_destroy(panel);1294 ui_window_destroy(window);1295 ui_destroy(ui);1296 }1297 1298 /** panel_page_up() moves one page up */1299 PCUT_TEST(page_up)1300 {1301 ui_t *ui;1302 ui_window_t *window;1303 ui_wnd_params_t params;1304 panel_t *panel;1305 panel_entry_attr_t attr;1306 gfx_rect_t rect;1307 errno_t rc;1308 1309 rc = ui_create_disp(NULL, &ui);1310 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1311 1312 ui_wnd_params_init(¶ms);1313 params.caption = "Test";1314 1315 rc = ui_window_create(ui, ¶ms, &window);1316 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1317 1318 rc = panel_create(window, true, &panel);1319 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1320 1321 rect.p0.x = 0;1322 rect.p0.y = 0;1323 rect.p1.x = 10;1324 rect.p1.y = 4; // XXX Assuming this makes page size 21325 panel_set_rect(panel, &rect);1326 1327 PCUT_ASSERT_INT_EQUALS(2, panel_page_size(panel));1328 1329 /* Add five entries (2 full pages, one partial) */1330 1331 panel_entry_attr_init(&attr);1332 1333 attr.name = "a";1334 attr.size = 1;1335 rc = panel_entry_append(panel, &attr);1336 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1337 1338 attr.name = "b";1339 attr.size = 2;1340 rc = panel_entry_append(panel, &attr);1341 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1342 1343 attr.name = "c";1344 attr.size = 3;1345 rc = panel_entry_append(panel, &attr);1346 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1347 1348 attr.name = "d";1349 attr.size = 4;1350 rc = panel_entry_append(panel, &attr);1351 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1352 1353 attr.name = "e";1354 attr.size = 5;1355 rc = panel_entry_append(panel, &attr);1356 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1357 1358 /* Cursor to the last entry and page start to the next-to-last entry */1359 panel->cursor = panel_last(panel);1360 panel->cursor_idx = 4;1361 panel->page = panel_prev(panel->cursor);1362 panel->page_idx = 3;1363 1364 /* Move one page up */1365 panel_page_up(panel);1366 1367 /* Page should now start at second entry and cursor at third */1368 PCUT_ASSERT_STR_EQUALS("c", panel->cursor->name);1369 PCUT_ASSERT_INT_EQUALS(3, panel->cursor->size);1370 PCUT_ASSERT_INT_EQUALS(2, panel->cursor_idx);1371 PCUT_ASSERT_STR_EQUALS("b", panel->page->name);1372 PCUT_ASSERT_INT_EQUALS(2, panel->page->size);1373 PCUT_ASSERT_INT_EQUALS(1, panel->page_idx);1374 1375 /* Move one page up again. */1376 panel_page_up(panel);1377 1378 /* Cursor and page start should now both be at the first entry */1379 PCUT_ASSERT_STR_EQUALS("a", panel->cursor->name);1380 PCUT_ASSERT_INT_EQUALS(1, panel->cursor->size);1381 PCUT_ASSERT_INT_EQUALS(0, panel->cursor_idx);1382 PCUT_ASSERT_EQUALS(panel->cursor, panel->page);1383 PCUT_ASSERT_INT_EQUALS(0, panel->page_idx);1384 1385 /* Moving further up should do nothing (we are at the top). */1386 panel_page_up(panel);1387 1388 /* Cursor and page start should still be at the first entry */1389 PCUT_ASSERT_STR_EQUALS("a", panel->cursor->name);1390 PCUT_ASSERT_INT_EQUALS(1, panel->cursor->size);1391 PCUT_ASSERT_INT_EQUALS(0, panel->cursor_idx);1392 PCUT_ASSERT_EQUALS(panel->cursor, panel->page);1393 PCUT_ASSERT_INT_EQUALS(0, panel->page_idx);1394 1395 panel_destroy(panel);1396 ui_window_destroy(window);1397 ui_destroy(ui);1398 }1399 1400 /** panel_page_up() moves one page down */1401 PCUT_TEST(page_down)1402 {1403 ui_t *ui;1404 ui_window_t *window;1405 ui_wnd_params_t params;1406 panel_t *panel;1407 panel_entry_attr_t attr;1408 gfx_rect_t rect;1409 errno_t rc;1410 1411 rc = ui_create_disp(NULL, &ui);1412 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1413 1414 ui_wnd_params_init(¶ms);1415 params.caption = "Test";1416 1417 rc = ui_window_create(ui, ¶ms, &window);1418 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1419 1420 rc = panel_create(window, true, &panel);1421 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1422 1423 rect.p0.x = 0;1424 rect.p0.y = 0;1425 rect.p1.x = 10;1426 rect.p1.y = 4; // XXX Assuming this makes page size 21427 panel_set_rect(panel, &rect);1428 1429 PCUT_ASSERT_INT_EQUALS(2, panel_page_size(panel));1430 1431 /* Add five entries (2 full pages, one partial) */1432 1433 panel_entry_attr_init(&attr);1434 1435 attr.name = "a";1436 attr.size = 1;1437 rc = panel_entry_append(panel, &attr);1438 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1439 1440 attr.name = "b";1441 attr.size = 2;1442 rc = panel_entry_append(panel, &attr);1443 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1444 1445 attr.name = "c";1446 attr.size = 3;1447 rc = panel_entry_append(panel, &attr);1448 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1449 1450 attr.name = "d";1451 attr.size = 4;1452 rc = panel_entry_append(panel, &attr);1453 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1454 1455 attr.name = "e";1456 attr.size = 5;1457 rc = panel_entry_append(panel, &attr);1458 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1459 1460 /* Cursor and page to the first entry */1461 panel->cursor = panel_first(panel);1462 panel->cursor_idx = 0;1463 panel->page = panel->cursor;1464 panel->page_idx = 0;1465 1466 /* Move one page down */1467 panel_page_down(panel);1468 1469 /* Page and cursor should point to the third entry */1470 PCUT_ASSERT_STR_EQUALS("c", panel->cursor->name);1471 PCUT_ASSERT_INT_EQUALS(3, panel->cursor->size);1472 PCUT_ASSERT_INT_EQUALS(2, panel->cursor_idx);1473 PCUT_ASSERT_STR_EQUALS("c", panel->page->name);1474 PCUT_ASSERT_INT_EQUALS(3, panel->page->size);1475 PCUT_ASSERT_INT_EQUALS(2, panel->page_idx);1476 1477 /* Move one page down again. */1478 panel_page_down(panel);1479 1480 /* Cursor should point to last and page to next-to-last entry */1481 PCUT_ASSERT_STR_EQUALS("e", panel->cursor->name);1482 PCUT_ASSERT_INT_EQUALS(5, panel->cursor->size);1483 PCUT_ASSERT_INT_EQUALS(4, panel->cursor_idx);1484 PCUT_ASSERT_STR_EQUALS("d", panel->page->name);1485 PCUT_ASSERT_INT_EQUALS(4, panel->page->size);1486 PCUT_ASSERT_INT_EQUALS(3, panel->page_idx);1487 1488 /* Moving further down should do nothing (we are at the bottom). */1489 panel_page_down(panel);1490 1491 /* Cursor should still point to last and page to next-to-last entry */1492 PCUT_ASSERT_STR_EQUALS("e", panel->cursor->name);1493 PCUT_ASSERT_INT_EQUALS(5, panel->cursor->size);1494 PCUT_ASSERT_INT_EQUALS(4, panel->cursor_idx);1495 PCUT_ASSERT_STR_EQUALS("d", panel->page->name);1496 PCUT_ASSERT_INT_EQUALS(4, panel->page->size);1497 PCUT_ASSERT_INT_EQUALS(3, panel->page_idx);1498 1499 panel_destroy(panel);1500 ui_window_destroy(window);1501 ui_destroy(ui);1502 }1503 1504 /** panel_open() opens a directory entry */1505 PCUT_TEST(open)1506 {1507 ui_t *ui;1508 ui_window_t *window;1509 ui_wnd_params_t params;1510 panel_t *panel;1511 panel_entry_t *entry;1512 char buf[L_tmpnam];1513 char *sdname;1514 char *p;1515 errno_t rc;1516 int rv;1517 1518 rc = ui_create_disp(NULL, &ui);1519 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1520 1521 ui_wnd_params_init(¶ms);1522 params.caption = "Test";1523 1524 rc = ui_window_create(ui, ¶ms, &window);1525 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1526 1527 /* Create name for temporary directory */1528 p = tmpnam(buf);1529 PCUT_ASSERT_NOT_NULL(p);1530 1531 /* Create temporary directory */1532 rc = vfs_link_path(p, KIND_DIRECTORY, NULL);1533 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1534 1535 rv = asprintf(&sdname, "%s/%s", p, "a");1536 PCUT_ASSERT_TRUE(rv >= 0);1537 1538 /* Create sub-directory */1539 rc = vfs_link_path(sdname, KIND_DIRECTORY, NULL);1540 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1541 1542 rc = panel_create(window, true, &panel);1543 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1544 1545 rc = panel_read_dir(panel, p);1546 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1547 PCUT_ASSERT_STR_EQUALS(p, panel->dir);1548 1549 PCUT_ASSERT_INT_EQUALS(2, list_count(&panel->entries));1550 1551 entry = panel_first(panel);1552 PCUT_ASSERT_NOT_NULL(entry);1553 PCUT_ASSERT_STR_EQUALS("..", entry->name);1554 1555 entry = panel_next(entry);1556 PCUT_ASSERT_NOT_NULL(entry);1557 PCUT_ASSERT_STR_EQUALS("a", entry->name);1558 PCUT_ASSERT_TRUE(entry->isdir);1559 1560 rc = panel_open(panel, entry);1561 PCUT_ASSERT_ERRNO_VAL(EOK, rc);1562 1563 PCUT_ASSERT_STR_EQUALS(sdname, panel->dir);1564 1565 panel_destroy(panel);1566 ui_window_destroy(window);1567 ui_destroy(ui);1568 1569 rv = remove(sdname);1570 PCUT_ASSERT_INT_EQUALS(0, rv);1571 1572 rv = remove(p);1573 PCUT_ASSERT_INT_EQUALS(0, rv);1574 1575 free(sdname);1576 }1577 1578 274 /** panel_activate_req() sends activation request */ 1579 275 PCUT_TEST(activate_req) -
uspace/app/nav/types/panel.h
r453f9645 r54ddb59 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2022 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 37 37 #define TYPES_PANEL_H 38 38 39 #include <adt/list.h>40 39 #include <gfx/color.h> 41 40 #include <gfx/coord.h> 42 #include < ipc/loc.h>41 #include <ui/filelist.h> 43 42 #include <ui/window.h> 44 43 #include <stdint.h> 45 46 /** Panel entry attributes */47 typedef struct {48 /** File name */49 const char *name;50 /** File size */51 uint64_t size;52 /** @c true iff entry is a directory */53 bool isdir;54 /** Service number for service special entries */55 service_id_t svc;56 } panel_entry_attr_t;57 58 /** Panel entry */59 typedef struct {60 /** Containing panel */61 struct panel *panel;62 /** Link to @c panel->entries */63 link_t lentries;64 /** File name */65 char *name;66 /** File size */67 uint64_t size;68 /** @c true iff entry is a directory */69 bool isdir;70 /** Service number for service special entries */71 service_id_t svc;72 } panel_entry_t;73 44 74 45 /** Navigator panel … … 95 66 gfx_color_t *color; 96 67 97 /** Panel cursor color */98 gfx_color_t *curs_color;99 100 68 /** Active border color */ 101 69 gfx_color_t *act_border_color; 102 103 /** Directory-type entry color */104 gfx_color_t *dir_color;105 106 /** Service-type entry color */107 gfx_color_t *svc_color;108 109 /** Panel entries (list of panel_entry_t) */110 list_t entries;111 112 /** Number of entries */113 size_t entries_cnt;114 115 /** First entry of current page */116 panel_entry_t *page;117 118 /** Index of first entry of current page */119 size_t page_idx;120 121 /** Cursor position */122 panel_entry_t *cursor;123 124 /** Index of entry under cursor */125 size_t cursor_idx;126 70 127 71 /** @c true iff the panel is active */ 128 72 bool active; 129 73 130 /** Directory*/131 char *dir;74 /** File list */ 75 ui_file_list_t *flist; 132 76 } panel_t; 133 77 -
uspace/lib/ui/include/ui/filelist.h
r453f9645 r54ddb59 54 54 extern errno_t ui_file_list_activate(ui_file_list_t *); 55 55 extern void ui_file_list_deactivate(ui_file_list_t *); 56 extern errno_t ui_file_list_open(ui_file_list_t *, ui_file_list_entry_t *); 57 extern ui_file_list_entry_t *ui_file_list_get_cursor(ui_file_list_t *); 56 58 57 59 #endif -
uspace/lib/ui/private/filelist.h
r453f9645 r54ddb59 164 164 extern void ui_file_list_scroll_page_down(ui_file_list_t *); 165 165 extern void ui_file_list_scroll_pos(ui_file_list_t *, size_t); 166 extern errno_t ui_file_list_open(ui_file_list_t *, ui_file_list_entry_t *);167 166 extern errno_t ui_file_list_open_dir(ui_file_list_t *, ui_file_list_entry_t *); 168 167 extern errno_t ui_file_list_open_file(ui_file_list_t *, ui_file_list_entry_t *); -
uspace/lib/ui/src/filelist.c
r453f9645 r54ddb59 1079 1079 } 1080 1080 1081 /** Get entry under cursor. 1082 * 1083 * @param flist File list 1084 * @return Current cursor 1085 */ 1086 ui_file_list_entry_t *ui_file_list_get_cursor(ui_file_list_t *flist) 1087 { 1088 return flist->cursor; 1089 } 1090 1081 1091 /** Move cursor to a new position, possibly scrolling. 1082 1092 *
Note:
See TracChangeset
for help on using the changeset viewer.