1 /* 2 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/> 3 * (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com> 4 * 5 * This file is part of lsp-plugins 6 * Created on: 15 июн. 2017 г. 7 * 8 * lsp-plugins is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * any later version. 12 * 13 * lsp-plugins is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>. 20 */ 21 22 #include <ui/tk/tk.h> 23 24 namespace lsp 25 { 26 namespace tk 27 { 28 const w_class_t LSPWidget::metadata = { "LSPWidget", NULL }; 29 LSPWidget(LSPDisplay * dpy)30 LSPWidget::LSPWidget(LSPDisplay *dpy): 31 sPadding(this), 32 sBgColor(this), 33 sBrightness(this) 34 { 35 pUID = NULL; 36 pDisplay = dpy; 37 pSurface = NULL; 38 pParent = NULL; 39 enCursor = MP_DEFAULT; 40 sSize.nLeft = 0; 41 sSize.nTop = 0; 42 sSize.nWidth = 0; 43 sSize.nHeight = 0; 44 nFlags = REDRAW_SURFACE | F_VISIBLE | F_HFILL | F_VFILL; 45 pClass = &metadata; 46 } 47 ~LSPWidget()48 LSPWidget::~LSPWidget() 49 { 50 do_destroy(); 51 } 52 instance_of(const w_class_t * wclass) const53 bool LSPWidget::instance_of(const w_class_t *wclass) const 54 { 55 const w_class_t *wc = pClass; 56 while (wc != NULL) 57 { 58 if (wc == wclass) 59 return true; 60 wc = wc->parent; 61 } 62 63 return false; 64 } 65 init()66 status_t LSPWidget::init() 67 { 68 // Initialize style 69 status_t res = sStyle.init(); 70 if (res == STATUS_OK) 71 res = sStyle.add_parent(pDisplay->theme()->root()); 72 if (res == STATUS_OK) 73 res = sBgColor.bind("bg_color"); 74 if (res == STATUS_OK) 75 res = sBrightness.bind("brightness"); 76 77 // Declare slots 78 ui_handler_id_t id = 0; 79 80 id = sSlots.add(LSPSLOT_FOCUS_IN, slot_focus_in, self()); 81 if (id >= 0) id = sSlots.add(LSPSLOT_FOCUS_OUT, slot_focus_out, self()); 82 if (id >= 0) id = sSlots.add(LSPSLOT_KEY_DOWN, slot_key_down, self()); 83 if (id >= 0) id = sSlots.add(LSPSLOT_KEY_UP, slot_key_up, self()); 84 if (id >= 0) id = sSlots.add(LSPSLOT_MOUSE_DOWN, slot_mouse_down, self()); 85 if (id >= 0) id = sSlots.add(LSPSLOT_MOUSE_UP, slot_mouse_up, self()); 86 if (id >= 0) id = sSlots.add(LSPSLOT_MOUSE_MOVE, slot_mouse_move, self()); 87 if (id >= 0) id = sSlots.add(LSPSLOT_MOUSE_SCROLL, slot_mouse_scroll, self()); 88 if (id >= 0) id = sSlots.add(LSPSLOT_MOUSE_DBL_CLICK, slot_mouse_dbl_click, self()); 89 if (id >= 0) id = sSlots.add(LSPSLOT_MOUSE_TRI_CLICK, slot_mouse_tri_click, self()); 90 if (id >= 0) id = sSlots.add(LSPSLOT_MOUSE_IN, slot_mouse_in, self()); 91 if (id >= 0) id = sSlots.add(LSPSLOT_MOUSE_OUT, slot_mouse_out, self()); 92 if (id >= 0) id = sSlots.add(LSPSLOT_HIDE, slot_hide, self()); 93 if (id >= 0) id = sSlots.add(LSPSLOT_SHOW, slot_show, self()); 94 if (id >= 0) id = sSlots.add(LSPSLOT_DESTROY, slot_destroy, self()); 95 if (id >= 0) id = sSlots.add(LSPSLOT_RESIZE, slot_resize, self()); 96 if (id >= 0) id = sSlots.add(LSPSLOT_RESIZE_PARENT, slot_resize_parent, self()); 97 if (id >= 0) id = sSlots.add(LSPSLOT_DRAG_REQUEST, slot_drag_request, self()); 98 99 return (id >= 0) ? STATUS_OK : -id; 100 } 101 do_destroy()102 void LSPWidget::do_destroy() 103 { 104 // Set parent widget to NULL 105 set_parent(NULL); 106 107 // Destroy surface 108 if (pSurface != NULL) 109 { 110 pSurface->destroy(); 111 delete pSurface; 112 pSurface = NULL; 113 } 114 115 // Execute slots and unbind all to prevent duplicate on_destroy calls 116 sSlots.execute(LSPSLOT_DESTROY, this); 117 sSlots.destroy(); 118 119 // Destroy widget identifier 120 if (pUID != NULL) 121 ::free(pUID); 122 pUID = NULL; 123 } 124 unlink_widget(LSPWidget * w)125 void LSPWidget::unlink_widget(LSPWidget *w) 126 { 127 if (w == NULL) 128 return; 129 if (w->pParent == this) 130 w->pParent = NULL; 131 } 132 init_color(color_t value,LSPColor * color)133 void LSPWidget::init_color(color_t value, LSPColor *color) 134 { 135 Color c; 136 if (pDisplay != NULL) 137 { 138 LSPTheme *theme = pDisplay->theme(); 139 140 if (theme != NULL) 141 theme->get_color(value, c); 142 } 143 color->copy(&c); 144 } 145 slot_mouse_move(LSPWidget * sender,void * ptr,void * data)146 status_t LSPWidget::slot_mouse_move(LSPWidget *sender, void *ptr, void *data) 147 { 148 if ((ptr == NULL) || (data == NULL)) 149 return STATUS_BAD_ARGUMENTS; 150 151 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 152 ws_event_t *ev = static_cast<ws_event_t *>(data); 153 return _this->on_mouse_move(ev); 154 } 155 slot_mouse_down(LSPWidget * sender,void * ptr,void * data)156 status_t LSPWidget::slot_mouse_down(LSPWidget *sender, void *ptr, void *data) 157 { 158 if ((ptr == NULL) || (data == NULL)) 159 return STATUS_BAD_ARGUMENTS; 160 161 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 162 ws_event_t *ev = static_cast<ws_event_t *>(data); 163 return _this->on_mouse_down(ev); 164 } 165 slot_mouse_up(LSPWidget * sender,void * ptr,void * data)166 status_t LSPWidget::slot_mouse_up(LSPWidget *sender, void *ptr, void *data) 167 { 168 if ((ptr == NULL) || (data == NULL)) 169 return STATUS_BAD_ARGUMENTS; 170 171 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 172 ws_event_t *ev = static_cast<ws_event_t *>(data); 173 return _this->on_mouse_up(ev); 174 } 175 slot_mouse_dbl_click(LSPWidget * sender,void * ptr,void * data)176 status_t LSPWidget::slot_mouse_dbl_click(LSPWidget *sender, void *ptr, void *data) 177 { 178 if ((ptr == NULL) || (data == NULL)) 179 return STATUS_BAD_ARGUMENTS; 180 181 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 182 ws_event_t *ev = static_cast<ws_event_t *>(data); 183 return _this->on_mouse_dbl_click(ev); 184 } 185 slot_mouse_tri_click(LSPWidget * sender,void * ptr,void * data)186 status_t LSPWidget::slot_mouse_tri_click(LSPWidget *sender, void *ptr, void *data) 187 { 188 if ((ptr == NULL) || (data == NULL)) 189 return STATUS_BAD_ARGUMENTS; 190 191 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 192 ws_event_t *ev = static_cast<ws_event_t *>(data); 193 return _this->on_mouse_tri_click(ev); 194 } 195 slot_mouse_scroll(LSPWidget * sender,void * ptr,void * data)196 status_t LSPWidget::slot_mouse_scroll(LSPWidget *sender, void *ptr, void *data) 197 { 198 if ((ptr == NULL) || (data == NULL)) 199 return STATUS_BAD_ARGUMENTS; 200 201 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 202 ws_event_t *ev = static_cast<ws_event_t *>(data); 203 return _this->on_mouse_scroll(ev); 204 } 205 slot_mouse_in(LSPWidget * sender,void * ptr,void * data)206 status_t LSPWidget::slot_mouse_in(LSPWidget *sender, void *ptr, void *data) 207 { 208 if ((ptr == NULL) || (data == NULL)) 209 return STATUS_BAD_ARGUMENTS; 210 211 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 212 ws_event_t *ev = static_cast<ws_event_t *>(data); 213 return _this->on_mouse_in(ev); 214 } 215 slot_mouse_out(LSPWidget * sender,void * ptr,void * data)216 status_t LSPWidget::slot_mouse_out(LSPWidget *sender, void *ptr, void *data) 217 { 218 if ((ptr == NULL) || (data == NULL)) 219 return STATUS_BAD_ARGUMENTS; 220 221 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 222 ws_event_t *ev = static_cast<ws_event_t *>(data); 223 return _this->on_mouse_out(ev); 224 } 225 slot_key_down(LSPWidget * sender,void * ptr,void * data)226 status_t LSPWidget::slot_key_down(LSPWidget *sender, void *ptr, void *data) 227 { 228 if ((ptr == NULL) || (data == NULL)) 229 return STATUS_BAD_ARGUMENTS; 230 231 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 232 ws_event_t *ev = static_cast<ws_event_t *>(data); 233 return _this->on_key_down(ev); 234 } 235 slot_key_up(LSPWidget * sender,void * ptr,void * data)236 status_t LSPWidget::slot_key_up(LSPWidget *sender, void *ptr, void *data) 237 { 238 if ((ptr == NULL) || (data == NULL)) 239 return STATUS_BAD_ARGUMENTS; 240 241 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 242 ws_event_t *ev = static_cast<ws_event_t *>(data); 243 return _this->on_key_up(ev); 244 } 245 slot_hide(LSPWidget * sender,void * ptr,void * data)246 status_t LSPWidget::slot_hide(LSPWidget *sender, void *ptr, void *data) 247 { 248 if (ptr == NULL) 249 return STATUS_BAD_ARGUMENTS; 250 251 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 252 return _this->on_hide(); 253 } 254 slot_show(LSPWidget * sender,void * ptr,void * data)255 status_t LSPWidget::slot_show(LSPWidget *sender, void *ptr, void *data) 256 { 257 if (ptr == NULL) 258 return STATUS_BAD_ARGUMENTS; 259 260 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 261 return _this->on_show(); 262 } 263 slot_destroy(LSPWidget * sender,void * ptr,void * data)264 status_t LSPWidget::slot_destroy(LSPWidget *sender, void *ptr, void *data) 265 { 266 if (ptr == NULL) 267 return STATUS_BAD_ARGUMENTS; 268 269 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 270 return _this->on_destroy(); 271 } 272 slot_resize(LSPWidget * sender,void * ptr,void * data)273 status_t LSPWidget::slot_resize(LSPWidget *sender, void *ptr, void *data) 274 { 275 if ((ptr == NULL) || (data == NULL)) 276 return STATUS_BAD_ARGUMENTS; 277 278 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 279 realize_t *ev = static_cast<realize_t *>(data); 280 return _this->on_resize(ev); 281 } 282 slot_resize_parent(LSPWidget * sender,void * ptr,void * data)283 status_t LSPWidget::slot_resize_parent(LSPWidget *sender, void *ptr, void *data) 284 { 285 if ((ptr == NULL) || (data == NULL)) 286 return STATUS_BAD_ARGUMENTS; 287 288 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 289 realize_t *ev = static_cast<realize_t *>(data); 290 return _this->on_resize_parent(ev); 291 } 292 slot_focus_in(LSPWidget * sender,void * ptr,void * data)293 status_t LSPWidget::slot_focus_in(LSPWidget *sender, void *ptr, void *data) 294 { 295 if ((ptr == NULL) || (data == NULL)) 296 return STATUS_BAD_ARGUMENTS; 297 298 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 299 ws_event_t *ev = static_cast<ws_event_t *>(data); 300 return _this->on_focus_in(ev); 301 } 302 slot_focus_out(LSPWidget * sender,void * ptr,void * data)303 status_t LSPWidget::slot_focus_out(LSPWidget *sender, void *ptr, void *data) 304 { 305 if ((ptr == NULL) || (data == NULL)) 306 return STATUS_BAD_ARGUMENTS; 307 308 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 309 ws_event_t *ev = static_cast<ws_event_t *>(data); 310 return _this->on_focus_out(ev); 311 } 312 slot_drag_request(LSPWidget * sender,void * ptr,void * data)313 status_t LSPWidget::slot_drag_request(LSPWidget *sender, void *ptr, void *data) 314 { 315 if ((ptr == NULL) || (data == NULL)) 316 return STATUS_BAD_ARGUMENTS; 317 318 LSPWidget *_this = static_cast<LSPWidget *>(ptr); 319 ws_event_t *ev = static_cast<ws_event_t *>(data); 320 const char * const *ctype = _this->pDisplay->get_drag_mime_types(); 321 322 return _this->on_drag_request(ev, ctype); 323 } 324 relative_left() const325 ssize_t LSPWidget::relative_left() const 326 { 327 return sSize.nLeft - ((pParent != NULL) ? pParent->left() : 0); 328 } 329 relative_right() const330 ssize_t LSPWidget::relative_right() const 331 { 332 return sSize.nLeft - ((pParent != NULL) ? pParent->left() : 0) + sSize.nWidth; 333 } 334 relative_top() const335 ssize_t LSPWidget::relative_top() const 336 { 337 return sSize.nTop - ((pParent != NULL) ? pParent->top() : 0); 338 } 339 relative_bottom() const340 ssize_t LSPWidget::relative_bottom() const 341 { 342 return sSize.nTop - ((pParent != NULL) ? pParent->top() : 0) + sSize.nHeight; 343 } 344 inside(ssize_t x,ssize_t y)345 bool LSPWidget::inside(ssize_t x, ssize_t y) 346 { 347 if (!(nFlags & F_VISIBLE)) 348 return false; 349 else if (x < sSize.nLeft) 350 return false; 351 else if (x >= (sSize.nLeft + sSize.nWidth)) 352 return false; 353 else if (y < sSize.nTop) 354 return false; 355 else if (y >= (sSize.nTop + sSize.nHeight)) 356 return false; 357 358 return true; 359 } 360 active_cursor() const361 mouse_pointer_t LSPWidget::active_cursor() const 362 { 363 return enCursor; 364 } 365 hide()366 bool LSPWidget::hide() 367 { 368 if (!(nFlags & F_VISIBLE)) 369 return false; 370 nFlags &= ~F_VISIBLE; 371 // lsp_trace("class = %s, this=%p", get_class()->name, this); 372 373 // Drop surface to not to eat memory 374 if (pSurface != NULL) 375 { 376 pSurface->destroy(); 377 delete pSurface; 378 pSurface = NULL; 379 } 380 381 // Execute slot 382 sSlots.execute(LSPSLOT_HIDE, this); 383 384 // Query draw for parent widget 385 if (pParent != NULL) 386 pParent->query_resize(); 387 388 return true; 389 } 390 show()391 bool LSPWidget::show() 392 { 393 if (nFlags & F_VISIBLE) 394 return false; 395 // lsp_trace("class = %s, this=%p", get_class()->name, this); 396 397 nFlags |= F_VISIBLE; 398 if (pParent != NULL) 399 pParent->query_resize(); 400 query_draw(REDRAW_CHILD | REDRAW_SURFACE); 401 sSlots.execute(LSPSLOT_SHOW, this); 402 403 return true; 404 } 405 set_parent(LSPComplexWidget * parent)406 void LSPWidget::set_parent(LSPComplexWidget *parent) 407 { 408 if (pParent == parent) 409 return; 410 411 if (pParent != NULL) 412 { 413 LSPWindow *wnd = widget_cast<LSPWindow>(toplevel()); 414 if (wnd != NULL) 415 wnd->unfocus_child(this); 416 sStyle.remove_parent(pParent->style()); // Unlink style 417 418 LSPWidgetContainer *wc = widget_cast<LSPWidgetContainer>(pParent); 419 if (wc != NULL) 420 wc->remove(this); 421 } 422 423 pParent = parent; 424 if (parent != NULL) // Inherit the style of parent widget 425 sStyle.add_parent(parent->style()); 426 } 427 toplevel()428 LSPWidget *LSPWidget::toplevel() 429 { 430 LSPWidget *p = this; 431 while (p->pParent != NULL) 432 p = p->pParent; 433 434 return p; 435 } 436 query_draw(size_t flags)437 void LSPWidget::query_draw(size_t flags) 438 { 439 if (!(nFlags & F_VISIBLE)) 440 return; 441 nFlags |= (flags & (REDRAW_CHILD | REDRAW_SURFACE)); 442 if (pParent != NULL) 443 pParent->query_draw(REDRAW_CHILD); 444 } 445 commit_redraw()446 void LSPWidget::commit_redraw() 447 { 448 nFlags &= ~(REDRAW_SURFACE | REDRAW_CHILD); 449 } 450 queue_destroy()451 status_t LSPWidget::queue_destroy() 452 { 453 if (pDisplay == NULL) 454 return STATUS_BAD_STATE; 455 return pDisplay->queue_destroy(this); 456 } 457 query_resize()458 void LSPWidget::query_resize() 459 { 460 LSPWidget *w = toplevel(); 461 if ((w != NULL) && (w != this)) 462 w->query_resize(); 463 } 464 set_expand(bool value)465 void LSPWidget::set_expand(bool value) 466 { 467 size_t flags = nFlags; 468 if (value) 469 nFlags |= F_EXPAND; 470 else 471 nFlags &= ~F_EXPAND; 472 473 if (flags != nFlags) 474 query_resize(); 475 } 476 set_fill(bool value)477 void LSPWidget::set_fill(bool value) 478 { 479 size_t flags = nFlags; 480 if (value) 481 nFlags |= F_HFILL | F_VFILL; 482 else 483 nFlags &= ~(F_HFILL | F_VFILL); 484 485 if (flags != nFlags) 486 query_resize(); 487 } 488 set_hfill(bool value)489 void LSPWidget::set_hfill(bool value) 490 { 491 size_t flags = nFlags; 492 if (value) 493 nFlags |= F_HFILL; 494 else 495 nFlags &= ~F_HFILL; 496 497 if (flags != nFlags) 498 query_resize(); 499 } 500 set_vfill(bool value)501 void LSPWidget::set_vfill(bool value) 502 { 503 size_t flags = nFlags; 504 if (value) 505 nFlags |= F_VFILL; 506 else 507 nFlags &= ~F_VFILL; 508 509 if (flags != nFlags) 510 query_resize(); 511 } 512 set_visible(bool visible)513 void LSPWidget::set_visible(bool visible) 514 { 515 if (visible) 516 show(); 517 else 518 hide(); 519 } 520 521 /** Set mouse pointer 522 * 523 * @param mp mouse pointer 524 * @return mouse pointer 525 */ set_cursor(mouse_pointer_t mp)526 status_t LSPWidget::set_cursor(mouse_pointer_t mp) 527 { 528 enCursor = mp; 529 return STATUS_OK; 530 } 531 render(ISurface * s,bool force)532 void LSPWidget::render(ISurface *s, bool force) 533 { 534 // Get surface of widget 535 ISurface *src = get_surface(s); 536 if (src == NULL) 537 return; 538 539 // Render to the main surface 540 s->draw(src, sSize.nLeft, sSize.nTop); 541 } 542 set_unique_id(const char * uid)543 status_t LSPWidget::set_unique_id(const char *uid) 544 { 545 char *rep = NULL; 546 if (uid != NULL) 547 { 548 if ((rep = strdup(uid)) == NULL) 549 return STATUS_NO_MEM; 550 } 551 552 if (pUID != NULL) 553 free(pUID); 554 pUID = rep; 555 return STATUS_OK; 556 } 557 get_surface(ISurface * s)558 ISurface *LSPWidget::get_surface(ISurface *s) 559 { 560 return get_surface(s, sSize.nWidth, sSize.nHeight); 561 } 562 get_surface(ISurface * s,ssize_t width,ssize_t height)563 ISurface *LSPWidget::get_surface(ISurface *s, ssize_t width, ssize_t height) 564 { 565 // Check surface 566 if (pSurface != NULL) 567 { 568 if ((width != ssize_t(pSurface->width())) || (height != ssize_t(pSurface->height()))) 569 { 570 pSurface->destroy(); 571 delete pSurface; 572 pSurface = NULL; 573 } 574 } 575 576 // Create new surface if needed 577 if (pSurface == NULL) 578 { 579 if (s == NULL) 580 return NULL; 581 582 // Do not return surface if size is negative 583 if ((width <= 0) || (height <= 0)) 584 return NULL; 585 586 pSurface = s->create(width, height); 587 if (pSurface == NULL) 588 return NULL; 589 nFlags |= REDRAW_SURFACE; 590 } 591 592 // Redraw surface if required 593 if (nFlags & REDRAW_SURFACE) 594 { 595 draw(pSurface); 596 nFlags &= ~REDRAW_SURFACE; 597 } 598 599 return pSurface; 600 } 601 draw(ISurface * s)602 void LSPWidget::draw(ISurface *s) 603 { 604 } 605 realize(const realize_t * r)606 void LSPWidget::realize(const realize_t *r) 607 { 608 // Do not report size request on size change 609 if ((sSize.nLeft == r->nLeft) && 610 (sSize.nTop == r->nTop) && 611 (sSize.nWidth == r->nWidth) && 612 (sSize.nHeight == r->nHeight)) 613 return; 614 615 // Execute slot and update size 616 realize_t xr = *r; 617 sSlots.execute(LSPSLOT_RESIZE, this, &xr); 618 sSize = *r; 619 } 620 size_request(size_request_t * r)621 void LSPWidget::size_request(size_request_t *r) 622 { 623 r->nMinWidth = -1; 624 r->nMinHeight = -1; 625 r->nMaxWidth = -1; 626 r->nMaxHeight = -1; 627 } 628 has_focus() const629 bool LSPWidget::has_focus() const 630 { 631 if (!(nFlags & F_VISIBLE)) 632 return false; 633 634 LSPWidget *_this = const_cast<LSPWidget *>(this); 635 LSPWindow *wnd = widget_cast<LSPWindow>(_this->toplevel()); 636 return (wnd != NULL) ? (wnd->focused_child() == this) : false; 637 } 638 set_focus(bool focus)639 status_t LSPWidget::set_focus(bool focus) 640 { 641 if (!(nFlags & F_VISIBLE)) 642 return STATUS_OK; 643 644 LSPWindow *wnd = widget_cast<LSPWindow>(toplevel()); 645 if (wnd == NULL) 646 return STATUS_BAD_HIERARCHY; 647 return (focus) ? wnd->focus_child(this) : wnd->unfocus_child(this); 648 } 649 toggle_focus()650 status_t LSPWidget::toggle_focus() 651 { 652 if (!(nFlags & F_VISIBLE)) 653 return STATUS_OK; 654 655 LSPWindow *wnd = widget_cast<LSPWindow>(toplevel()); 656 return (wnd != NULL) ? wnd->toggle_child_focus(this) : STATUS_BAD_HIERARCHY; 657 } 658 mark_pointed()659 status_t LSPWidget::mark_pointed() 660 { 661 LSPWindow *wnd = widget_cast<LSPWindow>(toplevel()); 662 if (wnd == NULL) 663 return STATUS_SUCCESS; 664 return wnd->point_child(this); 665 } 666 handle_event(const ws_event_t * e)667 status_t LSPWidget::handle_event(const ws_event_t *e) 668 { 669 #define FWD_EVENT(ev, slot_id) \ 670 case ev: \ 671 { \ 672 ws_event_t tmp = *e; \ 673 sSlots.execute(slot_id, this, &tmp); \ 674 break; \ 675 } 676 677 switch (e->nType) 678 { 679 FWD_EVENT(UIE_KEY_DOWN, LSPSLOT_KEY_DOWN ) 680 FWD_EVENT(UIE_KEY_UP, LSPSLOT_KEY_UP ) 681 FWD_EVENT(UIE_MOUSE_DOWN, LSPSLOT_MOUSE_DOWN ) 682 FWD_EVENT(UIE_MOUSE_UP, LSPSLOT_MOUSE_UP ) 683 FWD_EVENT(UIE_MOUSE_IN, LSPSLOT_MOUSE_IN ) 684 FWD_EVENT(UIE_MOUSE_OUT, LSPSLOT_MOUSE_OUT ) 685 FWD_EVENT(UIE_MOUSE_MOVE, LSPSLOT_MOUSE_MOVE ) 686 FWD_EVENT(UIE_MOUSE_SCROLL, LSPSLOT_MOUSE_SCROLL ) 687 FWD_EVENT(UIE_MOUSE_DBL_CLICK, LSPSLOT_MOUSE_DBL_CLICK ) 688 FWD_EVENT(UIE_MOUSE_TRI_CLICK, LSPSLOT_MOUSE_TRI_CLICK ) 689 FWD_EVENT(UIE_FOCUS_IN, LSPSLOT_FOCUS_IN ) 690 FWD_EVENT(UIE_FOCUS_OUT, LSPSLOT_FOCUS_OUT ) 691 FWD_EVENT(UIE_DRAG_REQUEST, LSPSLOT_DRAG_REQUEST ) 692 693 default: 694 break; 695 } 696 #undef FWD_EVENT 697 698 return STATUS_OK; 699 } 700 destroy()701 void LSPWidget::destroy() 702 { 703 do_destroy(); 704 } 705 on_key_down(const ws_event_t * e)706 status_t LSPWidget::on_key_down(const ws_event_t *e) 707 { 708 return STATUS_OK; 709 } 710 on_key_up(const ws_event_t * e)711 status_t LSPWidget::on_key_up(const ws_event_t *e) 712 { 713 return STATUS_OK; 714 } 715 on_mouse_down(const ws_event_t * e)716 status_t LSPWidget::on_mouse_down(const ws_event_t *e) 717 { 718 return STATUS_OK; 719 } 720 on_mouse_up(const ws_event_t * e)721 status_t LSPWidget::on_mouse_up(const ws_event_t *e) 722 { 723 return STATUS_OK; 724 } 725 on_mouse_move(const ws_event_t * e)726 status_t LSPWidget::on_mouse_move(const ws_event_t *e) 727 { 728 return STATUS_OK; 729 } 730 on_mouse_in(const ws_event_t * e)731 status_t LSPWidget::on_mouse_in(const ws_event_t *e) 732 { 733 // Always mark widget pointed 734 return mark_pointed(); 735 } 736 on_mouse_out(const ws_event_t * e)737 status_t LSPWidget::on_mouse_out(const ws_event_t *e) 738 { 739 return STATUS_OK; 740 } 741 on_mouse_scroll(const ws_event_t * e)742 status_t LSPWidget::on_mouse_scroll(const ws_event_t *e) 743 { 744 return STATUS_OK; 745 } 746 on_mouse_dbl_click(const ws_event_t * e)747 status_t LSPWidget::on_mouse_dbl_click(const ws_event_t *e) 748 { 749 return STATUS_OK; 750 } 751 on_mouse_tri_click(const ws_event_t * e)752 status_t LSPWidget::on_mouse_tri_click(const ws_event_t *e) 753 { 754 return STATUS_OK; 755 } 756 on_resize(const realize_t * r)757 status_t LSPWidget::on_resize(const realize_t *r) 758 { 759 return STATUS_OK; 760 } 761 on_resize_parent(const realize_t * r)762 status_t LSPWidget::on_resize_parent(const realize_t *r) 763 { 764 return STATUS_OK; 765 } 766 on_hide()767 status_t LSPWidget::on_hide() 768 { 769 return STATUS_OK; 770 } 771 on_show()772 status_t LSPWidget::on_show() 773 { 774 return STATUS_OK; 775 } 776 on_destroy()777 status_t LSPWidget::on_destroy() 778 { 779 return STATUS_OK; 780 } 781 on_focus_in(const ws_event_t * e)782 status_t LSPWidget::on_focus_in(const ws_event_t *e) 783 { 784 return STATUS_OK; 785 } 786 on_focus_out(const ws_event_t * e)787 status_t LSPWidget::on_focus_out(const ws_event_t *e) 788 { 789 return STATUS_OK; 790 } 791 on_drag_request(const ws_event_t * e,const char * const * ctype)792 status_t LSPWidget::on_drag_request(const ws_event_t *e, const char * const *ctype) 793 { 794 return STATUS_OK; 795 } 796 } 797 798 } /* namespace lsp */ 799