3 * Copyright 2011 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
11 SK_DEFINE_INST_COUNT(SkView::Artist)
12 SK_DEFINE_INST_COUNT(SkView::Layout)
14 ////////////////////////////////////////////////////////////////////////
16 SkView::SkView(uint32_t flags) : fFlags(SkToU8(flags))
20 fParent = fFirstChild = fNextSibling = fPrevSibling = NULL;
21 fMatrix.setIdentity();
27 this->detachAllChildren();
30 void SkView::setFlags(uint32_t flags)
32 SkASSERT((flags & ~kAllFlagMasks) == 0);
34 uint32_t diff = fFlags ^ flags;
36 if (diff & kVisible_Mask)
39 fFlags = SkToU8(flags);
41 if (diff & kVisible_Mask)
47 void SkView::setVisibleP(bool pred)
49 this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift));
52 void SkView::setEnabledP(bool pred)
54 this->setFlags(SkSetClearShift(fFlags, pred, kEnabled_Shift));
57 void SkView::setFocusableP(bool pred)
59 this->setFlags(SkSetClearShift(fFlags, pred, kFocusable_Shift));
62 void SkView::setClipToBounds(bool pred) {
63 this->setFlags(SkSetClearShift(fFlags, !pred, kNoClip_Shift));
66 void SkView::setSize(SkScalar width, SkScalar height)
68 width = SkMaxScalar(0, width);
69 height = SkMaxScalar(0, height);
71 if (fWidth != width || fHeight != height)
82 void SkView::setLoc(SkScalar x, SkScalar y)
84 if (fLoc.fX != x || fLoc.fY != y)
92 void SkView::offset(SkScalar dx, SkScalar dy)
95 this->setLoc(fLoc.fX + dx, fLoc.fY + dy);
98 void SkView::setLocalMatrix(const SkMatrix& matrix)
105 void SkView::draw(SkCanvas* canvas)
107 if (fWidth && fHeight && this->isVisible())
110 r.set(fLoc.fX, fLoc.fY, fLoc.fX + fWidth, fLoc.fY + fHeight);
111 if (this->isClipToBounds() &&
112 canvas->quickReject(r)) {
116 SkAutoCanvasRestore as(canvas, true);
118 if (this->isClipToBounds()) {
122 canvas->translate(fLoc.fX, fLoc.fY);
123 canvas->concat(fMatrix);
126 fParent->beforeChild(this, canvas);
129 int sc = canvas->save();
130 this->onDraw(canvas);
131 canvas->restoreToCount(sc);
134 fParent->afterChild(this, canvas);
140 SkCanvas* childCanvas = this->beforeChildren(canvas);
142 while ((child = iter.next()) != NULL)
143 child->draw(childCanvas);
145 this->afterChildren(canvas);
149 void SkView::inval(SkRect* rect) {
154 if (!view->isVisible()) {
157 if (view->isClipToBounds()) {
159 view->getLocalBounds(&bounds);
160 if (rect && !bounds.intersect(*rect)) {
166 if (view->handleInval(rect)) {
170 SkView* parent = view->fParent;
171 if (parent == NULL) {
176 rect->offset(view->fLoc.fX, view->fLoc.fY);
182 ////////////////////////////////////////////////////////////////////////////
184 bool SkView::setFocusView(SkView* fv)
189 if (view->onSetFocusView(fv))
191 } while ((view = view->fParent) != NULL);
195 SkView* SkView::getFocusView() const
197 SkView* focus = NULL;
198 const SkView* view = this;
200 if (view->onGetFocusView(&focus))
202 } while ((view = view->fParent) != NULL);
206 bool SkView::hasFocus() const
208 return this == this->getFocusView();
211 bool SkView::acceptFocus()
213 return this->isFocusable() && this->setFocusView(this);
217 Try to give focus to this view, or its children
219 SkView* SkView::acceptFocus(FocusDirection dir)
221 if (dir == kNext_FocusDirection)
223 if (this->acceptFocus())
227 SkView* child, *focus;
228 while ((child = iter.next()) != NULL)
229 if ((focus = child->acceptFocus(dir)) != NULL)
235 SkView* child, *focus;
236 while ((child = iter.next()) != NULL)
237 if ((focus = child->acceptFocus(dir)) != NULL)
240 if (this->acceptFocus())
247 SkView* SkView::moveFocus(FocusDirection dir)
249 SkView* focus = this->getFocusView();
252 { // start with the root
254 while (focus->fParent)
255 focus = focus->fParent;
258 SkView* child, *parent;
260 if (dir == kNext_FocusDirection)
263 child = focus->fFirstChild;
270 while (child != parent->fFirstChild)
273 if ((focus = child->acceptFocus(dir)) != NULL)
275 child = child->fNextSibling;
278 child = parent->fNextSibling;
279 parent = parent->fParent;
280 } while (parent != NULL);
284 parent = focus->fParent;
285 if (parent == NULL) // we're the root
286 return focus->acceptFocus(dir);
292 while (child != parent->fFirstChild)
294 child = child->fPrevSibling;
295 if ((focus = child->acceptFocus(dir)) != NULL)
298 if (parent->acceptFocus())
302 parent = parent->fParent;
309 void SkView::onFocusChange(bool gainFocusP)
314 ////////////////////////////////////////////////////////////////////////////
316 SkView::Click::Click(SkView* target)
319 fTargetID = target->getSinkID();
321 fWeOwnTheType = false;
325 SkView::Click::~Click()
330 void SkView::Click::resetType()
335 fWeOwnTheType = false;
340 bool SkView::Click::isType(const char type[]) const
342 const char* t = fType;
351 return !strcmp(t, type);
354 void SkView::Click::setType(const char type[])
360 void SkView::Click::copyType(const char type[])
367 size_t len = strlen(type) + 1;
368 fType = (char*)sk_malloc_throw(len);
369 memcpy(fType, type, len);
370 fWeOwnTheType = true;
375 SkView::Click* SkView::findClickHandler(SkScalar x, SkScalar y, unsigned modi) {
376 if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) {
380 if (this->onSendClickToChildren(x, y, modi)) {
384 while ((child = iter.next()) != NULL)
387 if (!child->globalToLocal(x, y, &p)) {
391 Click* click = child->findClickHandler(p.fX, p.fY, modi);
399 return this->onFindClickHandler(x, y, modi);
402 void SkView::DoClickDown(Click* click, int x, int y, unsigned modi)
406 SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
407 if (NULL == target) {
411 click->fIOrig.set(x, y);
412 click->fICurr = click->fIPrev = click->fIOrig;
414 click->fOrig.iset(x, y);
415 if (!target->globalToLocal(&click->fOrig)) {
416 // no history to let us recover from this failure
419 click->fPrev = click->fCurr = click->fOrig;
421 click->fState = Click::kDown_State;
422 click->fModifierKeys = modi;
423 target->onClick(click);
426 void SkView::DoClickMoved(Click* click, int x, int y, unsigned modi)
430 SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
431 if (NULL == target) {
435 click->fIPrev = click->fICurr;
436 click->fICurr.set(x, y);
438 click->fPrev = click->fCurr;
439 click->fCurr.iset(x, y);
440 if (!target->globalToLocal(&click->fCurr)) {
441 // on failure pretend the mouse didn't move
442 click->fCurr = click->fPrev;
445 click->fState = Click::kMoved_State;
446 click->fModifierKeys = modi;
447 target->onClick(click);
450 void SkView::DoClickUp(Click* click, int x, int y, unsigned modi)
454 SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
455 if (NULL == target) {
459 click->fIPrev = click->fICurr;
460 click->fICurr.set(x, y);
462 click->fPrev = click->fCurr;
463 click->fCurr.iset(x, y);
464 if (!target->globalToLocal(&click->fCurr)) {
465 // on failure pretend the mouse didn't move
466 click->fCurr = click->fPrev;
469 click->fState = Click::kUp_State;
470 click->fModifierKeys = modi;
471 target->onClick(click);
474 //////////////////////////////////////////////////////////////////////
476 void SkView::invokeLayout() {
477 SkView::Layout* layout = this->getLayout();
480 layout->layoutChildren(this);
484 void SkView::onDraw(SkCanvas* canvas) {
485 Artist* artist = this->getArtist();
488 artist->draw(this, canvas);
492 void SkView::onSizeChange() {}
494 bool SkView::onSendClickToChildren(SkScalar x, SkScalar y, unsigned modi) {
498 SkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
502 bool SkView::onClick(Click*) {
506 bool SkView::handleInval(const SkRect*) {
510 //////////////////////////////////////////////////////////////////////
512 void SkView::getLocalBounds(SkRect* bounds) const {
514 bounds->set(0, 0, fWidth, fHeight);
518 //////////////////////////////////////////////////////////////////////
519 //////////////////////////////////////////////////////////////////////
521 void SkView::detachFromParent_NoLayout() {
523 if (fParent == NULL) {
527 if (fContainsFocus) {
528 (void)this->setFocusView(NULL);
535 if (fNextSibling != this) { // do we have any siblings
536 fNextSibling->fPrevSibling = fPrevSibling;
537 fPrevSibling->fNextSibling = fNextSibling;
541 if (fParent->fFirstChild == this) {
542 fParent->fFirstChild = next;
545 fParent = fNextSibling = fPrevSibling = NULL;
551 void SkView::detachFromParent() {
553 SkView* parent = fParent;
556 this->detachFromParent_NoLayout();
557 parent->invokeLayout();
561 SkView* SkView::attachChildToBack(SkView* child) {
563 SkASSERT(child != this);
565 if (child == NULL || fFirstChild == child)
569 child->detachFromParent_NoLayout();
571 if (fFirstChild == NULL) {
572 child->fNextSibling = child;
573 child->fPrevSibling = child;
575 child->fNextSibling = fFirstChild;
576 child->fPrevSibling = fFirstChild->fPrevSibling;
577 fFirstChild->fPrevSibling->fNextSibling = child;
578 fFirstChild->fPrevSibling = child;
582 child->fParent = this;
586 this->invokeLayout();
591 SkView* SkView::attachChildToFront(SkView* child) {
593 SkASSERT(child != this);
595 if (child == NULL || (fFirstChild && fFirstChild->fPrevSibling == child))
599 child->detachFromParent_NoLayout();
601 if (fFirstChild == NULL) {
603 child->fNextSibling = child;
604 child->fPrevSibling = child;
606 child->fNextSibling = fFirstChild;
607 child->fPrevSibling = fFirstChild->fPrevSibling;
608 fFirstChild->fPrevSibling->fNextSibling = child;
609 fFirstChild->fPrevSibling = child;
612 child->fParent = this;
616 this->invokeLayout();
621 void SkView::detachAllChildren() {
624 fFirstChild->detachFromParent_NoLayout();
627 void SkView::localToGlobal(SkMatrix* matrix) const {
630 const SkView* view = this;
633 matrix->preConcat(view->getLocalMatrix());
634 matrix->preTranslate(-view->fLoc.fX, -view->fLoc.fY);
635 view = view->fParent;
639 bool SkView::globalToLocal(SkScalar x, SkScalar y, SkPoint* local) const
645 this->localToGlobal(&m);
651 local->set(p.fX, p.fY);
657 //////////////////////////////////////////////////////////////////
659 /* Even if the subclass overrides onInflate, they should always be
660 sure to call the inherited method, so that we get called.
662 void SkView::onInflate(const SkDOM& dom, const SkDOM::Node* node) {
667 (void)dom.findScalar(node, "x", &x);
668 (void)dom.findScalar(node, "y", &y);
673 (void)dom.findScalar(node, "width", &x);
674 (void)dom.findScalar(node, "height", &y);
679 static const char* gFlagNames[] = {
680 "visible", "enabled", "focusable", "flexH", "flexV"
682 SkASSERT(SK_ARRAY_COUNT(gFlagNames) == kFlagShiftCount);
685 uint32_t flags = this->getFlags();
686 for (unsigned i = 0; i < SK_ARRAY_COUNT(gFlagNames); i++)
687 if (dom.findBool(node, gFlagNames[i], &b))
688 flags = SkSetClearShift(flags, b, i);
689 this->setFlags(flags);
692 void SkView::inflate(const SkDOM& dom, const SkDOM::Node* node) {
693 this->onInflate(dom, node);
696 void SkView::onPostInflate(const SkTDict<SkView*>&) {
697 // override in subclass as needed
700 void SkView::postInflate(const SkTDict<SkView*>& dict) {
701 this->onPostInflate(dict);
705 while ((child = iter.next()) != NULL)
706 child->postInflate(dict);
709 //////////////////////////////////////////////////////////////////
711 SkView* SkView::sendEventToParents(const SkEvent& evt) {
712 SkView* parent = fParent;
715 if (parent->doEvent(evt)) {
718 parent = parent->fParent;
723 SkView* SkView::sendQueryToParents(SkEvent* evt) {
724 SkView* parent = fParent;
727 if (parent->doQuery(evt)) {
730 parent = parent->fParent;
735 //////////////////////////////////////////////////////////////////
736 //////////////////////////////////////////////////////////////////
738 SkView::F2BIter::F2BIter(const SkView* parent) {
739 fFirstChild = parent ? parent->fFirstChild : NULL;
740 fChild = fFirstChild ? fFirstChild->fPrevSibling : NULL;
743 SkView* SkView::F2BIter::next() {
744 SkView* curr = fChild;
747 if (fChild == fFirstChild) {
750 fChild = fChild->fPrevSibling;
756 SkView::B2FIter::B2FIter(const SkView* parent) {
757 fFirstChild = parent ? parent->fFirstChild : NULL;
758 fChild = fFirstChild;
761 SkView* SkView::B2FIter::next() {
762 SkView* curr = fChild;
765 SkView* next = fChild->fNextSibling;
766 if (next == fFirstChild)
773 //////////////////////////////////////////////////////////////////
774 //////////////////////////////////////////////////////////////////
778 void SkView::validate() const {
779 // SkASSERT(this->getRefCnt() > 0 && this->getRefCnt() < 100);
781 SkASSERT(fNextSibling);
782 SkASSERT(fPrevSibling);
784 bool nextNull = NULL == fNextSibling;
785 bool prevNull = NULL == fNextSibling;
786 SkASSERT(nextNull == prevNull);
790 static inline void show_if_nonzero(const char name[], SkScalar value)
793 SkDebugf("%s=\"%g\"", name, value/65536.);
796 static void tab(int level)
798 for (int i = 0; i < level; i++)
802 static void dumpview(const SkView* view, int level, bool recurse)
807 show_if_nonzero(" x", view->locX());
808 show_if_nonzero(" y", view->locY());
809 show_if_nonzero(" width", view->width());
810 show_if_nonzero(" height", view->height());
814 SkView::B2FIter iter(view);
816 bool noChildren = true;
818 while ((child = iter.next()) != NULL)
823 dumpview(child, level + 1, true);
829 SkDebugf("</view>\n");
841 void SkView::dump(bool recurse) const
843 dumpview(this, 0, recurse);