1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkView::SkView(uint32_t flags) : fFlags(SkToU8(flags))
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
15a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fWidth = fHeight = 0;
16a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fLoc.set(0, 0);
17a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fParent = fFirstChild = fNextSibling = fPrevSibling = NULL;
18f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    fMatrix.setIdentity();
19a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fContainsFocus = 0;
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkView::~SkView()
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
24a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->detachAllChildren();
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::setFlags(uint32_t flags)
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
29a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkASSERT((flags & ~kAllFlagMasks) == 0);
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
31a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    uint32_t diff = fFlags ^ flags;
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
33a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (diff & kVisible_Mask)
34a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->inval(NULL);
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
36a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fFlags = SkToU8(flags);
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
38a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (diff & kVisible_Mask)
39a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
40a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->inval(NULL);
41a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::setVisibleP(bool pred)
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
46a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift));
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::setEnabledP(bool pred)
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
51a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setFlags(SkSetClearShift(fFlags, pred, kEnabled_Shift));
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::setFocusableP(bool pred)
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
56a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setFlags(SkSetClearShift(fFlags, pred, kFocusable_Shift));
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
59f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comvoid SkView::setClipToBounds(bool pred) {
60f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    this->setFlags(SkSetClearShift(fFlags, !pred, kNoClip_Shift));
61f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
62f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::setSize(SkScalar width, SkScalar height)
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
65a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    width = SkMaxScalar(0, width);
66a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    height = SkMaxScalar(0, height);
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
68a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (fWidth != width || fHeight != height)
69a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
70a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->inval(NULL);
71a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fWidth = width;
72a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fHeight = height;
73a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->inval(NULL);
74a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->onSizeChange();
75a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->invokeLayout();
76a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::setLoc(SkScalar x, SkScalar y)
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
81a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (fLoc.fX != x || fLoc.fY != y)
82a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
83a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->inval(NULL);
84a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fLoc.set(x, y);
85f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        this->inval(NULL);
86a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::offset(SkScalar dx, SkScalar dy)
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
91a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (dx || dy)
92a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->setLoc(fLoc.fX + dx, fLoc.fY + dy);
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
95d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comvoid SkView::setLocalMatrix(const SkMatrix& matrix)
96f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com{
97f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    this->inval(NULL);
98f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    fMatrix = matrix;
99f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    this->inval(NULL);
100f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com}
101f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::draw(SkCanvas* canvas)
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
104a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (fWidth && fHeight && this->isVisible())
105a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
106d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkRect    r;
107a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        r.set(fLoc.fX, fLoc.fY, fLoc.fX + fWidth, fLoc.fY + fHeight);
108a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (this->isClipToBounds() &&
1093b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com            canvas->quickReject(r)) {
110f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                return;
111f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
113d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkAutoCanvasRestore    as(canvas, true);
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
115f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (this->isClipToBounds()) {
116f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            canvas->clipRect(r);
117f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
118d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
119d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        canvas->translate(fLoc.fX, fLoc.fY);
120f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        canvas->concat(fMatrix);
121d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1226c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        if (fParent) {
1236c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            fParent->beforeChild(this, canvas);
1246c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        }
125562ea92179edb35303bd7b3dd6272a5f4eae47ffreed@android.com
126562ea92179edb35303bd7b3dd6272a5f4eae47ffreed@android.com        int sc = canvas->save();
127a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->onDraw(canvas);
128562ea92179edb35303bd7b3dd6272a5f4eae47ffreed@android.com        canvas->restoreToCount(sc);
129562ea92179edb35303bd7b3dd6272a5f4eae47ffreed@android.com
1306c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        if (fParent) {
1316c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            fParent->afterChild(this, canvas);
1326c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        }
133d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
134d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        B2FIter    iter(this);
135d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView*    child;
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkCanvas* childCanvas = this->beforeChildren(canvas);
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
139a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        while ((child = iter.next()) != NULL)
140a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            child->draw(childCanvas);
141d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->afterChildren(canvas);
143a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
146f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comvoid SkView::inval(SkRect* rect) {
147d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView*    view = this;
148f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkRect storage;
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
150a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    for (;;) {
151f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (!view->isVisible()) {
152f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            return;
153f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
154f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view->isClipToBounds()) {
155f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkRect bounds;
156f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            view->getLocalBounds(&bounds);
157f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (rect && !bounds.intersect(*rect)) {
158f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                return;
159f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
160f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            storage = bounds;
161f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            rect = &storage;
162f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
163f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view->handleInval(rect)) {
164f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            return;
165f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
167a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SkView* parent = view->fParent;
168f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (parent == NULL) {
169f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            return;
170f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
172f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (rect) {
173f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            rect->offset(view->fLoc.fX, view->fLoc.fY);
174f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
175f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        view = parent;
176a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkView::setFocusView(SkView* fv)
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
183a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* view = this;
184d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
185a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    do {
186a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (view->onSetFocusView(fv))
187a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return true;
188a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    } while ((view = view->fParent) != NULL);
189a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return false;
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkView* SkView::getFocusView() const
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
194d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView*            focus = NULL;
195d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    const SkView*    view = this;
196a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    do {
197a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (view->onGetFocusView(&focus))
198a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            break;
199a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    } while ((view = view->fParent) != NULL);
200a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return focus;
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkView::hasFocus() const
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
205a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return this == this->getFocusView();
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkView::acceptFocus()
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
210a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return this->isFocusable() && this->setFocusView(this);
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
214a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    Try to give focus to this view, or its children
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkView* SkView::acceptFocus(FocusDirection dir)
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
218a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (dir == kNext_FocusDirection)
219a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
220a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (this->acceptFocus())
221a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return this;
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
223d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        B2FIter    iter(this);
224d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView*    child, *focus;
225a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        while ((child = iter.next()) != NULL)
226a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            if ((focus = child->acceptFocus(dir)) != NULL)
227a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                return focus;
228a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
229a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    else // prev
230a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
231d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        F2BIter    iter(this);
232d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView*    child, *focus;
233a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        while ((child = iter.next()) != NULL)
234a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            if ((focus = child->acceptFocus(dir)) != NULL)
235a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                return focus;
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
237a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (this->acceptFocus())
238a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return this;
239a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
241a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return NULL;
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkView* SkView::moveFocus(FocusDirection dir)
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
246a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* focus = this->getFocusView();
247a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
248a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (focus == NULL)
249d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {    // start with the root
250a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        focus = this;
251a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        while (focus->fParent)
252a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            focus = focus->fParent;
253a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
254a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
255d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView*    child, *parent;
256a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
257a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (dir == kNext_FocusDirection)
258a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
259a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        parent = focus;
260a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child = focus->fFirstChild;
261a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (child)
262a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            goto FIRST_CHILD;
263a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        else
264a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            goto NEXT_SIB;
265a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
266a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        do {
267a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            while (child != parent->fFirstChild)
268a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            {
269a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    FIRST_CHILD:
270a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                if ((focus = child->acceptFocus(dir)) != NULL)
271a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                    return focus;
272a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                child = child->fNextSibling;
273a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            }
274a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    NEXT_SIB:
275a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            child = parent->fNextSibling;
276a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            parent = parent->fParent;
277a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        } while (parent != NULL);
278a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
279d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else    // prevfocus
280a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
281a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        parent = focus->fParent;
282d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (parent == NULL)    // we're the root
283a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return focus->acceptFocus(dir);
284a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        else
285a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        {
286a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            child = focus;
287a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            while (parent)
288a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            {
289a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                while (child != parent->fFirstChild)
290a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                {
291a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                    child = child->fPrevSibling;
292a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                    if ((focus = child->acceptFocus(dir)) != NULL)
293a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                        return focus;
294a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                }
295a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                if (parent->acceptFocus())
296a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                    return parent;
297a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
298a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                child = parent;
299a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                parent = parent->fParent;
300a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            }
301a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        }
302a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
303a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return NULL;
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::onFocusChange(bool gainFocusP)
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
308a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->inval(NULL);
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkView::Click::Click(SkView* target)
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
315d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo    SkASSERT(target);
316d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo    fTargetID = target->getSinkID();
317d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo    fType = NULL;
318d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo    fWeOwnTheType = false;
319d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo    fOwner = NULL;
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkView::Click::~Click()
3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
324a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->resetType();
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::Click::resetType()
3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
329a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (fWeOwnTheType)
330a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
331a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        sk_free(fType);
332a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fWeOwnTheType = false;
333a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
334a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fType = NULL;
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkView::Click::isType(const char type[]) const
3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
339a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    const char* t = fType;
3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
341a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (type == t)
342a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        return true;
3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
344a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (type == NULL)
345a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        type = "";
346a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (t == NULL)
347a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        t = "";
348a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return !strcmp(t, type);
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::Click::setType(const char type[])
3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
353a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->resetType();
354a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fType = (char*)type;
3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::Click::copyType(const char type[])
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
359a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (fType != type)
360a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
361a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->resetType();
362a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (type)
363a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        {
364d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            size_t    len = strlen(type) + 1;
365a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            fType = (char*)sk_malloc_throw(len);
366a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            memcpy(fType, type, len);
367a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            fWeOwnTheType = true;
368a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        }
369a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3724d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comSkView::Click* SkView::findClickHandler(SkScalar x, SkScalar y, unsigned modi) {
37307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) {
37407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return NULL;
375e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    }
376e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com
3774d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    if (this->onSendClickToChildren(x, y, modi)) {
378d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        F2BIter    iter(this);
379d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView*    child;
38007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
381e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com        while ((child = iter.next()) != NULL)
382e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com        {
383f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            SkPoint p;
38407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com            if (!child->globalToLocal(x, y, &p)) {
38507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com                continue;
38607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com            }
38707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
3884d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            Click* click = child->findClickHandler(p.fX, p.fY, modi);
38907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
390e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com            if (click) {
391e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com                return click;
392e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com            }
393e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com        }
394e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    }
39507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
3964d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    return this->onFindClickHandler(x, y, modi);
3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3994d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comvoid SkView::DoClickDown(Click* click, int x, int y, unsigned modi)
4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
40107ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkASSERT(click);
4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
40307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
40407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (NULL == target) {
40507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return;
40607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
40807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fIOrig.set(x, y);
40907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fICurr = click->fIPrev = click->fIOrig;
4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
41107ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fOrig.iset(x, y);
41207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (!target->globalToLocal(&click->fOrig)) {
41307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        // no history to let us recover from this failure
41407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return;
41507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
41607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fPrev = click->fCurr = click->fOrig;
4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
41807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fState = Click::kDown_State;
4194d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    click->fModifierKeys = modi;
42007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    target->onClick(click);
4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4234d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comvoid SkView::DoClickMoved(Click* click, int x, int y, unsigned modi)
4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
42507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkASSERT(click);
4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
42707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
42807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (NULL == target) {
42907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return;
43007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
43207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fIPrev = click->fICurr;
43307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fICurr.set(x, y);
4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
43507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fPrev = click->fCurr;
43607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fCurr.iset(x, y);
43707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (!target->globalToLocal(&click->fCurr)) {
43807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        // on failure pretend the mouse didn't move
43907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        click->fCurr = click->fPrev;
44007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
44207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fState = Click::kMoved_State;
4434d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    click->fModifierKeys = modi;
44407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    target->onClick(click);
4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4474d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comvoid SkView::DoClickUp(Click* click, int x, int y, unsigned modi)
4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
44907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkASSERT(click);
4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
45107ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
45207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (NULL == target) {
45307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return;
45407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
45607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fIPrev = click->fICurr;
45707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fICurr.set(x, y);
4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
45907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fPrev = click->fCurr;
46007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fCurr.iset(x, y);
46107ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (!target->globalToLocal(&click->fCurr)) {
46207ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        // on failure pretend the mouse didn't move
46307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        click->fCurr = click->fPrev;
46407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
46607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    click->fState = Click::kUp_State;
4674d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    click->fModifierKeys = modi;
46807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    target->onClick(click);
4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////
4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
473e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.comvoid SkView::invokeLayout() {
474a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView::Layout* layout = this->getLayout();
4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
476a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (layout) {
477a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        layout->layoutChildren(this);
478e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    }
4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
481e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.comvoid SkView::onDraw(SkCanvas* canvas) {
482a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    Artist* artist = this->getArtist();
4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
484a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (artist) {
485a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        artist->draw(this, canvas);
486e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    }
4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
489e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.comvoid SkView::onSizeChange() {}
490e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com
4914d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.combool SkView::onSendClickToChildren(SkScalar x, SkScalar y, unsigned modi) {
492e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    return true;
4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4954d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comSkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
496a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return NULL;
4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
499e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.combool SkView::onClick(Click*) {
500a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return false;
5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
503f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SkView::handleInval(const SkRect*) {
504a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return false;
5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////
5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
509a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::getLocalBounds(SkRect* bounds) const {
510a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (bounds) {
511a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        bounds->set(0, 0, fWidth, fHeight);
512a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    }
5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////
5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////
5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
518a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::detachFromParent_NoLayout() {
519a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
520a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fParent == NULL) {
521a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        return;
522a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    }
5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
524a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fContainsFocus) {
525a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        (void)this->setFocusView(NULL);
526a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    }
5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
528a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->inval(NULL);
5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
530a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    SkView* next = NULL;
5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
532a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fNextSibling != this) {   // do we have any siblings
533a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fNextSibling->fPrevSibling = fPrevSibling;
534a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fPrevSibling->fNextSibling = fNextSibling;
535a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        next = fNextSibling;
536a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
538a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fParent->fFirstChild == this) {
539a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fParent->fFirstChild = next;
540a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    }
5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
542a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fParent = fNextSibling = fPrevSibling = NULL;
5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
544a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
545a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->unref();
5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
548a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::detachFromParent() {
549a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
550a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* parent = fParent;
5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
552a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (parent) {
553a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        this->detachFromParent_NoLayout();
554a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        parent->invokeLayout();
555a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
558a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView* SkView::attachChildToBack(SkView* child) {
559a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
560a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkASSERT(child != this);
5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
562a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (child == NULL || fFirstChild == child)
563a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        goto DONE;
5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
565a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->ref();
566a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->detachFromParent_NoLayout();
5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
568a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fFirstChild == NULL) {
569a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fNextSibling = child;
570a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fPrevSibling = child;
571a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    } else {
572a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fNextSibling = fFirstChild;
573a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fPrevSibling = fFirstChild->fPrevSibling;
574a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild->fPrevSibling->fNextSibling = child;
575a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild->fPrevSibling = child;
576a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
578a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fFirstChild = child;
579a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->fParent = this;
580a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->inval(NULL);
5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
582a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
583a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->invokeLayout();
5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comDONE:
585a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return child;
5868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
588a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView* SkView::attachChildToFront(SkView* child) {
589a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
590a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkASSERT(child != this);
5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
592a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (child == NULL || (fFirstChild && fFirstChild->fPrevSibling == child))
593a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        goto DONE;
5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
595a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->ref();
596a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->detachFromParent_NoLayout();
5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
598a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fFirstChild == NULL) {
599a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild = child;
600a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fNextSibling = child;
601a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fPrevSibling = child;
602a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    } else {
603a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fNextSibling = fFirstChild;
604a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->fPrevSibling = fFirstChild->fPrevSibling;
605a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild->fPrevSibling->fNextSibling = child;
606a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild->fPrevSibling = child;
607a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
6088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
609a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->fParent = this;
610a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    child->inval(NULL);
6118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
612a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
613a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->invokeLayout();
6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comDONE:
615a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return child;
6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
618a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::detachAllChildren() {
619a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    this->validate();
620a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    while (fFirstChild)
621a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fFirstChild->detachFromParent_NoLayout();
6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
624a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::localToGlobal(SkMatrix* matrix) const {
625f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    if (matrix) {
626f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        matrix->reset();
627f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        const SkView* view = this;
628f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        while (view)
629f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        {
630f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            matrix->preConcat(view->getLocalMatrix());
631f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            matrix->preTranslate(-view->fLoc.fX, -view->fLoc.fY);
632f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            view = view->fParent;
633f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        }
634f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    }
635f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com}
63607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.combool SkView::globalToLocal(SkScalar x, SkScalar y, SkPoint* local) const
6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
63807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    SkASSERT(this);
63907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
64049f085dddff10473b6ebf832a974288300224e60bsalomon    if (local) {
641f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        SkMatrix m;
642f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        this->localToGlobal(&m);
64307ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        if (!m.invert(&m)) {
64407ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com            return false;
64507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        }
646f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        SkPoint p;
647f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.mapXY(x, y, &p);
64807ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        local->set(p.fX, p.fY);
64907ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
65007ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com
65107ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    return true;
6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
656d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com/*    Even if the subclass overrides onInflate, they should always be
657a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    sure to call the inherited method, so that we get called.
6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
659a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::onInflate(const SkDOM& dom, const SkDOM::Node* node) {
660a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkScalar x, y;
6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
662a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    x = this->locX();
663a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    y = this->locY();
664a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    (void)dom.findScalar(node, "x", &x);
665a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    (void)dom.findScalar(node, "y", &y);
666a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setLoc(x, y);
6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
668a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    x = this->width();
669a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    y = this->height();
670a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    (void)dom.findScalar(node, "width", &x);
671a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    (void)dom.findScalar(node, "height", &y);
672a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setSize(x, y);
6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
674a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    // inflate the flags
6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
676a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    static const char* gFlagNames[] = {
677a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        "visible", "enabled", "focusable", "flexH", "flexV"
678a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    };
679a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkASSERT(SK_ARRAY_COUNT(gFlagNames) == kFlagShiftCount);
6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
681a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    bool     b;
682a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    uint32_t flags = this->getFlags();
683a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    for (unsigned i = 0; i < SK_ARRAY_COUNT(gFlagNames); i++)
684a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (dom.findBool(node, gFlagNames[i], &b))
685a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            flags = SkSetClearShift(flags, b, i);
686a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->setFlags(flags);
6878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
689a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::inflate(const SkDOM& dom, const SkDOM::Node* node) {
690a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->onInflate(dom, node);
6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
693a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::onPostInflate(const SkTDict<SkView*>&) {
694a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    // override in subclass as needed
6958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
697a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::postInflate(const SkTDict<SkView*>& dict) {
698a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    this->onPostInflate(dict);
6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
700d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    B2FIter    iter(this);
701d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView*    child;
702a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    while ((child = iter.next()) != NULL)
703a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        child->postInflate(dict);
7048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
7078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
708a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView* SkView::sendEventToParents(const SkEvent& evt) {
709a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* parent = fParent;
710d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
711a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    while (parent) {
712a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        if (parent->doEvent(evt)) {
713a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return parent;
714a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        }
715a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        parent = parent->fParent;
716a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
717a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return NULL;
7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
72034245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comSkView* SkView::sendQueryToParents(SkEvent* evt) {
721a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* parent = fParent;
722d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
723a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    while (parent) {
724a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (parent->doQuery(evt)) {
725a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            return parent;
72634245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        }
727a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        parent = parent->fParent;
728a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
729a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return NULL;
73034245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com}
73134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com
7328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
7338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
735a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView::F2BIter::F2BIter(const SkView* parent) {
736a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fFirstChild = parent ? parent->fFirstChild : NULL;
737a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fChild = fFirstChild ? fFirstChild->fPrevSibling : NULL;
7388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
740a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView* SkView::F2BIter::next() {
741a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* curr = fChild;
7428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
743a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fChild) {
744a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        if (fChild == fFirstChild) {
745a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            fChild = NULL;
746a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        } else {
747a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            fChild = fChild->fPrevSibling;
748a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        }
749a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
750a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return curr;
7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
753a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView::B2FIter::B2FIter(const SkView* parent) {
754a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fFirstChild = parent ? parent->fFirstChild : NULL;
755a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    fChild = fFirstChild;
7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
758a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comSkView* SkView::B2FIter::next() {
759a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkView* curr = fChild;
7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
761a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fChild) {
762a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SkView* next = fChild->fNextSibling;
763a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (next == fFirstChild)
764a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            next = NULL;
765a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        fChild = next;
766a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
767a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    return curr;
7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////
7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
775a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.comvoid SkView::validate() const {
776079813e2da59f35e2744af7a785d01d9f490e280reed@google.com//    SkASSERT(this->getRefCnt() > 0 && this->getRefCnt() < 100);
777a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    if (fParent) {
778a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        SkASSERT(fNextSibling);
779a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        SkASSERT(fPrevSibling);
780a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    } else {
781a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        bool nextNull = NULL == fNextSibling;
782a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com        bool prevNull = NULL == fNextSibling;
783732c5d516a3ad729e69d88043c771f8b8eac2560reed@google.com        SkASSERT(nextNull == prevNull);
784a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com    }
785a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com}
786a25c94e50a6bbd1a73656923592293385acc2ce7reed@google.com
7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline void show_if_nonzero(const char name[], SkScalar value)
7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
789a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (value)
790a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SkDebugf("%s=\"%g\"", name, value/65536.);
7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void tab(int level)
7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
795a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    for (int i = 0; i < level; i++)
796a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SkDebugf("    ");
7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void dumpview(const SkView* view, int level, bool recurse)
8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
801a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    tab(level);
802a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
803a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SkDebugf("<view");
804a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    show_if_nonzero(" x", view->locX());
805a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    show_if_nonzero(" y", view->locY());
806a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    show_if_nonzero(" width", view->width());
807a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    show_if_nonzero(" height", view->height());
808a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
809a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    if (recurse)
810a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
811d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView::B2FIter    iter(view);
812d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkView*            child;
813d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        bool            noChildren = true;
814a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
815a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        while ((child = iter.next()) != NULL)
816a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        {
817a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            if (noChildren)
818a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com                SkDebugf(">\n");
819a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            noChildren = false;
820a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            dumpview(child, level + 1, true);
821a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        }
822a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
823a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        if (!noChildren)
824a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        {
825a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            tab(level);
826a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            SkDebugf("</view>\n");
827a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        }
828a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        else
829a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com            goto ONELINER;
830a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
831a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    else
832a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    {
833a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    ONELINER:
834a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SkDebugf(" />\n");
835a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    }
8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkView::dump(bool recurse) const
8398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
840a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    dumpview(this, 0, recurse);
8418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
8428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
844