1 #include "SkView.h" 2 #include "SkCanvas.h" 3 4 //////////////////////////////////////////////////////////////////////// 5 6 SkView::SkView(uint32_t flags) : fFlags(SkToU8(flags)) 7 { 8 fWidth = fHeight = 0; 9 fLoc.set(0, 0); 10 fParent = fFirstChild = fNextSibling = fPrevSibling = NULL; 11 12 fContainsFocus = 0; 13 } 14 15 SkView::~SkView() 16 { 17 this->detachAllChildren(); 18 } 19 20 void SkView::setFlags(uint32_t flags) 21 { 22 SkASSERT((flags & ~kAllFlagMasks) == 0); 23 24 uint32_t diff = fFlags ^ flags; 25 26 if (diff & kVisible_Mask) 27 this->inval(NULL); 28 29 fFlags = SkToU8(flags); 30 31 if (diff & kVisible_Mask) 32 { 33 this->inval(NULL); 34 } 35 } 36 37 void SkView::setVisibleP(bool pred) 38 { 39 this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift)); 40 } 41 42 void SkView::setEnabledP(bool pred) 43 { 44 this->setFlags(SkSetClearShift(fFlags, pred, kEnabled_Shift)); 45 } 46 47 void SkView::setFocusableP(bool pred) 48 { 49 this->setFlags(SkSetClearShift(fFlags, pred, kFocusable_Shift)); 50 } 51 52 void SkView::setSize(SkScalar width, SkScalar height) 53 { 54 width = SkMaxScalar(0, width); 55 height = SkMaxScalar(0, height); 56 57 if (fWidth != width || fHeight != height) 58 { 59 this->inval(NULL); 60 fWidth = width; 61 fHeight = height; 62 this->inval(NULL); 63 this->onSizeChange(); 64 this->invokeLayout(); 65 } 66 } 67 68 void SkView::setLoc(SkScalar x, SkScalar y) 69 { 70 if (fLoc.fX != x || fLoc.fY != y) 71 { 72 this->inval(NULL); 73 fLoc.set(x, y); 74 this->inval(NULL); 75 } 76 } 77 78 void SkView::offset(SkScalar dx, SkScalar dy) 79 { 80 if (dx || dy) 81 this->setLoc(fLoc.fX + dx, fLoc.fY + dy); 82 } 83 84 void SkView::draw(SkCanvas* canvas) 85 { 86 if (fWidth && fHeight && this->isVisible()) 87 { 88 SkRect r; 89 r.set(fLoc.fX, fLoc.fY, fLoc.fX + fWidth, fLoc.fY + fHeight); 90 if (canvas->quickReject(r, SkCanvas::kBW_EdgeType)) 91 return; 92 93 SkAutoCanvasRestore as(canvas, true); 94 95 canvas->clipRect(r); 96 canvas->translate(fLoc.fX, fLoc.fY); 97 98 if (fParent) { 99 fParent->beforeChild(this, canvas); 100 } 101 102 int sc = canvas->save(); 103 this->onDraw(canvas); 104 canvas->restoreToCount(sc); 105 106 if (fParent) { 107 fParent->afterChild(this, canvas); 108 } 109 110 B2FIter iter(this); 111 SkView* child; 112 113 SkCanvas* childCanvas = this->beforeChildren(canvas); 114 115 while ((child = iter.next()) != NULL) 116 child->draw(childCanvas); 117 118 this->afterChildren(canvas); 119 } 120 } 121 122 void SkView::inval(SkRect* rect) 123 { 124 if (!this->isVisible()) 125 return; 126 127 SkRect bounds; 128 129 this->getLocalBounds(&bounds); 130 if (rect && !bounds.intersect(*rect)) 131 return; 132 133 rect = &bounds; 134 SkView* view = this; 135 136 for (;;) 137 { 138 if (view->handleInval(bounds)) 139 break; 140 141 SkRect parentR; 142 SkView* parent = view->fParent; 143 144 if (parent == NULL || !parent->isVisible()) 145 break; 146 147 bounds.offset(view->fLoc.fX, view->fLoc.fY); 148 parent->getLocalBounds(&parentR); 149 if (!bounds.intersect(parentR)) 150 return; 151 152 view = parent; 153 } 154 } 155 156 //////////////////////////////////////////////////////////////////////////// 157 158 bool SkView::setFocusView(SkView* fv) 159 { 160 SkView* view = this; 161 162 do { 163 if (view->onSetFocusView(fv)) 164 return true; 165 } while ((view = view->fParent) != NULL); 166 return false; 167 } 168 169 SkView* SkView::getFocusView() const 170 { 171 SkView* focus = NULL; 172 const SkView* view = this; 173 do { 174 if (view->onGetFocusView(&focus)) 175 break; 176 } while ((view = view->fParent) != NULL); 177 return focus; 178 } 179 180 bool SkView::hasFocus() const 181 { 182 return this == this->getFocusView(); 183 } 184 185 bool SkView::acceptFocus() 186 { 187 return this->isFocusable() && this->setFocusView(this); 188 } 189 190 /* 191 Try to give focus to this view, or its children 192 */ 193 SkView* SkView::acceptFocus(FocusDirection dir) 194 { 195 if (dir == kNext_FocusDirection) 196 { 197 if (this->acceptFocus()) 198 return this; 199 200 B2FIter iter(this); 201 SkView* child, *focus; 202 while ((child = iter.next()) != NULL) 203 if ((focus = child->acceptFocus(dir)) != NULL) 204 return focus; 205 } 206 else // prev 207 { 208 F2BIter iter(this); 209 SkView* child, *focus; 210 while ((child = iter.next()) != NULL) 211 if ((focus = child->acceptFocus(dir)) != NULL) 212 return focus; 213 214 if (this->acceptFocus()) 215 return this; 216 } 217 218 return NULL; 219 } 220 221 SkView* SkView::moveFocus(FocusDirection dir) 222 { 223 SkView* focus = this->getFocusView(); 224 225 if (focus == NULL) 226 { // start with the root 227 focus = this; 228 while (focus->fParent) 229 focus = focus->fParent; 230 } 231 232 SkView* child, *parent; 233 234 if (dir == kNext_FocusDirection) 235 { 236 parent = focus; 237 child = focus->fFirstChild; 238 if (child) 239 goto FIRST_CHILD; 240 else 241 goto NEXT_SIB; 242 243 do { 244 while (child != parent->fFirstChild) 245 { 246 FIRST_CHILD: 247 if ((focus = child->acceptFocus(dir)) != NULL) 248 return focus; 249 child = child->fNextSibling; 250 } 251 NEXT_SIB: 252 child = parent->fNextSibling; 253 parent = parent->fParent; 254 } while (parent != NULL); 255 } 256 else // prevfocus 257 { 258 parent = focus->fParent; 259 if (parent == NULL) // we're the root 260 return focus->acceptFocus(dir); 261 else 262 { 263 child = focus; 264 while (parent) 265 { 266 while (child != parent->fFirstChild) 267 { 268 child = child->fPrevSibling; 269 if ((focus = child->acceptFocus(dir)) != NULL) 270 return focus; 271 } 272 if (parent->acceptFocus()) 273 return parent; 274 275 child = parent; 276 parent = parent->fParent; 277 } 278 } 279 } 280 return NULL; 281 } 282 283 void SkView::onFocusChange(bool gainFocusP) 284 { 285 this->inval(NULL); 286 } 287 288 //////////////////////////////////////////////////////////////////////////// 289 290 SkView::Click::Click(SkView* target) 291 { 292 SkASSERT(target); 293 fTargetID = target->getSinkID(); 294 fType = NULL; 295 fWeOwnTheType = false; 296 } 297 298 SkView::Click::~Click() 299 { 300 this->resetType(); 301 } 302 303 void SkView::Click::resetType() 304 { 305 if (fWeOwnTheType) 306 { 307 sk_free(fType); 308 fWeOwnTheType = false; 309 } 310 fType = NULL; 311 } 312 313 bool SkView::Click::isType(const char type[]) const 314 { 315 const char* t = fType; 316 317 if (type == t) 318 return true; 319 320 if (type == NULL) 321 type = ""; 322 if (t == NULL) 323 t = ""; 324 return !strcmp(t, type); 325 } 326 327 void SkView::Click::setType(const char type[]) 328 { 329 this->resetType(); 330 fType = (char*)type; 331 } 332 333 void SkView::Click::copyType(const char type[]) 334 { 335 if (fType != type) 336 { 337 this->resetType(); 338 if (type) 339 { 340 size_t len = strlen(type) + 1; 341 fType = (char*)sk_malloc_throw(len); 342 memcpy(fType, type, len); 343 fWeOwnTheType = true; 344 } 345 } 346 } 347 348 SkView::Click* SkView::findClickHandler(SkScalar x, SkScalar y) 349 { 350 if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) { 351 return false; 352 } 353 354 if (this->onSendClickToChildren(x, y)) { 355 F2BIter iter(this); 356 SkView* child; 357 358 while ((child = iter.next()) != NULL) 359 { 360 Click* click = child->findClickHandler(x - child->fLoc.fX, 361 y - child->fLoc.fY); 362 if (click) { 363 return click; 364 } 365 } 366 } 367 return this->onFindClickHandler(x, y); 368 } 369 370 void SkView::DoClickDown(Click* click, int x, int y) 371 { 372 SkASSERT(click); 373 374 SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID); 375 if (target == NULL) 376 return; 377 378 click->fIOrig.set(x, y); 379 click->fICurr = click->fIPrev = click->fIOrig; 380 381 click->fOrig.iset(x, y); 382 target->globalToLocal(&click->fOrig); 383 click->fPrev = click->fCurr = click->fOrig; 384 385 click->fState = Click::kDown_State; 386 target->onClick(click); 387 } 388 389 void SkView::DoClickMoved(Click* click, int x, int y) 390 { 391 SkASSERT(click); 392 393 SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID); 394 if (target == NULL) 395 return; 396 397 click->fIPrev = click->fICurr; 398 click->fICurr.set(x, y); 399 400 click->fPrev = click->fCurr; 401 click->fCurr.iset(x, y); 402 target->globalToLocal(&click->fCurr); 403 404 click->fState = Click::kMoved_State; 405 target->onClick(click); 406 } 407 408 void SkView::DoClickUp(Click* click, int x, int y) 409 { 410 SkASSERT(click); 411 412 SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID); 413 if (target == NULL) 414 return; 415 416 click->fIPrev = click->fICurr; 417 click->fICurr.set(x, y); 418 419 click->fPrev = click->fCurr; 420 click->fCurr.iset(x, y); 421 target->globalToLocal(&click->fCurr); 422 423 click->fState = Click::kUp_State; 424 target->onClick(click); 425 } 426 427 ////////////////////////////////////////////////////////////////////// 428 429 void SkView::invokeLayout() { 430 SkView::Layout* layout = this->getLayout(); 431 432 if (layout) { 433 layout->layoutChildren(this); 434 } 435 } 436 437 void SkView::onDraw(SkCanvas* canvas) { 438 Artist* artist = this->getArtist(); 439 440 if (artist) { 441 artist->draw(this, canvas); 442 } 443 } 444 445 void SkView::onSizeChange() {} 446 447 bool SkView::onSendClickToChildren(SkScalar x, SkScalar y) { 448 return true; 449 } 450 451 SkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y) { 452 return NULL; 453 } 454 455 bool SkView::onClick(Click*) { 456 return false; 457 } 458 459 bool SkView::handleInval(const SkRect& r) { 460 return false; 461 } 462 463 ////////////////////////////////////////////////////////////////////// 464 465 void SkView::getLocalBounds(SkRect* bounds) const 466 { 467 if (bounds) 468 bounds->set(0, 0, fWidth, fHeight); 469 } 470 471 ////////////////////////////////////////////////////////////////////// 472 ////////////////////////////////////////////////////////////////////// 473 474 void SkView::detachFromParent_NoLayout() 475 { 476 if (fParent == NULL) 477 return; 478 479 if (fContainsFocus) 480 (void)this->setFocusView(NULL); 481 482 this->inval(NULL); 483 484 SkView* next = NULL; 485 486 if (fNextSibling != this) // do we have any siblings 487 { 488 fNextSibling->fPrevSibling = fPrevSibling; 489 fPrevSibling->fNextSibling = fNextSibling; 490 next = fNextSibling; 491 } 492 493 if (fParent->fFirstChild == this) 494 fParent->fFirstChild = next; 495 496 fParent = fNextSibling = fPrevSibling = NULL; 497 498 this->unref(); 499 } 500 501 void SkView::detachFromParent() 502 { 503 SkView* parent = fParent; 504 505 if (parent) 506 { 507 this->detachFromParent_NoLayout(); 508 parent->invokeLayout(); 509 } 510 } 511 512 SkView* SkView::attachChildToBack(SkView* child) 513 { 514 SkASSERT(child != this); 515 516 if (child == NULL || fFirstChild == child) 517 goto DONE; 518 519 child->ref(); 520 child->detachFromParent_NoLayout(); 521 522 if (fFirstChild == NULL) 523 { 524 child->fNextSibling = child; 525 child->fPrevSibling = child; 526 } 527 else 528 { 529 child->fNextSibling = fFirstChild; 530 child->fPrevSibling = fFirstChild->fPrevSibling; 531 fFirstChild->fPrevSibling->fNextSibling = child; 532 fFirstChild->fPrevSibling = child; 533 } 534 535 fFirstChild = child; 536 child->fParent = this; 537 child->inval(NULL); 538 539 this->invokeLayout(); 540 DONE: 541 return child; 542 } 543 544 SkView* SkView::attachChildToFront(SkView* child) 545 { 546 SkASSERT(child != this); 547 548 if (child == NULL || fFirstChild && fFirstChild->fPrevSibling == child) 549 goto DONE; 550 551 child->ref(); 552 child->detachFromParent_NoLayout(); 553 554 if (fFirstChild == NULL) 555 { 556 fFirstChild = child; 557 child->fNextSibling = child; 558 child->fPrevSibling = child; 559 } 560 else 561 { 562 child->fNextSibling = fFirstChild; 563 child->fPrevSibling = fFirstChild->fPrevSibling; 564 fFirstChild->fPrevSibling->fNextSibling = child; 565 fFirstChild->fPrevSibling = child; 566 } 567 568 child->fParent = this; 569 child->inval(NULL); 570 571 this->invokeLayout(); 572 DONE: 573 return child; 574 } 575 576 void SkView::detachAllChildren() 577 { 578 while (fFirstChild) 579 fFirstChild->detachFromParent_NoLayout(); 580 } 581 582 void SkView::globalToLocal(SkScalar x, SkScalar y, SkPoint* local) const 583 { 584 SkASSERT(this); 585 586 if (local) 587 { 588 const SkView* view = this; 589 while (view) 590 { 591 x -= view->fLoc.fX; 592 y -= view->fLoc.fY; 593 view = view->fParent; 594 } 595 local->set(x, y); 596 } 597 } 598 599 ////////////////////////////////////////////////////////////////// 600 601 /* Even if the subclass overrides onInflate, they should always be 602 sure to call the inherited method, so that we get called. 603 */ 604 void SkView::onInflate(const SkDOM& dom, const SkDOM::Node* node) 605 { 606 SkScalar x, y; 607 608 x = this->locX(); 609 y = this->locY(); 610 (void)dom.findScalar(node, "x", &x); 611 (void)dom.findScalar(node, "y", &y); 612 this->setLoc(x, y); 613 614 x = this->width(); 615 y = this->height(); 616 (void)dom.findScalar(node, "width", &x); 617 (void)dom.findScalar(node, "height", &y); 618 this->setSize(x, y); 619 620 // inflate the flags 621 622 static const char* gFlagNames[] = { 623 "visible", "enabled", "focusable", "flexH", "flexV" 624 }; 625 SkASSERT(SK_ARRAY_COUNT(gFlagNames) == kFlagShiftCount); 626 627 bool b; 628 uint32_t flags = this->getFlags(); 629 for (unsigned i = 0; i < SK_ARRAY_COUNT(gFlagNames); i++) 630 if (dom.findBool(node, gFlagNames[i], &b)) 631 flags = SkSetClearShift(flags, b, i); 632 this->setFlags(flags); 633 } 634 635 void SkView::inflate(const SkDOM& dom, const SkDOM::Node* node) 636 { 637 this->onInflate(dom, node); 638 } 639 640 void SkView::onPostInflate(const SkTDict<SkView*>&) 641 { 642 // override in subclass as needed 643 } 644 645 void SkView::postInflate(const SkTDict<SkView*>& dict) 646 { 647 this->onPostInflate(dict); 648 649 B2FIter iter(this); 650 SkView* child; 651 while ((child = iter.next()) != NULL) 652 child->postInflate(dict); 653 } 654 655 ////////////////////////////////////////////////////////////////// 656 657 SkView* SkView::sendEventToParents(const SkEvent& evt) 658 { 659 SkView* parent = fParent; 660 661 while (parent) 662 { 663 if (parent->doEvent(evt)) 664 return parent; 665 parent = parent->fParent; 666 } 667 return NULL; 668 } 669 670 SkView* SkView::sendQueryToParents(SkEvent* evt) { 671 SkView* parent = fParent; 672 673 while (parent) { 674 if (parent->doQuery(evt)) { 675 return parent; 676 } 677 parent = parent->fParent; 678 } 679 return NULL; 680 } 681 682 ////////////////////////////////////////////////////////////////// 683 ////////////////////////////////////////////////////////////////// 684 685 SkView::F2BIter::F2BIter(const SkView* parent) 686 { 687 fFirstChild = parent ? parent->fFirstChild : NULL; 688 fChild = fFirstChild ? fFirstChild->fPrevSibling : NULL; 689 } 690 691 SkView* SkView::F2BIter::next() 692 { 693 SkView* curr = fChild; 694 695 if (fChild) 696 { 697 if (fChild == fFirstChild) 698 fChild = NULL; 699 else 700 fChild = fChild->fPrevSibling; 701 } 702 return curr; 703 } 704 705 SkView::B2FIter::B2FIter(const SkView* parent) 706 { 707 fFirstChild = parent ? parent->fFirstChild : NULL; 708 fChild = fFirstChild; 709 } 710 711 SkView* SkView::B2FIter::next() 712 { 713 SkView* curr = fChild; 714 715 if (fChild) 716 { 717 SkView* next = fChild->fNextSibling; 718 if (next == fFirstChild) 719 next = NULL; 720 fChild = next; 721 } 722 return curr; 723 } 724 725 ////////////////////////////////////////////////////////////////// 726 ////////////////////////////////////////////////////////////////// 727 728 #ifdef SK_DEBUG 729 730 static inline void show_if_nonzero(const char name[], SkScalar value) 731 { 732 if (value) 733 SkDebugf("%s=\"%g\"", name, value/65536.); 734 } 735 736 static void tab(int level) 737 { 738 for (int i = 0; i < level; i++) 739 SkDebugf(" "); 740 } 741 742 static void dumpview(const SkView* view, int level, bool recurse) 743 { 744 tab(level); 745 746 SkDebugf("<view"); 747 show_if_nonzero(" x", view->locX()); 748 show_if_nonzero(" y", view->locY()); 749 show_if_nonzero(" width", view->width()); 750 show_if_nonzero(" height", view->height()); 751 752 if (recurse) 753 { 754 SkView::B2FIter iter(view); 755 SkView* child; 756 bool noChildren = true; 757 758 while ((child = iter.next()) != NULL) 759 { 760 if (noChildren) 761 SkDebugf(">\n"); 762 noChildren = false; 763 dumpview(child, level + 1, true); 764 } 765 766 if (!noChildren) 767 { 768 tab(level); 769 SkDebugf("</view>\n"); 770 } 771 else 772 goto ONELINER; 773 } 774 else 775 { 776 ONELINER: 777 SkDebugf(" />\n"); 778 } 779 } 780 781 void SkView::dump(bool recurse) const 782 { 783 dumpview(this, 0, recurse); 784 } 785 786 #endif 787