• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SkView.h"
2 #include "SkCanvas.h"
3 
4 ////////////////////////////////////////////////////////////////////////
5 
SkView(uint32_t flags)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 
~SkView()15 SkView::~SkView()
16 {
17 	this->detachAllChildren();
18 }
19 
setFlags(uint32_t flags)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 
setVisibleP(bool pred)37 void SkView::setVisibleP(bool pred)
38 {
39 	this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift));
40 }
41 
setEnabledP(bool pred)42 void SkView::setEnabledP(bool pred)
43 {
44 	this->setFlags(SkSetClearShift(fFlags, pred, kEnabled_Shift));
45 }
46 
setFocusableP(bool pred)47 void SkView::setFocusableP(bool pred)
48 {
49 	this->setFlags(SkSetClearShift(fFlags, pred, kFocusable_Shift));
50 }
51 
setSize(SkScalar width,SkScalar height)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 
setLoc(SkScalar x,SkScalar y)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 
offset(SkScalar dx,SkScalar dy)78 void SkView::offset(SkScalar dx, SkScalar dy)
79 {
80 	if (dx || dy)
81 		this->setLoc(fLoc.fX + dx, fLoc.fY + dy);
82 }
83 
draw(SkCanvas * canvas)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 
inval(SkRect * rect)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 
setFocusView(SkView * fv)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 
getFocusView() const169 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 
hasFocus() const180 bool SkView::hasFocus() const
181 {
182 	return this == this->getFocusView();
183 }
184 
acceptFocus()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 */
acceptFocus(FocusDirection dir)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 
moveFocus(FocusDirection dir)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 
onFocusChange(bool gainFocusP)283 void SkView::onFocusChange(bool gainFocusP)
284 {
285 	this->inval(NULL);
286 }
287 
288 ////////////////////////////////////////////////////////////////////////////
289 
Click(SkView * target)290 SkView::Click::Click(SkView* target)
291 {
292 	SkASSERT(target);
293 	fTargetID = target->getSinkID();
294 	fType = NULL;
295 	fWeOwnTheType = false;
296 }
297 
~Click()298 SkView::Click::~Click()
299 {
300 	this->resetType();
301 }
302 
resetType()303 void SkView::Click::resetType()
304 {
305 	if (fWeOwnTheType)
306 	{
307 		sk_free(fType);
308 		fWeOwnTheType = false;
309 	}
310 	fType = NULL;
311 }
312 
isType(const char type[]) const313 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 
setType(const char type[])327 void SkView::Click::setType(const char type[])
328 {
329 	this->resetType();
330 	fType = (char*)type;
331 }
332 
copyType(const char type[])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 
findClickHandler(SkScalar x,SkScalar y)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 
DoClickDown(Click * click,int x,int y)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 
DoClickMoved(Click * click,int x,int y)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 
DoClickUp(Click * click,int x,int y)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 
invokeLayout()429 void SkView::invokeLayout() {
430 	SkView::Layout* layout = this->getLayout();
431 
432 	if (layout) {
433 		layout->layoutChildren(this);
434     }
435 }
436 
onDraw(SkCanvas * canvas)437 void SkView::onDraw(SkCanvas* canvas) {
438 	Artist* artist = this->getArtist();
439 
440 	if (artist) {
441 		artist->draw(this, canvas);
442     }
443 }
444 
onSizeChange()445 void SkView::onSizeChange() {}
446 
onSendClickToChildren(SkScalar x,SkScalar y)447 bool SkView::onSendClickToChildren(SkScalar x, SkScalar y) {
448     return true;
449 }
450 
onFindClickHandler(SkScalar x,SkScalar y)451 SkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y) {
452 	return NULL;
453 }
454 
onClick(Click *)455 bool SkView::onClick(Click*) {
456 	return false;
457 }
458 
handleInval(const SkRect & r)459 bool SkView::handleInval(const SkRect& r) {
460 	return false;
461 }
462 
463 //////////////////////////////////////////////////////////////////////
464 
getLocalBounds(SkRect * bounds) const465 void SkView::getLocalBounds(SkRect* bounds) const
466 {
467 	if (bounds)
468 		bounds->set(0, 0, fWidth, fHeight);
469 }
470 
471 //////////////////////////////////////////////////////////////////////
472 //////////////////////////////////////////////////////////////////////
473 
detachFromParent_NoLayout()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 
detachFromParent()501 void SkView::detachFromParent()
502 {
503 	SkView* parent = fParent;
504 
505 	if (parent)
506 	{
507 		this->detachFromParent_NoLayout();
508 		parent->invokeLayout();
509 	}
510 }
511 
attachChildToBack(SkView * child)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 
attachChildToFront(SkView * child)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 
detachAllChildren()576 void SkView::detachAllChildren()
577 {
578 	while (fFirstChild)
579 		fFirstChild->detachFromParent_NoLayout();
580 }
581 
globalToLocal(SkScalar x,SkScalar y,SkPoint * local) const582 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 */
onInflate(const SkDOM & dom,const SkDOM::Node * node)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 
inflate(const SkDOM & dom,const SkDOM::Node * node)635 void SkView::inflate(const SkDOM& dom, const SkDOM::Node* node)
636 {
637 	this->onInflate(dom, node);
638 }
639 
onPostInflate(const SkTDict<SkView * > &)640 void SkView::onPostInflate(const SkTDict<SkView*>&)
641 {
642 	// override in subclass as needed
643 }
644 
postInflate(const SkTDict<SkView * > & dict)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 
sendEventToParents(const SkEvent & evt)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 
sendQueryToParents(SkEvent * evt)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 
F2BIter(const SkView * parent)685 SkView::F2BIter::F2BIter(const SkView* parent)
686 {
687 	fFirstChild = parent ? parent->fFirstChild : NULL;
688 	fChild = fFirstChild ? fFirstChild->fPrevSibling : NULL;
689 }
690 
next()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 
B2FIter(const SkView * parent)705 SkView::B2FIter::B2FIter(const SkView* parent)
706 {
707 	fFirstChild = parent ? parent->fFirstChild : NULL;
708 	fChild = fFirstChild;
709 }
710 
next()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 
show_if_nonzero(const char name[],SkScalar value)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 
tab(int level)736 static void tab(int level)
737 {
738 	for (int i = 0; i < level; i++)
739 		SkDebugf("    ");
740 }
741 
dumpview(const SkView * view,int level,bool recurse)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 
dump(bool recurse) const781 void SkView::dump(bool recurse) const
782 {
783 	dumpview(this, 0, recurse);
784 }
785 
786 #endif
787