Changeset af2ea83 in mainline for uspace/app/nav/panel.c
- Timestamp:
- 2021-10-12T17:06:45Z (3 years ago)
- Children:
- 3e6c51f
- Parents:
- 166aba54
- git-author:
- Jiri Svoboda <jiri@…> (2021-10-12 17:06:35)
- git-committer:
- Jiri Svoboda <jiri@…> (2021-10-12 17:06:45)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/nav/panel.c
r166aba54 raf2ea83 49 49 static void panel_ctl_destroy(void *); 50 50 static errno_t panel_ctl_paint(void *); 51 static ui_evclaim_t panel_ctl_kbd_event(void *, kbd_event_t *); 51 52 static ui_evclaim_t panel_ctl_pos_event(void *, pos_event_t *); 52 53 … … 55 56 .destroy = panel_ctl_destroy, 56 57 .paint = panel_ctl_paint, 58 .kbd_event = panel_ctl_kbd_event, 57 59 .pos_event = panel_ctl_pos_event 58 60 }; … … 90 92 panel->window = window; 91 93 list_initialize(&panel->entries); 94 panel->entries_cnt = 0; 92 95 *rpanel = panel; 93 96 return EOK; … … 115 118 } 116 119 117 /** Paint panel. 118 * 119 * @param panel Panel 120 */ 121 errno_t panel_paint(panel_t *panel) 122 { 120 /** Paint panel entry. 121 * 122 * @param entry Panel entry 123 * @param entry_idx Entry index (within list of entries) 124 * @return EOK on success or an error code 125 */ 126 errno_t panel_entry_paint(panel_entry_t *entry, size_t entry_idx) 127 { 128 panel_t *panel = entry->panel; 123 129 gfx_context_t *gc = ui_window_get_gc(panel->window); 124 130 ui_resource_t *res = ui_window_get_res(panel->window); 125 131 gfx_font_t *font = ui_resource_get_font(res); 126 132 gfx_text_fmt_t fmt; 127 panel_entry_t *entry;128 133 gfx_coord2_t pos; 129 134 gfx_rect_t rect; 135 size_t rows; 136 errno_t rc; 137 138 gfx_text_fmt_init(&fmt); 139 140 rows = panel->rect.p1.y - panel->rect.p0.y - 2; 141 142 /* Do not display entry outside of current page */ 143 if (entry_idx < panel->page_idx || 144 entry_idx >= panel->page_idx + rows) 145 return EOK; 146 147 pos.x = panel->rect.p0.x + 1; 148 pos.y = panel->rect.p0.y + 1 + entry_idx - panel->page_idx; 149 150 if (entry == panel->cursor) 151 fmt.color = panel->curs_color; 152 else 153 fmt.color = panel->color; 154 155 /* Draw entry background */ 156 rect.p0 = pos; 157 rect.p1.x = panel->rect.p1.x - 1; 158 rect.p1.y = rect.p0.y + 1; 159 160 rc = gfx_set_color(gc, fmt.color); 161 if (rc != EOK) 162 return rc; 163 164 rc = gfx_fill_rect(gc, &rect); 165 if (rc != EOK) 166 return rc; 167 168 rc = gfx_puttext(font, &pos, &fmt, entry->name); 169 if (rc != EOK) 170 return rc; 171 172 return EOK; 173 } 174 175 /** Paint panel. 176 * 177 * @param panel Panel 178 */ 179 errno_t panel_paint(panel_t *panel) 180 { 181 gfx_context_t *gc = ui_window_get_gc(panel->window); 182 ui_resource_t *res = ui_window_get_res(panel->window); 183 gfx_text_fmt_t fmt; 184 panel_entry_t *entry; 185 int i, lines; 130 186 errno_t rc; 131 187 … … 145 201 return rc; 146 202 147 pos.x = panel->rect.p0.x + 1;148 pos.y = panel->rect.p0.y + 1;203 lines = panel->rect.p1.y - panel->rect.p0.y - 2; 204 i = 0; 149 205 150 206 entry = panel->page; 151 while (entry != NULL && pos.y < panel->rect.p1.y - 1) { 152 if (entry == panel->cursor) { 153 /* Draw cursor background */ 154 rect.p0 = pos; 155 rect.p1.x = panel->rect.p1.x - 1; 156 rect.p1.y = rect.p0.y + 1; 157 158 rc = gfx_set_color(gc, panel->curs_color); 159 if (rc != EOK) 160 return rc; 161 162 rc = gfx_fill_rect(gc, &rect); 163 if (rc != EOK) 164 return rc; 165 166 fmt.color = panel->curs_color; 167 } else { 168 fmt.color = panel->color; 169 } 170 171 rc = gfx_puttext(font, &pos, &fmt, entry->name); 207 while (entry != NULL && i < lines) { 208 rc = panel_entry_paint(entry, panel->page_idx + i); 172 209 if (rc != EOK) 173 210 return rc; 174 211 175 pos.y++;212 ++i; 176 213 entry = panel_next(entry); 177 214 } … … 184 221 } 185 222 223 /** Handle panel keyboard event. 224 * 225 * @param panel Panel 226 * @param event Keyboard event 227 * @return ui_claimed iff event was claimed 228 */ 229 ui_evclaim_t panel_kbd_event(panel_t *panel, kbd_event_t *event) 230 { 231 if (event->type == KEY_PRESS) { 232 if ((event->mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) { 233 switch (event->key) { 234 case KC_UP: 235 panel_cursor_up(panel); 236 break; 237 case KC_DOWN: 238 panel_cursor_down(panel); 239 break; 240 case KC_HOME: 241 panel_cursor_top(panel); 242 break; 243 case KC_END: 244 panel_cursor_bottom(panel); 245 break; 246 default: 247 break; 248 } 249 } 250 } 251 252 return ui_unclaimed; 253 } 254 186 255 /** Handle panel position event. 187 256 * … … 236 305 237 306 return panel_paint(panel); 307 } 308 309 /** Handle panel control keyboard event. 310 * 311 * @param arg Argument (panel_t *) 312 * @param kbd_event Keyboard event 313 * @return @c ui_claimed iff the event is claimed 314 */ 315 ui_evclaim_t panel_ctl_kbd_event(void *arg, kbd_event_t *event) 316 { 317 panel_t *panel = (panel_t *) arg; 318 319 return panel_kbd_event(panel, event); 238 320 } 239 321 … … 276 358 link_initialize(&entry->lentries); 277 359 list_append(&entry->lentries, &panel->entries); 360 ++panel->entries_cnt; 278 361 return EOK; 279 362 } … … 291 374 292 375 list_remove(&entry->lentries); 376 --entry->panel->entries_cnt; 293 377 free(entry->name); 294 378 free(entry); … … 337 421 338 422 panel->cursor = panel_first(panel); 423 panel->cursor_idx = 0; 339 424 panel->page = panel_first(panel); 425 panel->page_idx = 0; 340 426 return EOK; 341 427 error: … … 360 446 } 361 447 448 /** Return last panel entry. 449 * 450 * @panel Panel 451 * @return Last panel entry or @c NULL if there are no entries 452 */ 453 panel_entry_t *panel_last(panel_t *panel) 454 { 455 link_t *link; 456 457 link = list_last(&panel->entries); 458 if (link == NULL) 459 return NULL; 460 461 return list_get_instance(link, panel_entry_t, lentries); 462 } 463 362 464 /** Return next panel entry. 363 465 * … … 376 478 } 377 479 480 /** Return previous panel entry. 481 * 482 * @param cur Current entry 483 * @return Previous entry or @c NULL if @a cur is the first entry 484 */ 485 panel_entry_t *panel_prev(panel_entry_t *cur) 486 { 487 link_t *link; 488 489 link = list_prev(&cur->lentries, &cur->panel->entries); 490 if (link == NULL) 491 return NULL; 492 493 return list_get_instance(link, panel_entry_t, lentries); 494 } 495 496 void panel_cursor_move(panel_t *panel, panel_entry_t *entry, size_t entry_idx) 497 { 498 gfx_context_t *gc = ui_window_get_gc(panel->window); 499 panel_entry_t *old_cursor; 500 size_t old_idx; 501 size_t rows; 502 panel_entry_t *e; 503 size_t i; 504 505 rows = panel->rect.p1.y - panel->rect.p0.y - 2; 506 507 old_cursor = panel->cursor; 508 old_idx = panel->cursor_idx; 509 510 panel->cursor = entry; 511 panel->cursor_idx = entry_idx; 512 513 if (entry_idx >= panel->page_idx && 514 entry_idx < panel->page_idx + rows) { 515 /* 516 * If cursor is still on the current page, we're not 517 * scrolling. Just unpaint old cursor and paint new 518 * cursor. 519 */ 520 panel_entry_paint(old_cursor, old_idx); 521 panel_entry_paint(panel->cursor, panel->cursor_idx); 522 523 (void) gfx_update(gc); 524 } else { 525 /* 526 * Need to scroll and update all rows. 527 */ 528 529 /* Scrolling up */ 530 if (entry_idx < panel->page_idx) { 531 panel->page = entry; 532 panel->page_idx = entry_idx; 533 } 534 535 /* Scrolling down */ 536 if (entry_idx >= panel->page_idx + rows) { 537 if (entry_idx >= rows) { 538 panel->page_idx = entry_idx - rows + 1; 539 /* Find first page entry (go back rows - 1) */ 540 e = entry; 541 for (i = 0; i < rows - 1; i++) { 542 e = panel_prev(e); 543 } 544 545 /* Should be valid */ 546 assert(e != NULL); 547 panel->page = e; 548 } else { 549 panel->page = panel_first(panel); 550 panel->page_idx = 0; 551 } 552 } 553 554 (void) panel_paint(panel); 555 } 556 } 557 558 /** Move cursor one entry up. 559 * 560 * @param panel Panel 561 */ 562 void panel_cursor_up(panel_t *panel) 563 { 564 panel_entry_t *prev; 565 size_t prev_idx; 566 567 prev = panel_prev(panel->cursor); 568 prev_idx = panel->cursor_idx - 1; 569 if (prev != NULL) 570 panel_cursor_move(panel, prev, prev_idx); 571 } 572 573 /** Move cursor one entry down. 574 * 575 * @param panel Panel 576 */ 577 void panel_cursor_down(panel_t *panel) 578 { 579 panel_entry_t *next; 580 size_t next_idx; 581 582 next = panel_next(panel->cursor); 583 next_idx = panel->cursor_idx + 1; 584 if (next != NULL) 585 panel_cursor_move(panel, next, next_idx); 586 } 587 588 /** Move cursor to top. 589 * 590 * @param panel Panel 591 */ 592 void panel_cursor_top(panel_t *panel) 593 { 594 panel_cursor_move(panel, panel_first(panel), 0); 595 } 596 597 /** Move cursor to bottom. 598 * 599 * @param panel Panel 600 */ 601 void panel_cursor_bottom(panel_t *panel) 602 { 603 panel_cursor_move(panel, panel_last(panel), panel->entries_cnt - 1); 604 } 605 378 606 /** @} 379 607 */
Note:
See TracChangeset
for help on using the changeset viewer.