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