1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
79a878a00ef2c2eb72628c807be5969e2d8098317reed
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
1020de615e3d02ff52c9a3c319ce35bcaace97be25Hal Canary#include "SkDOM.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
129a878a00ef2c2eb72628c807be5969e2d8098317reedstatic inline uint32_t SkSetClearShift(uint32_t bits, bool cond, unsigned shift) {
139a878a00ef2c2eb72628c807be5969e2d8098317reed    SkASSERT((int)cond == 0 || (int)cond == 1);
149a878a00ef2c2eb72628c807be5969e2d8098317reed    return (bits & ~(1 << shift)) | ((int)cond << shift);
159a878a00ef2c2eb72628c807be5969e2d8098317reed}
169a878a00ef2c2eb72628c807be5969e2d8098317reed
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
199a878a00ef2c2eb72628c807be5969e2d8098317reedSkView::SkView(uint32_t flags) : fFlags(SkToU8(flags)) {
20a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fWidth = fHeight = 0;
21a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fLoc.set(0, 0);
2296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fParent = fFirstChild = fNextSibling = fPrevSibling = nullptr;
23f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    fMatrix.setIdentity();
24a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fContainsFocus = 0;
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
279a878a00ef2c2eb72628c807be5969e2d8098317reedSkView::~SkView() {
28a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->detachAllChildren();
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
319a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::setFlags(uint32_t flags) {
32a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkASSERT((flags & ~kAllFlagMasks) == 0);
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
34a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    uint32_t diff = fFlags ^ flags;
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
36a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (diff & kVisible_Mask)
3796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        this->inval(nullptr);
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
39a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fFlags = SkToU8(flags);
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
419a878a00ef2c2eb72628c807be5969e2d8098317reed    if (diff & kVisible_Mask) {
4296fcdcc219d2a0d3579719b84b28bede76efba64halcanary        this->inval(nullptr);
43a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
469a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::setVisibleP(bool pred) {
47a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift));
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
509a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::setEnabledP(bool pred) {
51a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setFlags(SkSetClearShift(fFlags, pred, kEnabled_Shift));
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
549a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::setFocusableP(bool pred) {
55a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setFlags(SkSetClearShift(fFlags, pred, kFocusable_Shift));
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
58f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comvoid SkView::setClipToBounds(bool pred) {
59f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    this->setFlags(SkSetClearShift(fFlags, !pred, kNoClip_Shift));
60f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
61f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
629a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::setSize(SkScalar width, SkScalar height) {
63a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    width = SkMaxScalar(0, width);
64a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    height = SkMaxScalar(0, height);
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
66a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (fWidth != width || fHeight != height)
67a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
6896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        this->inval(nullptr);
69a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fWidth = width;
70a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fHeight = height;
7196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        this->inval(nullptr);
72a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->onSizeChange();
73a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->invokeLayout();
74a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
779a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::setLoc(SkScalar x, SkScalar y) {
789a878a00ef2c2eb72628c807be5969e2d8098317reed    if (fLoc.fX != x || fLoc.fY != y) {
7996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        this->inval(nullptr);
80a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fLoc.set(x, y);
8196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        this->inval(nullptr);
82a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
859a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::offset(SkScalar dx, SkScalar dy) {
86a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (dx || dy)
87a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->setLoc(fLoc.fX + dx, fLoc.fY + dy);
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
909a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::setLocalMatrix(const SkMatrix& matrix) {
9196fcdcc219d2a0d3579719b84b28bede76efba64halcanary    this->inval(nullptr);
92f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    fMatrix = matrix;
9396fcdcc219d2a0d3579719b84b28bede76efba64halcanary    this->inval(nullptr);
94f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com}
95f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com
969a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::draw(SkCanvas* canvas) {
979a878a00ef2c2eb72628c807be5969e2d8098317reed    if (fWidth && fHeight && this->isVisible()) {
98d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkRect    r;
99a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        r.set(fLoc.fX, fLoc.fY, fLoc.fX + fWidth, fLoc.fY + fHeight);
1009a878a00ef2c2eb72628c807be5969e2d8098317reed        if (this->isClipToBounds() && canvas->quickReject(r)) {
1019a878a00ef2c2eb72628c807be5969e2d8098317reed            return;
102f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
104d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkAutoCanvasRestore    as(canvas, true);
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
106f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (this->isClipToBounds()) {
107f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            canvas->clipRect(r);
108f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
109d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
110d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        canvas->translate(fLoc.fX, fLoc.fY);
111f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        canvas->concat(fMatrix);
112d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1136c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        if (fParent) {
1146c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            fParent->beforeChild(this, canvas);
1156c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        }
116562ea92179edb35303bd7b3dd6272a5f4eae47ffreed@android.com
117562ea92179edb35303bd7b3dd6272a5f4eae47ffreed@android.com        int sc = canvas->save();
118a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->onDraw(canvas);
119562ea92179edb35303bd7b3dd6272a5f4eae47ffreed@android.com        canvas->restoreToCount(sc);
120562ea92179edb35303bd7b3dd6272a5f4eae47ffreed@android.com
1216c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        if (fParent) {
1226c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            fParent->afterChild(this, canvas);
1236c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        }
124d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
125d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        B2FIter    iter(this);
126d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView*    child;
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkCanvas* childCanvas = this->beforeChildren(canvas);
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
13096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        while ((child = iter.next()) != nullptr)
131a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            child->draw(childCanvas);
132d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->afterChildren(canvas);
134a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
137f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comvoid SkView::inval(SkRect* rect) {
138d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView*    view = this;
139f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkRect storage;
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
141a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    for (;;) {
142f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (!view->isVisible()) {
143f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            return;
144f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
145f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view->isClipToBounds()) {
146f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkRect bounds;
147f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            view->getLocalBounds(&bounds);
148f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (rect && !bounds.intersect(*rect)) {
149f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                return;
150f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
151f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            storage = bounds;
152f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            rect = &storage;
153f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
154f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view->handleInval(rect)) {
155f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            return;
156f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
158a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SkView* parent = view->fParent;
15996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (parent == nullptr) {
160f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            return;
161f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
163f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (rect) {
164f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            rect->offset(view->fLoc.fX, view->fLoc.fY);
165f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
166f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        view = parent;
167a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1729a878a00ef2c2eb72628c807be5969e2d8098317reedbool SkView::setFocusView(SkView* fv) {
173a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* view = this;
174d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
175a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    do {
1769a878a00ef2c2eb72628c807be5969e2d8098317reed        if (view->onSetFocusView(fv)) {
177a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return true;
1789a878a00ef2c2eb72628c807be5969e2d8098317reed        }
17996fcdcc219d2a0d3579719b84b28bede76efba64halcanary    } while ((view = view->fParent) != nullptr);
180a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return false;
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1839a878a00ef2c2eb72628c807be5969e2d8098317reedSkView* SkView::getFocusView() const {
1849a878a00ef2c2eb72628c807be5969e2d8098317reed    SkView*         focus = nullptr;
1859a878a00ef2c2eb72628c807be5969e2d8098317reed    const SkView*   view = this;
186a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    do {
1879a878a00ef2c2eb72628c807be5969e2d8098317reed        if (view->onGetFocusView(&focus)) {
188a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            break;
1899a878a00ef2c2eb72628c807be5969e2d8098317reed        }
19096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    } while ((view = view->fParent) != nullptr);
191a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return focus;
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1949a878a00ef2c2eb72628c807be5969e2d8098317reedbool SkView::hasFocus() const {
195a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return this == this->getFocusView();
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1989a878a00ef2c2eb72628c807be5969e2d8098317reedbool SkView::acceptFocus() {
199a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return this->isFocusable() && this->setFocusView(this);
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
203a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    Try to give focus to this view, or its children
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
2059a878a00ef2c2eb72628c807be5969e2d8098317reedSkView* SkView::acceptFocus(FocusDirection dir) {
2069a878a00ef2c2eb72628c807be5969e2d8098317reed    if (dir == kNext_FocusDirection) {
2079a878a00ef2c2eb72628c807be5969e2d8098317reed        if (this->acceptFocus()) {
208a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return this;
2099a878a00ef2c2eb72628c807be5969e2d8098317reed        }
210d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        B2FIter    iter(this);
211d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView*    child, *focus;
2129a878a00ef2c2eb72628c807be5969e2d8098317reed        while ((child = iter.next()) != nullptr) {
2139a878a00ef2c2eb72628c807be5969e2d8098317reed            if ((focus = child->acceptFocus(dir)) != nullptr) {
214a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                return focus;
2159a878a00ef2c2eb72628c807be5969e2d8098317reed            }
2169a878a00ef2c2eb72628c807be5969e2d8098317reed        }
2179a878a00ef2c2eb72628c807be5969e2d8098317reed    } else { // prev
218d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        F2BIter    iter(this);
219d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView*    child, *focus;
2209a878a00ef2c2eb72628c807be5969e2d8098317reed        while ((child = iter.next()) != nullptr) {
2219a878a00ef2c2eb72628c807be5969e2d8098317reed            if ((focus = child->acceptFocus(dir)) != nullptr) {
222a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                return focus;
2239a878a00ef2c2eb72628c807be5969e2d8098317reed            }
2249a878a00ef2c2eb72628c807be5969e2d8098317reed        }
2259a878a00ef2c2eb72628c807be5969e2d8098317reed        if (this->acceptFocus()) {
226a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return this;
2279a878a00ef2c2eb72628c807be5969e2d8098317reed        }
228a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
22996fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return nullptr;
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2329a878a00ef2c2eb72628c807be5969e2d8098317reedSkView* SkView::moveFocus(FocusDirection dir) {
233a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* focus = this->getFocusView();
234a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
2359a878a00ef2c2eb72628c807be5969e2d8098317reed    if (focus == nullptr) {    // start with the root
236a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        focus = this;
2379a878a00ef2c2eb72628c807be5969e2d8098317reed        while (focus->fParent) {
238a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            focus = focus->fParent;
2399a878a00ef2c2eb72628c807be5969e2d8098317reed        }
240a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
241a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
2429a878a00ef2c2eb72628c807be5969e2d8098317reed    SkView* child, *parent;
243a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
2449a878a00ef2c2eb72628c807be5969e2d8098317reed    if (dir == kNext_FocusDirection) {
245a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        parent = focus;
246a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child = focus->fFirstChild;
247a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (child)
248a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            goto FIRST_CHILD;
249a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        else
250a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            goto NEXT_SIB;
251a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
252a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        do {
2539a878a00ef2c2eb72628c807be5969e2d8098317reed            while (child != parent->fFirstChild) {
254a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    FIRST_CHILD:
25596fcdcc219d2a0d3579719b84b28bede76efba64halcanary                if ((focus = child->acceptFocus(dir)) != nullptr)
256a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                    return focus;
257a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                child = child->fNextSibling;
258a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            }
259a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    NEXT_SIB:
260a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            child = parent->fNextSibling;
261a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            parent = parent->fParent;
26296fcdcc219d2a0d3579719b84b28bede76efba64halcanary        } while (parent != nullptr);
2639a878a00ef2c2eb72628c807be5969e2d8098317reed    } else {    // prevfocus
264a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        parent = focus->fParent;
2659a878a00ef2c2eb72628c807be5969e2d8098317reed        if (parent == nullptr) {    // we're the root
266a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return focus->acceptFocus(dir);
2679a878a00ef2c2eb72628c807be5969e2d8098317reed        } else {
268a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            child = focus;
2699a878a00ef2c2eb72628c807be5969e2d8098317reed            while (parent) {
2709a878a00ef2c2eb72628c807be5969e2d8098317reed                while (child != parent->fFirstChild) {
271a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                    child = child->fPrevSibling;
2729a878a00ef2c2eb72628c807be5969e2d8098317reed                    if ((focus = child->acceptFocus(dir)) != nullptr) {
273a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                        return focus;
2749a878a00ef2c2eb72628c807be5969e2d8098317reed                    }
275a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                }
2769a878a00ef2c2eb72628c807be5969e2d8098317reed                if (parent->acceptFocus()) {
277a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                    return parent;
2789a878a00ef2c2eb72628c807be5969e2d8098317reed                }
279a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                child = parent;
280a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                parent = parent->fParent;
281a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            }
282a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        }
283a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
28496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return nullptr;
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2879a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::onFocusChange(bool gainFocusP) {
28896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    this->inval(nullptr);
2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////
2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2939a878a00ef2c2eb72628c807be5969e2d8098317reedSkView::Click::Click(SkView* target) {
294d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo    SkASSERT(target);
295d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo    fTargetID = target->getSinkID();
29696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fType = nullptr;
297d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo    fWeOwnTheType = false;
29896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fOwner = nullptr;
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3019a878a00ef2c2eb72628c807be5969e2d8098317reedSkView::Click::~Click() {
302a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->resetType();
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3059a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::Click::resetType() {
3069a878a00ef2c2eb72628c807be5969e2d8098317reed    if (fWeOwnTheType) {
307a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        sk_free(fType);
308a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fWeOwnTheType = false;
309a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
31096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fType = nullptr;
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3139a878a00ef2c2eb72628c807be5969e2d8098317reedbool SkView::Click::isType(const char type[]) const {
314a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    const char* t = fType;
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3169a878a00ef2c2eb72628c807be5969e2d8098317reed    if (type == t) {
317a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        return true;
3189a878a00ef2c2eb72628c807be5969e2d8098317reed    }
3199a878a00ef2c2eb72628c807be5969e2d8098317reed    if (type == nullptr) {
320a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        type = "";
3219a878a00ef2c2eb72628c807be5969e2d8098317reed    }
3229a878a00ef2c2eb72628c807be5969e2d8098317reed    if (t == nullptr) {
323a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        t = "";
3249a878a00ef2c2eb72628c807be5969e2d8098317reed    }
325a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return !strcmp(t, type);
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3289a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::Click::setType(const char type[]) {
329a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->resetType();
330a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fType = (char*)type;
3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3339a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::Click::copyType(const char type[]) {
3349a878a00ef2c2eb72628c807be5969e2d8098317reed    if (fType != type) {
335a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->resetType();
3369a878a00ef2c2eb72628c807be5969e2d8098317reed        if (type) {
3379a878a00ef2c2eb72628c807be5969e2d8098317reed            size_t len = strlen(type) + 1;
338a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            fType = (char*)sk_malloc_throw(len);
339a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            memcpy(fType, type, len);
340a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            fWeOwnTheType = true;
341a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        }
342a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3454d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comSkView::Click* SkView::findClickHandler(SkScalar x, SkScalar y, unsigned modi) {
34607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) {
34796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
348e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    }
349e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com
3504d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    if (this->onSendClickToChildren(x, y, modi)) {
351d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        F2BIter    iter(this);
352d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView*    child;
35307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
3541a9cafff044e5a352c60065e44d64e9d0eb8f92areed        while ((child = iter.next()) != nullptr) {
355f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            SkPoint p;
3561a9cafff044e5a352c60065e44d64e9d0eb8f92areed#if 0
35707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com            if (!child->globalToLocal(x, y, &p)) {
35807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com                continue;
35907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com            }
3601a9cafff044e5a352c60065e44d64e9d0eb8f92areed#else
3611a9cafff044e5a352c60065e44d64e9d0eb8f92areed            // the above seems broken, so just respecting fLoc for now <reed>
3621a9cafff044e5a352c60065e44d64e9d0eb8f92areed            p.set(x - child->fLoc.x(), y - child->fLoc.y());
3631a9cafff044e5a352c60065e44d64e9d0eb8f92areed#endif
36407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
3654d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            Click* click = child->findClickHandler(p.fX, p.fY, modi);
36607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
367e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com            if (click) {
368e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com                return click;
369e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com            }
370e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com        }
371e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    }
37207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
3734d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    return this->onFindClickHandler(x, y, modi);
3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3769a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::DoClickDown(Click* click, int x, int y, unsigned modi) {
37707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkASSERT(click);
3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
37907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
38096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == target) {
38107ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return;
38207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
38407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fIOrig.set(x, y);
38507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fICurr = click->fIPrev = click->fIOrig;
3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
38707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fOrig.iset(x, y);
38807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (!target->globalToLocal(&click->fOrig)) {
38907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        // no history to let us recover from this failure
39007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return;
39107ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
39207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fPrev = click->fCurr = click->fOrig;
3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
39407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fState = Click::kDown_State;
3954d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    click->fModifierKeys = modi;
39607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    target->onClick(click);
3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3999a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::DoClickMoved(Click* click, int x, int y, unsigned modi) {
40007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkASSERT(click);
4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
40207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
40396fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == target) {
40407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return;
40507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
40707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fIPrev = click->fICurr;
40807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fICurr.set(x, y);
4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
41007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fPrev = click->fCurr;
41107ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fCurr.iset(x, y);
41207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (!target->globalToLocal(&click->fCurr)) {
41307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        // on failure pretend the mouse didn't move
41407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        click->fCurr = click->fPrev;
41507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
41707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fState = Click::kMoved_State;
4184d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    click->fModifierKeys = modi;
41907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    target->onClick(click);
4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4229a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::DoClickUp(Click* click, int x, int y, unsigned modi) {
42307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkASSERT(click);
4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
42507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
42696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == target) {
42707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return;
42807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
43007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fIPrev = click->fICurr;
43107ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fICurr.set(x, y);
4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
43307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fPrev = click->fCurr;
43407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fCurr.iset(x, y);
43507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (!target->globalToLocal(&click->fCurr)) {
43607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        // on failure pretend the mouse didn't move
43707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        click->fCurr = click->fPrev;
43807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
44007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fState = Click::kUp_State;
4414d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    click->fModifierKeys = modi;
44207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    target->onClick(click);
4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////
4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
447e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.comvoid SkView::invokeLayout() {
448a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView::Layout* layout = this->getLayout();
4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
450a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (layout) {
451a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        layout->layoutChildren(this);
452e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    }
4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
455e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.comvoid SkView::onDraw(SkCanvas* canvas) {
456a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    Artist* artist = this->getArtist();
4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
458a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (artist) {
459a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        artist->draw(this, canvas);
460e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    }
4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
463e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.comvoid SkView::onSizeChange() {}
464e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com
4654d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.combool SkView::onSendClickToChildren(SkScalar x, SkScalar y, unsigned modi) {
466e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    return true;
4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4694d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comSkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
47096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return nullptr;
4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
473e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.combool SkView::onClick(Click*) {
474a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return false;
4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
477f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SkView::handleInval(const SkRect*) {
478a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return false;
4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////
4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
483a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::getLocalBounds(SkRect* bounds) const {
484a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (bounds) {
485a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        bounds->set(0, 0, fWidth, fHeight);
486a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    }
4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////
4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////
4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
492a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::detachFromParent_NoLayout() {
493a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
49496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (fParent == nullptr) {
495a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        return;
496a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    }
4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
498a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fContainsFocus) {
49996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        (void)this->setFocusView(nullptr);
500a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    }
5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
50296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    this->inval(nullptr);
5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
50496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    SkView* next = nullptr;
5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
506a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fNextSibling != this) {   // do we have any siblings
507a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fNextSibling->fPrevSibling = fPrevSibling;
508a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fPrevSibling->fNextSibling = fNextSibling;
509a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        next = fNextSibling;
510a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
512a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fParent->fFirstChild == this) {
513a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fParent->fFirstChild = next;
514a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    }
5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
51696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fParent = fNextSibling = fPrevSibling = nullptr;
5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
518a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
519a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->unref();
5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
522a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::detachFromParent() {
523a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
524a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* parent = fParent;
5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
526a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (parent) {
527a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->detachFromParent_NoLayout();
528a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        parent->invokeLayout();
529a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
532a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView* SkView::attachChildToBack(SkView* child) {
533a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
534a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkASSERT(child != this);
5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
53696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (child == nullptr || fFirstChild == child)
537a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        goto DONE;
5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
539a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->ref();
540a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->detachFromParent_NoLayout();
5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
54296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (fFirstChild == nullptr) {
543a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fNextSibling = child;
544a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fPrevSibling = child;
545a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    } else {
546a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fNextSibling = fFirstChild;
547a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fPrevSibling = fFirstChild->fPrevSibling;
548a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild->fPrevSibling->fNextSibling = child;
549a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild->fPrevSibling = child;
550a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
552a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fFirstChild = child;
553a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->fParent = this;
55496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    child->inval(nullptr);
5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
556a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
557a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->invokeLayout();
5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comDONE:
559a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return child;
5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
562a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView* SkView::attachChildToFront(SkView* child) {
563a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
564a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkASSERT(child != this);
5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
56696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (child == nullptr || (fFirstChild && fFirstChild->fPrevSibling == child))
567a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        goto DONE;
5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
569a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->ref();
570a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->detachFromParent_NoLayout();
5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
57296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (fFirstChild == nullptr) {
573a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild = child;
574a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fNextSibling = child;
575a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fPrevSibling = child;
576a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    } else {
577a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fNextSibling = fFirstChild;
578a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fPrevSibling = fFirstChild->fPrevSibling;
579a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild->fPrevSibling->fNextSibling = child;
580a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild->fPrevSibling = child;
581a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
583a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->fParent = this;
58496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    child->inval(nullptr);
5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
586a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
587a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->invokeLayout();
5888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comDONE:
589a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return child;
5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
592a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::detachAllChildren() {
593a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
594a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    while (fFirstChild)
595a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild->detachFromParent_NoLayout();
5968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
598a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::localToGlobal(SkMatrix* matrix) const {
599f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    if (matrix) {
600f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        matrix->reset();
601f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        const SkView* view = this;
602f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        while (view)
603f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        {
604f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            matrix->preConcat(view->getLocalMatrix());
605f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            matrix->preTranslate(-view->fLoc.fX, -view->fLoc.fY);
606f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            view = view->fParent;
607f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        }
608f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    }
609f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com}
6109a878a00ef2c2eb72628c807be5969e2d8098317reed
6119a878a00ef2c2eb72628c807be5969e2d8098317reedbool SkView::globalToLocal(SkScalar x, SkScalar y, SkPoint* local) const {
61249f085dddff10473b6ebf832a974288300224e60bsalomon    if (local) {
613f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        SkMatrix m;
614f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        this->localToGlobal(&m);
61507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        if (!m.invert(&m)) {
61607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com            return false;
61707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        }
618f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        SkPoint p;
619f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.mapXY(x, y, &p);
62007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        local->set(p.fX, p.fY);
62107ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
62207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
62307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    return true;
6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
628d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com/*    Even if the subclass overrides onInflate, they should always be
629a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    sure to call the inherited method, so that we get called.
6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
631a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::onInflate(const SkDOM& dom, const SkDOM::Node* node) {
632a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkScalar x, y;
6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
634a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    x = this->locX();
635a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    y = this->locY();
636a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    (void)dom.findScalar(node, "x", &x);
637a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    (void)dom.findScalar(node, "y", &y);
638a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setLoc(x, y);
6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
640a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    x = this->width();
641a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    y = this->height();
642a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    (void)dom.findScalar(node, "width", &x);
643a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    (void)dom.findScalar(node, "height", &y);
644a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setSize(x, y);
6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
646a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    // inflate the flags
6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
648a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    static const char* gFlagNames[] = {
649a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        "visible", "enabled", "focusable", "flexH", "flexV"
650a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    };
651a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkASSERT(SK_ARRAY_COUNT(gFlagNames) == kFlagShiftCount);
6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
653a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    bool     b;
654a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    uint32_t flags = this->getFlags();
6559a878a00ef2c2eb72628c807be5969e2d8098317reed    for (unsigned i = 0; i < SK_ARRAY_COUNT(gFlagNames); i++) {
6569a878a00ef2c2eb72628c807be5969e2d8098317reed        if (dom.findBool(node, gFlagNames[i], &b)) {
657a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            flags = SkSetClearShift(flags, b, i);
6589a878a00ef2c2eb72628c807be5969e2d8098317reed        }
6599a878a00ef2c2eb72628c807be5969e2d8098317reed    }
660a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setFlags(flags);
6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
663a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::inflate(const SkDOM& dom, const SkDOM::Node* node) {
664a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->onInflate(dom, node);
6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
669a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView* SkView::sendEventToParents(const SkEvent& evt) {
670a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* parent = fParent;
671d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
672a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    while (parent) {
673a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        if (parent->doEvent(evt)) {
674a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return parent;
675a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        }
676a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        parent = parent->fParent;
677a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
67896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return nullptr;
6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
68134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comSkView* SkView::sendQueryToParents(SkEvent* evt) {
682a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* parent = fParent;
683d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
684a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    while (parent) {
685a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (parent->doQuery(evt)) {
686a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return parent;
68734245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        }
688a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        parent = parent->fParent;
689a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
69096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return nullptr;
69134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com}
69234245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com
6938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
6958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
696a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView::F2BIter::F2BIter(const SkView* parent) {
69796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fFirstChild = parent ? parent->fFirstChild : nullptr;
69896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fChild = fFirstChild ? fFirstChild->fPrevSibling : nullptr;
6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
701a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView* SkView::F2BIter::next() {
702a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* curr = fChild;
7038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
704a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fChild) {
705a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        if (fChild == fFirstChild) {
70696fcdcc219d2a0d3579719b84b28bede76efba64halcanary            fChild = nullptr;
707a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        } else {
708a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            fChild = fChild->fPrevSibling;
709a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        }
710a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
711a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return curr;
7128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
714a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView::B2FIter::B2FIter(const SkView* parent) {
71596fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fFirstChild = parent ? parent->fFirstChild : nullptr;
716a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fChild = fFirstChild;
7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
719a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView* SkView::B2FIter::next() {
720a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* curr = fChild;
7218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
722a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fChild) {
723a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SkView* next = fChild->fNextSibling;
724a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (next == fFirstChild)
72596fcdcc219d2a0d3579719b84b28bede76efba64halcanary            next = nullptr;
726a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fChild = next;
727a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
728a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return curr;
7298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
7328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
7338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
7358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
736a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::validate() const {
737079813e2da59f35e2744af7a785d01d9f490e280reed@google.com//    SkASSERT(this->getRefCnt() > 0 && this->getRefCnt() < 100);
738a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fParent) {
739a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        SkASSERT(fNextSibling);
740a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        SkASSERT(fPrevSibling);
741a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    } else {
74296fcdcc219d2a0d3579719b84b28bede76efba64halcanary        bool nextNull = nullptr == fNextSibling;
74396fcdcc219d2a0d3579719b84b28bede76efba64halcanary        bool prevNull = nullptr == fNextSibling;
744732c5d516a3ad729e69d88043c771f8b8eac2560reed@google.com        SkASSERT(nextNull == prevNull);
745a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    }
746a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com}
747a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com
7489a878a00ef2c2eb72628c807be5969e2d8098317reedstatic inline void show_if_nonzero(const char name[], SkScalar value) {
7499a878a00ef2c2eb72628c807be5969e2d8098317reed    if (value) {
750a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SkDebugf("%s=\"%g\"", name, value/65536.);
7519a878a00ef2c2eb72628c807be5969e2d8098317reed    }
7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7549a878a00ef2c2eb72628c807be5969e2d8098317reedstatic void tab(int level) {
7559a878a00ef2c2eb72628c807be5969e2d8098317reed    for (int i = 0; i < level; i++) {
756a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SkDebugf("    ");
7579a878a00ef2c2eb72628c807be5969e2d8098317reed    }
7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7609a878a00ef2c2eb72628c807be5969e2d8098317reedstatic void dumpview(const SkView* view, int level, bool recurse) {
761a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    tab(level);
762a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
763a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkDebugf("<view");
764a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    show_if_nonzero(" x", view->locX());
765a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    show_if_nonzero(" y", view->locY());
766a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    show_if_nonzero(" width", view->width());
767a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    show_if_nonzero(" height", view->height());
768a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
7699a878a00ef2c2eb72628c807be5969e2d8098317reed    if (recurse) {
770d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView::B2FIter    iter(view);
771d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView*            child;
772d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        bool            noChildren = true;
773a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
7749a878a00ef2c2eb72628c807be5969e2d8098317reed        while ((child = iter.next()) != nullptr) {
7759a878a00ef2c2eb72628c807be5969e2d8098317reed            if (noChildren) {
776a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                SkDebugf(">\n");
7779a878a00ef2c2eb72628c807be5969e2d8098317reed            }
778a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            noChildren = false;
779a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            dumpview(child, level + 1, true);
780a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        }
781a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
7829a878a00ef2c2eb72628c807be5969e2d8098317reed        if (!noChildren) {
783a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            tab(level);
784a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            SkDebugf("</view>\n");
7859a878a00ef2c2eb72628c807be5969e2d8098317reed        } else {
786a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            goto ONELINER;
7879a878a00ef2c2eb72628c807be5969e2d8098317reed        }
7889a878a00ef2c2eb72628c807be5969e2d8098317reed    } else {
789a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    ONELINER:
790a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SkDebugf(" />\n");
791a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7949a878a00ef2c2eb72628c807be5969e2d8098317reedvoid SkView::dump(bool recurse) const {
795a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    dumpview(this, 0, recurse);
7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
799