Changeset 59768c7 in mainline for uspace/lib/ui/src
- Timestamp:
- 2022-01-10T19:29:00Z (4 years ago)
- Branches:
- master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5de852c
- Parents:
- 9754ed2
- git-author:
- Jiri Svoboda <jiri@…> (2022-01-10 19:27:55)
- git-committer:
- Jiri Svoboda <jiri@…> (2022-01-10 19:29:00)
- Location:
- uspace/lib/ui/src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ui/src/menu.c
r9754ed2 r59768c7 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2022 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 47 47 #include <ui/popup.h> 48 48 #include <ui/menu.h> 49 #include <ui/menubar.h> 49 50 #include <ui/menuentry.h> 50 51 #include <ui/resource.h> … … 63 64 64 65 static void ui_menu_popup_close(ui_popup_t *, void *); 66 static void ui_menu_popup_kbd(ui_popup_t *, void *, kbd_event_t *); 65 67 static void ui_menu_popup_pos(ui_popup_t *, void *, pos_event_t *); 66 68 67 69 static ui_popup_cb_t ui_menu_popup_cb = { 68 70 .close = ui_menu_popup_close, 71 .kbd = ui_menu_popup_kbd, 69 72 .pos = ui_menu_popup_pos 70 73 }; … … 149 152 150 153 link = list_next(&cur->lmenus, &cur->mbar->menus); 154 if (link == NULL) 155 return NULL; 156 157 return list_get_instance(link, ui_menu_t, lmenus); 158 } 159 160 /** Get last menu in menu bar. 161 * 162 * @param mbar Menu bar 163 * @return Last menu or @c NULL if there is none 164 */ 165 ui_menu_t *ui_menu_last(ui_menu_bar_t *mbar) 166 { 167 link_t *link; 168 169 link = list_last(&mbar->menus); 170 if (link == NULL) 171 return NULL; 172 173 return list_get_instance(link, ui_menu_t, lmenus); 174 } 175 176 /** Get previous menu in menu bar. 177 * 178 * @param cur Current menu 179 * @return Previous menu or @c NULL if @a cur is the fist one 180 */ 181 ui_menu_t *ui_menu_prev(ui_menu_t *cur) 182 { 183 link_t *link; 184 185 link = list_prev(&cur->lmenus, &cur->mbar->menus); 151 186 if (link == NULL) 152 187 return NULL; … … 240 275 errno_t rc; 241 276 277 /* Select first entry */ 278 menu->selected = ui_menu_entry_first(menu); 279 242 280 /* Determine menu dimensions */ 243 281 … … 269 307 ui_popup_destroy(menu->popup); 270 308 menu->popup = NULL; 309 } 310 311 /** Determine if menu is open. 312 * 313 * @param menu Menu 314 * @return @c true iff menu is open 315 */ 316 bool ui_menu_is_open(ui_menu_t *menu) 317 { 318 return menu->popup != NULL; 271 319 } 272 320 … … 439 487 /* Press outside menu - close it */ 440 488 if (event->type == POS_PRESS) 441 ui_menu_bar_ select(menu->mbar, NULL, NULL);489 ui_menu_bar_deactivate(menu->mbar); 442 490 } 443 491 … … 454 502 ui_menu_t *menu = (ui_menu_t *)arg; 455 503 456 /* Close the menu */ 457 ui_menu_bar_select(menu->mbar, NULL, NULL); 504 /* Deactivate menu bar, close menu */ 505 ui_menu_bar_deactivate(menu->mbar); 506 } 507 508 /** Move one entry up. 509 * 510 * Non-selectable entries are skipped. If we are already at the top, 511 * we wrap around. 512 * 513 * @param menu Menu 514 */ 515 void ui_menu_up(ui_menu_t *menu) 516 { 517 gfx_coord2_t mpos; 518 ui_menu_entry_t *nentry; 519 520 if (menu->selected == NULL) 521 return; 522 523 nentry = ui_menu_entry_prev(menu->selected); 524 if (nentry == NULL) 525 nentry = ui_menu_entry_last(menu); 526 527 /* Need to find a selectable entry */ 528 while (!ui_menu_entry_selectable(nentry)) { 529 nentry = ui_menu_entry_prev(nentry); 530 if (nentry == NULL) 531 nentry = ui_menu_entry_last(menu); 532 533 /* Went completely around and found nothing? */ 534 if (nentry == menu->selected) 535 return; 536 } 537 538 menu->selected = nentry; 539 540 mpos.x = 0; 541 mpos.y = 0; 542 (void) ui_menu_paint(menu, &mpos); 543 } 544 545 /** Move one entry down. 546 * 547 * Non-selectable entries are skipped. If we are already at the bottom, 548 * we wrap around. 549 * 550 * @param menu Menu 551 */ 552 void ui_menu_down(ui_menu_t *menu) 553 { 554 gfx_coord2_t mpos; 555 ui_menu_entry_t *nentry; 556 557 if (menu->selected == NULL) 558 return; 559 560 nentry = ui_menu_entry_next(menu->selected); 561 if (nentry == NULL) 562 nentry = ui_menu_entry_first(menu); 563 564 /* Need to find a selectable entry */ 565 while (!ui_menu_entry_selectable(nentry)) { 566 nentry = ui_menu_entry_next(nentry); 567 if (nentry == NULL) 568 nentry = ui_menu_entry_first(menu); 569 570 /* Went completely around and found nothing? */ 571 if (nentry == menu->selected) 572 return; 573 } 574 575 menu->selected = nentry; 576 577 mpos.x = 0; 578 mpos.y = 0; 579 (void) ui_menu_paint(menu, &mpos); 580 } 581 582 /** Handle key press without modifiers in menu popup window. 583 * 584 * @param menu Menu 585 * @param event Keyboard event 586 */ 587 static void ui_menu_key_press_unmod(ui_menu_t *menu, kbd_event_t *event) 588 { 589 switch (event->key) { 590 case KC_ESCAPE: 591 ui_menu_bar_deactivate(menu->mbar); 592 break; 593 case KC_LEFT: 594 ui_menu_bar_left(menu->mbar); 595 break; 596 case KC_RIGHT: 597 ui_menu_bar_right(menu->mbar); 598 break; 599 case KC_UP: 600 ui_menu_up(menu); 601 break; 602 case KC_DOWN: 603 ui_menu_down(menu); 604 break; 605 case KC_ENTER: 606 if (menu->selected != NULL) 607 ui_menu_entry_activate(menu->selected); 608 break; 609 default: 610 break; 611 } 612 } 613 614 /** Handle keyboard event in menu popup window. 615 * 616 * @param popup Menu popup window 617 * @param arg Argument (ui_menu_t *) 618 * @param event Keyboard event 619 */ 620 static void ui_menu_popup_kbd(ui_popup_t *popup, void *arg, kbd_event_t *event) 621 { 622 ui_menu_t *menu = (ui_menu_t *)arg; 623 624 if (event->type == KEY_PRESS && (event->mods & 625 (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) { 626 ui_menu_key_press_unmod(menu, event); 627 } 458 628 } 459 629 -
uspace/lib/ui/src/menubar.c
r9754ed2 r59768c7 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2022 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 60 60 static void ui_menu_bar_ctl_destroy(void *); 61 61 static errno_t ui_menu_bar_ctl_paint(void *); 62 static ui_evclaim_t ui_menu_bar_ctl_kbd_event(void *, kbd_event_t *); 62 63 static ui_evclaim_t ui_menu_bar_ctl_pos_event(void *, pos_event_t *); 63 64 … … 66 67 .destroy = ui_menu_bar_ctl_destroy, 67 68 .paint = ui_menu_bar_ctl_paint, 68 .pos_event = ui_menu_bar_ctl_pos_event, 69 .kbd_event = ui_menu_bar_ctl_kbd_event, 70 .pos_event = ui_menu_bar_ctl_pos_event 69 71 }; 70 72 … … 236 238 * 237 239 * @param mbar Menu bar 238 * @param rect Menu bar entry rectangle239 240 * @param menu Menu to select (or deselect if selected) or @c NULL 240 * /241 void ui_menu_bar_select(ui_menu_bar_t *mbar, gfx_rect_t *rect, 242 ui_menu_t *menu)241 * @param openup Open menu even if not currently open 242 */ 243 void ui_menu_bar_select(ui_menu_bar_t *mbar, ui_menu_t *menu, bool openup) 243 244 { 244 245 ui_menu_t *old_menu; 246 gfx_rect_t rect; 247 bool was_open; 245 248 246 249 old_menu = mbar->selected; … … 252 255 253 256 /* Close previously open menu */ 254 if (old_menu != NULL) 257 if (old_menu != NULL && ui_menu_is_open(old_menu)) { 258 was_open = true; 255 259 (void) ui_menu_close(old_menu); 260 } else { 261 was_open = false; 262 } 256 263 257 264 (void) ui_menu_bar_paint(mbar); 258 265 259 266 if (mbar->selected != NULL) { 260 (void) ui_menu_open(mbar->selected, rect); 261 } 267 ui_menu_bar_entry_rect(mbar, mbar->selected, &rect); 268 if (openup || was_open) { 269 /* 270 * Open the newly selected menu if either 271 * the old menu was open or @a openup was 272 * specified. 273 */ 274 (void) ui_menu_open(mbar->selected, &rect); 275 } 276 } 277 } 278 279 /** Move one entry left. 280 * 281 * If the selected menu is open, the newly selected menu will be open 282 * as well. If we are already at the first entry, we wrap around. 283 * 284 * @param mbar Menu bar 285 */ 286 void ui_menu_bar_left(ui_menu_bar_t *mbar) 287 { 288 ui_menu_t *nmenu; 289 290 if (mbar->selected == NULL) 291 return; 292 293 nmenu = ui_menu_prev(mbar->selected); 294 if (nmenu == NULL) 295 nmenu = ui_menu_last(mbar); 296 297 ui_menu_bar_select(mbar, nmenu, false); 298 } 299 300 /** Move one entry right. 301 * 302 * If the selected menu is open, the newly selected menu will be open 303 * as well. If we are already at the last entry, we wrap around. 304 * 305 * @param mbar Menu bar 306 */ 307 void ui_menu_bar_right(ui_menu_bar_t *mbar) 308 { 309 ui_menu_t *nmenu; 310 311 if (mbar->selected == NULL) 312 return; 313 314 nmenu = ui_menu_next(mbar->selected); 315 if (nmenu == NULL) 316 nmenu = ui_menu_first(mbar); 317 318 ui_menu_bar_select(mbar, nmenu, false); 319 } 320 321 /** Handle menu bar key press without modifiers. 322 * 323 * @param mbar Menu bar 324 * @param kbd_event Keyboard event 325 * @return @c ui_claimed iff the event is claimed 326 */ 327 ui_evclaim_t ui_menu_bar_key_press_unmod(ui_menu_bar_t *mbar, kbd_event_t *event) 328 { 329 gfx_rect_t rect; 330 331 if (event->key == KC_F10) { 332 ui_menu_bar_activate(mbar); 333 return ui_claimed; 334 } 335 336 if (!mbar->active) 337 return ui_unclaimed; 338 339 if (event->key == KC_ESCAPE) { 340 ui_menu_bar_deactivate(mbar); 341 return ui_claimed; 342 } 343 344 if (event->key == KC_LEFT) 345 ui_menu_bar_left(mbar); 346 347 if (event->key == KC_RIGHT) 348 ui_menu_bar_right(mbar); 349 350 if (event->key == KC_ENTER || event->key == KC_DOWN) { 351 if (mbar->selected != NULL && !ui_menu_is_open(mbar->selected)) { 352 ui_menu_bar_entry_rect(mbar, mbar->selected, 353 &rect); 354 ui_menu_open(mbar->selected, &rect); 355 } 356 357 return ui_claimed; 358 } 359 360 return ui_claimed; 361 } 362 363 /** Handle menu bar keyboard event. 364 * 365 * @param mbar Menu bar 366 * @param kbd_event Keyboard event 367 * @return @c ui_claimed iff the event is claimed 368 */ 369 ui_evclaim_t ui_menu_bar_kbd_event(ui_menu_bar_t *mbar, kbd_event_t *event) 370 { 371 if (event->type == KEY_PRESS && (event->mods & 372 (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) { 373 ui_menu_bar_key_press_unmod(mbar, event); 374 return ui_claimed; 375 } 376 377 return ui_claimed; 262 378 } 263 379 … … 304 420 if (event->type == POS_PRESS && 305 421 gfx_pix_inside_rect(&ppos, &rect)) { 306 ui_menu_bar_select(mbar, &rect, menu); 422 mbar->active = true; 423 ui_menu_bar_select(mbar, menu, true); 307 424 return ui_claimed; 308 425 } … … 315 432 } 316 433 434 /** Handle menu bar position event. 435 * 436 * @param mbar Menu bar 437 * @param menu Menu whose entry's rectangle is to be returned 438 * @param rrect Place to store entry rectangle 439 */ 440 void ui_menu_bar_entry_rect(ui_menu_bar_t *mbar, ui_menu_t *menu, 441 gfx_rect_t *rrect) 442 { 443 ui_resource_t *res; 444 gfx_coord2_t pos; 445 gfx_rect_t rect; 446 ui_menu_t *cur; 447 const char *caption; 448 gfx_coord_t width; 449 gfx_coord_t hpad; 450 451 res = ui_window_get_res(mbar->window); 452 453 if (res->textmode) { 454 hpad = menubar_hpad_text; 455 } else { 456 hpad = menubar_hpad; 457 } 458 459 pos = mbar->rect.p0; 460 461 cur = ui_menu_first(mbar); 462 while (cur != NULL) { 463 caption = ui_menu_caption(cur); 464 width = gfx_text_width(res->font, caption) + 2 * hpad; 465 466 rect.p0 = pos; 467 rect.p1.x = rect.p0.x + width; 468 rect.p1.y = mbar->rect.p1.y; 469 470 if (cur == menu) { 471 *rrect = rect; 472 return; 473 } 474 475 pos.x += width; 476 cur = ui_menu_next(cur); 477 } 478 479 /* We should never get here */ 480 assert(false); 481 } 482 483 /** Activate menu bar. 484 * 485 * @param mbar Menu bar 486 */ 487 void ui_menu_bar_activate(ui_menu_bar_t *mbar) 488 { 489 if (mbar->active) 490 return; 491 492 mbar->active = true; 493 if (mbar->selected == NULL) 494 mbar->selected = ui_menu_first(mbar); 495 496 (void) ui_menu_bar_paint(mbar); 497 } 498 499 void ui_menu_bar_deactivate(ui_menu_bar_t *mbar) 500 { 501 ui_menu_bar_select(mbar, NULL, false); 502 mbar->active = false; 503 } 504 317 505 /** Destroy menu bar control. 318 506 * … … 338 526 } 339 527 340 /** Handle menu bar control positionevent.528 /** Handle menu bar control keyboard event. 341 529 * 342 530 * @param arg Argument (ui_menu_bar_t *) … … 344 532 * @return @c ui_claimed iff the event is claimed 345 533 */ 534 ui_evclaim_t ui_menu_bar_ctl_kbd_event(void *arg, kbd_event_t *event) 535 { 536 ui_menu_bar_t *mbar = (ui_menu_bar_t *) arg; 537 538 return ui_menu_bar_kbd_event(mbar, event); 539 } 540 541 /** Handle menu bar control position event. 542 * 543 * @param arg Argument (ui_menu_bar_t *) 544 * @param pos_event Position event 545 * @return @c ui_claimed iff the event is claimed 546 */ 346 547 ui_evclaim_t ui_menu_bar_ctl_pos_event(void *arg, pos_event_t *event) 347 548 { -
uspace/lib/ui/src/menuentry.c
r9754ed2 r59768c7 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2022 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 45 45 #include <ui/control.h> 46 46 #include <ui/paint.h> 47 #include <ui/menubar.h> 47 48 #include <ui/menuentry.h> 48 49 #include <ui/window.h> … … 177 178 } 178 179 180 /** Get last menu entry in menu. 181 * 182 * @param menu Menu 183 * @return Last menu entry or @c NULL if there is none 184 */ 185 ui_menu_entry_t *ui_menu_entry_last(ui_menu_t *menu) 186 { 187 link_t *link; 188 189 link = list_last(&menu->entries); 190 if (link == NULL) 191 return NULL; 192 193 return list_get_instance(link, ui_menu_entry_t, lentries); 194 } 195 179 196 /** Get next menu entry in menu. 180 197 * … … 187 204 188 205 link = list_next(&cur->lentries, &cur->menu->entries); 206 if (link == NULL) 207 return NULL; 208 209 return list_get_instance(link, ui_menu_entry_t, lentries); 210 } 211 212 /** Get previous menu entry in menu. 213 * 214 * @param cur Current menu entry 215 * @return Next menu entry or @c NULL if @a cur is the last one 216 */ 217 ui_menu_entry_t *ui_menu_entry_prev(ui_menu_entry_t *cur) 218 { 219 link_t *link; 220 221 link = list_prev(&cur->lentries, &cur->menu->entries); 189 222 if (link == NULL) 190 223 return NULL; … … 378 411 } 379 412 413 /** Determine if entry is selectable. 414 * 415 * @return @c true iff entry is selectable 416 */ 417 bool ui_menu_entry_selectable(ui_menu_entry_t *mentry) 418 { 419 return !mentry->separator; 420 } 421 380 422 /** Handle button press in menu entry. 381 423 * … … 407 449 mentry->held = false; 408 450 409 if (mentry->inside) { 410 /* Close menu */ 411 ui_menu_bar_select(mentry->menu->mbar, NULL, NULL); 412 413 /* Call back */ 414 ui_menu_entry_cb(mentry); 415 } 451 ui_menu_entry_activate(mentry); 452 } 453 454 /** Activate menu entry. 455 * 456 * @param mentry Menu entry 457 */ 458 void ui_menu_entry_activate(ui_menu_entry_t *mentry) 459 { 460 /* Deactivate menu bar, close menu */ 461 ui_menu_bar_deactivate(mentry->menu->mbar); 462 463 /* Call back */ 464 ui_menu_entry_cb(mentry); 416 465 } 417 466 -
uspace/lib/ui/src/popup.c
r9754ed2 r59768c7 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2022 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 36 36 #include <errno.h> 37 37 #include <gfx/context.h> 38 //#include <io/kbd_event.h>38 #include <io/kbd_event.h> 39 39 #include <io/pos_event.h> 40 40 #include <mem.h> … … 47 47 48 48 static void ui_popup_window_close(ui_window_t *, void *); 49 static void ui_popup_window_kbd(ui_window_t *, void *, kbd_event_t *); 49 50 static void ui_popup_window_pos(ui_window_t *, void *, pos_event_t *); 50 51 51 52 static ui_window_cb_t ui_popup_window_cb = { 52 53 .close = ui_popup_window_close, 54 .kbd = ui_popup_window_kbd, 53 55 .pos = ui_popup_window_pos 54 56 }; … … 200 202 } 201 203 204 /** Handle keyboard event in popup window. 205 * 206 * @param window Window 207 * @param arg Argument (ui_popup_t *) 208 * @param event Keyboard event 209 */ 210 static void ui_popup_window_kbd(ui_window_t *window, void *arg, 211 kbd_event_t *event) 212 { 213 ui_popup_t *popup = (ui_popup_t *)arg; 214 215 if (popup->cb != NULL && popup->cb->kbd != NULL) 216 popup->cb->kbd(popup, popup->arg, event); 217 } 218 202 219 /** Handle position event in popup window. 203 220 *
Note:
See TracChangeset
for help on using the changeset viewer.