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