1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com
2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com/*
3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2011 Google Inc.
4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com *
5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file.
7685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com */
8bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkView.h"
9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkCanvas.h"
10bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
11bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com////////////////////////////////////////////////////////////////////////
12bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
13bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkView::SkView(uint32_t flags) : fFlags(SkToU8(flags))
14bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
1518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fWidth = fHeight = 0;
1618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fLoc.set(0, 0);
1718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fParent = fFirstChild = fNextSibling = fPrevSibling = NULL;
18f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com    fMatrix.setIdentity();
1918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fContainsFocus = 0;
20bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
21bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
22bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkView::~SkView()
23bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
2418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->detachAllChildren();
25bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
26bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
27bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::setFlags(uint32_t flags)
28bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
2918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkASSERT((flags & ~kAllFlagMasks) == 0);
30bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
3118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    uint32_t diff = fFlags ^ flags;
32bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
3318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (diff & kVisible_Mask)
3418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->inval(NULL);
35bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
3618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fFlags = SkToU8(flags);
37bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
3818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (diff & kVisible_Mask)
3918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
4018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->inval(NULL);
4118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
42bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
43bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
44bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::setVisibleP(bool pred)
45bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
4618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift));
47bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
48bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
49bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::setEnabledP(bool pred)
50bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
5118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->setFlags(SkSetClearShift(fFlags, pred, kEnabled_Shift));
52bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
53bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
54bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::setFocusableP(bool pred)
55bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
5618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->setFlags(SkSetClearShift(fFlags, pred, kFocusable_Shift));
57bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
58bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
59e216b62841acd5db9d91b63960805568259a2e0ereed@android.comvoid SkView::setClipToBounds(bool pred) {
60e216b62841acd5db9d91b63960805568259a2e0ereed@android.com    this->setFlags(SkSetClearShift(fFlags, !pred, kNoClip_Shift));
61e216b62841acd5db9d91b63960805568259a2e0ereed@android.com}
62e216b62841acd5db9d91b63960805568259a2e0ereed@android.com
63bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::setSize(SkScalar width, SkScalar height)
64bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
6518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    width = SkMaxScalar(0, width);
6618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    height = SkMaxScalar(0, height);
67bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
6818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (fWidth != width || fHeight != height)
6918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
7018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->inval(NULL);
7118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fWidth = width;
7218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fHeight = height;
7318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->inval(NULL);
7418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->onSizeChange();
7518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->invokeLayout();
7618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
77bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
78bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
79bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::setLoc(SkScalar x, SkScalar y)
80bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
8118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (fLoc.fX != x || fLoc.fY != y)
8218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
8318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->inval(NULL);
8418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fLoc.set(x, y);
85f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        this->inval(NULL);
8618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
87bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
88bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
89bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::offset(SkScalar dx, SkScalar dy)
90bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
9118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (dx || dy)
9218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->setLoc(fLoc.fX + dx, fLoc.fY + dy);
93bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
94bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
95dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.comvoid SkView::setLocalMatrix(const SkMatrix& matrix)
96f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com{
97f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com    this->inval(NULL);
98f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com    fMatrix = matrix;
99f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com    this->inval(NULL);
100f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com}
101f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com
102bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::draw(SkCanvas* canvas)
103bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
10418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (fWidth && fHeight && this->isVisible())
10518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
106dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        SkRect    r;
10718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        r.set(fLoc.fX, fLoc.fY, fLoc.fX + fWidth, fLoc.fY + fHeight);
10818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (this->isClipToBounds() &&
10968d45a469bd9613ea4f4956ed2eae3fb5bb97c86reed@google.com            canvas->quickReject(r)) {
110e216b62841acd5db9d91b63960805568259a2e0ereed@android.com                return;
111e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        }
112bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
113dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        SkAutoCanvasRestore    as(canvas, true);
114bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
115e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        if (this->isClipToBounds()) {
116e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            canvas->clipRect(r);
117e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        }
118dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
119dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        canvas->translate(fLoc.fX, fLoc.fY);
120f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        canvas->concat(fMatrix);
121dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
12216d00c5674e18b45c72a5d2177e3ca72c8f81f70reed@android.com        if (fParent) {
12316d00c5674e18b45c72a5d2177e3ca72c8f81f70reed@android.com            fParent->beforeChild(this, canvas);
12416d00c5674e18b45c72a5d2177e3ca72c8f81f70reed@android.com        }
12528ad2df376540012a79d07a1a6b95786bc265d11reed@android.com
12628ad2df376540012a79d07a1a6b95786bc265d11reed@android.com        int sc = canvas->save();
12718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->onDraw(canvas);
12828ad2df376540012a79d07a1a6b95786bc265d11reed@android.com        canvas->restoreToCount(sc);
12928ad2df376540012a79d07a1a6b95786bc265d11reed@android.com
13016d00c5674e18b45c72a5d2177e3ca72c8f81f70reed@android.com        if (fParent) {
13116d00c5674e18b45c72a5d2177e3ca72c8f81f70reed@android.com            fParent->afterChild(this, canvas);
13216d00c5674e18b45c72a5d2177e3ca72c8f81f70reed@android.com        }
133dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
134dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        B2FIter    iter(this);
135dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        SkView*    child;
136bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
137bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        SkCanvas* childCanvas = this->beforeChildren(canvas);
138bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
13918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        while ((child = iter.next()) != NULL)
14018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            child->draw(childCanvas);
141dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
142bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com        this->afterChildren(canvas);
14318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
144bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
145bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
146e216b62841acd5db9d91b63960805568259a2e0ereed@android.comvoid SkView::inval(SkRect* rect) {
147dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com    SkView*    view = this;
148e216b62841acd5db9d91b63960805568259a2e0ereed@android.com    SkRect storage;
149bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
15018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    for (;;) {
151e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        if (!view->isVisible()) {
152e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            return;
153e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        }
154e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        if (view->isClipToBounds()) {
155e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            SkRect bounds;
156e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            view->getLocalBounds(&bounds);
157e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            if (rect && !bounds.intersect(*rect)) {
158e216b62841acd5db9d91b63960805568259a2e0ereed@android.com                return;
159e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            }
160e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            storage = bounds;
161e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            rect = &storage;
162e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        }
163e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        if (view->handleInval(rect)) {
164e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            return;
165e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        }
166bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
16718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        SkView* parent = view->fParent;
168e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        if (parent == NULL) {
169e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            return;
170e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        }
171bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
172e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        if (rect) {
173e216b62841acd5db9d91b63960805568259a2e0ereed@android.com            rect->offset(view->fLoc.fX, view->fLoc.fY);
174e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        }
175e216b62841acd5db9d91b63960805568259a2e0ereed@android.com        view = parent;
17618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
177bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
178bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
179bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com////////////////////////////////////////////////////////////////////////////
180bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
181bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkView::setFocusView(SkView* fv)
182bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
18318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkView* view = this;
184dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
18518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    do {
18618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (view->onSetFocusView(fv))
18718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            return true;
18818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    } while ((view = view->fParent) != NULL);
18918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return false;
190bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
191bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
192bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkView* SkView::getFocusView() const
193bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
194dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com    SkView*            focus = NULL;
195dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com    const SkView*    view = this;
19618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    do {
19718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (view->onGetFocusView(&focus))
19818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            break;
19918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    } while ((view = view->fParent) != NULL);
20018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return focus;
201bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
202bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
203bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkView::hasFocus() const
204bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
20518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return this == this->getFocusView();
206bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
207bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
208bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkView::acceptFocus()
209bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
21018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return this->isFocusable() && this->setFocusView(this);
211bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
212bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
213bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/*
21418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    Try to give focus to this view, or its children
215bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com*/
216bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkView* SkView::acceptFocus(FocusDirection dir)
217bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
21818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (dir == kNext_FocusDirection)
21918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
22018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (this->acceptFocus())
22118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            return this;
222bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
223dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        B2FIter    iter(this);
224dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        SkView*    child, *focus;
22518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        while ((child = iter.next()) != NULL)
22618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            if ((focus = child->acceptFocus(dir)) != NULL)
22718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                return focus;
22818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
22918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    else // prev
23018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
231dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        F2BIter    iter(this);
232dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        SkView*    child, *focus;
23318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        while ((child = iter.next()) != NULL)
23418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            if ((focus = child->acceptFocus(dir)) != NULL)
23518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                return focus;
236bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
23718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (this->acceptFocus())
23818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            return this;
23918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
240bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
24118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return NULL;
242bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
243bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
244bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkView* SkView::moveFocus(FocusDirection dir)
245bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
24618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkView* focus = this->getFocusView();
24718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
24818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (focus == NULL)
249dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com    {    // start with the root
25018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        focus = this;
25118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        while (focus->fParent)
25218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            focus = focus->fParent;
25318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
25418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
255dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com    SkView*    child, *parent;
25618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
25718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (dir == kNext_FocusDirection)
25818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
25918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        parent = focus;
26018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        child = focus->fFirstChild;
26118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (child)
26218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            goto FIRST_CHILD;
26318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        else
26418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            goto NEXT_SIB;
26518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
26618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        do {
26718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            while (child != parent->fFirstChild)
26818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            {
26918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    FIRST_CHILD:
27018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                if ((focus = child->acceptFocus(dir)) != NULL)
27118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                    return focus;
27218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                child = child->fNextSibling;
27318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            }
27418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    NEXT_SIB:
27518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            child = parent->fNextSibling;
27618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            parent = parent->fParent;
27718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        } while (parent != NULL);
27818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
279dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com    else    // prevfocus
28018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
28118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        parent = focus->fParent;
282dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        if (parent == NULL)    // we're the root
28318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            return focus->acceptFocus(dir);
28418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        else
28518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        {
28618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            child = focus;
28718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            while (parent)
28818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            {
28918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                while (child != parent->fFirstChild)
29018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                {
29118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                    child = child->fPrevSibling;
29218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                    if ((focus = child->acceptFocus(dir)) != NULL)
29318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                        return focus;
29418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                }
29518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                if (parent->acceptFocus())
29618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                    return parent;
29718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
29818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                child = parent;
29918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                parent = parent->fParent;
30018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            }
30118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        }
30218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
30318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return NULL;
304bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
305bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
306bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::onFocusChange(bool gainFocusP)
307bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
30818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->inval(NULL);
309bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
310bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
311bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com////////////////////////////////////////////////////////////////////////////
312bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
313bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkView::Click::Click(SkView* target)
314bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
315e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com    SkASSERT(target);
316e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com    fTargetID = target->getSinkID();
317e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com    fType = NULL;
318e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com    fWeOwnTheType = false;
319e1c204f635116e86d2be7250a2ebbc41a535ef30bungeman@google.com    fOwner = NULL;
320bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
321bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
322bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comSkView::Click::~Click()
323bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
32418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->resetType();
325bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
326bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
327bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::Click::resetType()
328bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
32918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (fWeOwnTheType)
33018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
33118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        sk_free(fType);
33218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fWeOwnTheType = false;
33318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
33418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fType = NULL;
335bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
336bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
337bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.combool SkView::Click::isType(const char type[]) const
338bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
33918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    const char* t = fType;
340bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
34118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (type == t)
34218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        return true;
343bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
34418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (type == NULL)
34518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        type = "";
34618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (t == NULL)
34718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        t = "";
34818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return !strcmp(t, type);
349bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
350bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
351bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::Click::setType(const char type[])
352bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
35318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->resetType();
35418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fType = (char*)type;
355bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
356bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
357bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::Click::copyType(const char type[])
358bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
35918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (fType != type)
36018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
36118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->resetType();
36218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (type)
36318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        {
364dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com            size_t    len = strlen(type) + 1;
36518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            fType = (char*)sk_malloc_throw(len);
36618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            memcpy(fType, type, len);
36718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            fWeOwnTheType = true;
36818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        }
36918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
370bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
371bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
372c27af8426e3647239ca1e662904b938e3fd424bdreed@google.comSkView::Click* SkView::findClickHandler(SkScalar x, SkScalar y, unsigned modi) {
373b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) {
374b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        return NULL;
375f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com    }
376f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com
377c27af8426e3647239ca1e662904b938e3fd424bdreed@google.com    if (this->onSendClickToChildren(x, y, modi)) {
378dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        F2BIter    iter(this);
379dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        SkView*    child;
380b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com
381f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com        while ((child = iter.next()) != NULL)
382f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com        {
383f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com            SkPoint p;
384b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com            if (!child->globalToLocal(x, y, &p)) {
385b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com                continue;
386b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com            }
387b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com
388c27af8426e3647239ca1e662904b938e3fd424bdreed@google.com            Click* click = child->findClickHandler(p.fX, p.fY, modi);
389b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com
390f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com            if (click) {
391f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com                return click;
392f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com            }
393f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com        }
394f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com    }
395b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com
396c27af8426e3647239ca1e662904b938e3fd424bdreed@google.com    return this->onFindClickHandler(x, y, modi);
397bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
398bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
399c27af8426e3647239ca1e662904b938e3fd424bdreed@google.comvoid SkView::DoClickDown(Click* click, int x, int y, unsigned modi)
400bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
401b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    SkASSERT(click);
402bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
403b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
404b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    if (NULL == target) {
405b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        return;
406b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    }
407bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
408b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fIOrig.set(x, y);
409b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fICurr = click->fIPrev = click->fIOrig;
410bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
411b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fOrig.iset(x, y);
412b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    if (!target->globalToLocal(&click->fOrig)) {
413b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        // no history to let us recover from this failure
414b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        return;
415b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    }
416b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fPrev = click->fCurr = click->fOrig;
417bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
418b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fState = Click::kDown_State;
419c27af8426e3647239ca1e662904b938e3fd424bdreed@google.com    click->fModifierKeys = modi;
420b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    target->onClick(click);
421bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
422bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
423c27af8426e3647239ca1e662904b938e3fd424bdreed@google.comvoid SkView::DoClickMoved(Click* click, int x, int y, unsigned modi)
424bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
425b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    SkASSERT(click);
426bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
427b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
428b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    if (NULL == target) {
429b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        return;
430b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    }
431bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
432b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fIPrev = click->fICurr;
433b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fICurr.set(x, y);
434bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
435b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fPrev = click->fCurr;
436b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fCurr.iset(x, y);
437b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    if (!target->globalToLocal(&click->fCurr)) {
438b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        // on failure pretend the mouse didn't move
439b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        click->fCurr = click->fPrev;
440b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    }
441bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
442b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fState = Click::kMoved_State;
443c27af8426e3647239ca1e662904b938e3fd424bdreed@google.com    click->fModifierKeys = modi;
444b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    target->onClick(click);
445bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
446bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
447c27af8426e3647239ca1e662904b938e3fd424bdreed@google.comvoid SkView::DoClickUp(Click* click, int x, int y, unsigned modi)
448bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
449b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    SkASSERT(click);
450bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
451b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
452b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    if (NULL == target) {
453b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        return;
454b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    }
455bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
456b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fIPrev = click->fICurr;
457b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fICurr.set(x, y);
458bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
459b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fPrev = click->fCurr;
460b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fCurr.iset(x, y);
461b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    if (!target->globalToLocal(&click->fCurr)) {
462b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        // on failure pretend the mouse didn't move
463b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        click->fCurr = click->fPrev;
464b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    }
465bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
466b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    click->fState = Click::kUp_State;
467c27af8426e3647239ca1e662904b938e3fd424bdreed@google.com    click->fModifierKeys = modi;
468b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    target->onClick(click);
469bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
470bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
471bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////////
472bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
473f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.comvoid SkView::invokeLayout() {
47418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkView::Layout* layout = this->getLayout();
475bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
47618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (layout) {
47718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        layout->layoutChildren(this);
478f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com    }
479bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
480bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
481f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.comvoid SkView::onDraw(SkCanvas* canvas) {
48218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    Artist* artist = this->getArtist();
483bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
48418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (artist) {
48518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        artist->draw(this, canvas);
486f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com    }
487bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
488bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
489f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.comvoid SkView::onSizeChange() {}
490f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com
491c27af8426e3647239ca1e662904b938e3fd424bdreed@google.combool SkView::onSendClickToChildren(SkScalar x, SkScalar y, unsigned modi) {
492f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com    return true;
493bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
494bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
495c27af8426e3647239ca1e662904b938e3fd424bdreed@google.comSkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
49618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return NULL;
497bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
498bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
499f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.combool SkView::onClick(Click*) {
50018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return false;
501bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
502bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
503e216b62841acd5db9d91b63960805568259a2e0ereed@android.combool SkView::handleInval(const SkRect*) {
50418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return false;
505bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
506bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
507bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////////
508bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5093d978075f2db743a197e42486483a11ab780e409reed@google.comvoid SkView::getLocalBounds(SkRect* bounds) const {
5103d978075f2db743a197e42486483a11ab780e409reed@google.com    if (bounds) {
51118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        bounds->set(0, 0, fWidth, fHeight);
5123d978075f2db743a197e42486483a11ab780e409reed@google.com    }
513bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
514bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
515bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////////
516bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////////
517bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5183d978075f2db743a197e42486483a11ab780e409reed@google.comvoid SkView::detachFromParent_NoLayout() {
5193d978075f2db743a197e42486483a11ab780e409reed@google.com    this->validate();
5203d978075f2db743a197e42486483a11ab780e409reed@google.com    if (fParent == NULL) {
52118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        return;
5223d978075f2db743a197e42486483a11ab780e409reed@google.com    }
523bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5243d978075f2db743a197e42486483a11ab780e409reed@google.com    if (fContainsFocus) {
52518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        (void)this->setFocusView(NULL);
5263d978075f2db743a197e42486483a11ab780e409reed@google.com    }
527bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
52818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->inval(NULL);
529bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5303d978075f2db743a197e42486483a11ab780e409reed@google.com    SkView* next = NULL;
531bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5323d978075f2db743a197e42486483a11ab780e409reed@google.com    if (fNextSibling != this) {   // do we have any siblings
53318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fNextSibling->fPrevSibling = fPrevSibling;
53418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fPrevSibling->fNextSibling = fNextSibling;
53518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        next = fNextSibling;
53618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
537bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5383d978075f2db743a197e42486483a11ab780e409reed@google.com    if (fParent->fFirstChild == this) {
53918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fParent->fFirstChild = next;
5403d978075f2db743a197e42486483a11ab780e409reed@google.com    }
541bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
54218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fParent = fNextSibling = fPrevSibling = NULL;
543bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5443d978075f2db743a197e42486483a11ab780e409reed@google.com    this->validate();
54518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->unref();
546bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
547bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5483d978075f2db743a197e42486483a11ab780e409reed@google.comvoid SkView::detachFromParent() {
5493d978075f2db743a197e42486483a11ab780e409reed@google.com    this->validate();
55018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkView* parent = fParent;
551bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5523d978075f2db743a197e42486483a11ab780e409reed@google.com    if (parent) {
55318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        this->detachFromParent_NoLayout();
55418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        parent->invokeLayout();
55518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
556bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
557bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5583d978075f2db743a197e42486483a11ab780e409reed@google.comSkView* SkView::attachChildToBack(SkView* child) {
5593d978075f2db743a197e42486483a11ab780e409reed@google.com    this->validate();
56018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkASSERT(child != this);
561bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
56218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (child == NULL || fFirstChild == child)
56318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        goto DONE;
564bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
56518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    child->ref();
56618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    child->detachFromParent_NoLayout();
567bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5683d978075f2db743a197e42486483a11ab780e409reed@google.com    if (fFirstChild == NULL) {
56918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        child->fNextSibling = child;
57018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        child->fPrevSibling = child;
5713d978075f2db743a197e42486483a11ab780e409reed@google.com    } else {
57218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        child->fNextSibling = fFirstChild;
57318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        child->fPrevSibling = fFirstChild->fPrevSibling;
57418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fFirstChild->fPrevSibling->fNextSibling = child;
57518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fFirstChild->fPrevSibling = child;
57618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
577bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
57818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fFirstChild = child;
57918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    child->fParent = this;
58018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    child->inval(NULL);
581bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5823d978075f2db743a197e42486483a11ab780e409reed@google.com    this->validate();
58318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->invokeLayout();
584bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comDONE:
58518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return child;
586bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
587bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5883d978075f2db743a197e42486483a11ab780e409reed@google.comSkView* SkView::attachChildToFront(SkView* child) {
5893d978075f2db743a197e42486483a11ab780e409reed@google.com    this->validate();
59018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkASSERT(child != this);
591bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
59218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (child == NULL || (fFirstChild && fFirstChild->fPrevSibling == child))
59318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        goto DONE;
594bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
59518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    child->ref();
59618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    child->detachFromParent_NoLayout();
597bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
5983d978075f2db743a197e42486483a11ab780e409reed@google.com    if (fFirstChild == NULL) {
59918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fFirstChild = child;
60018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        child->fNextSibling = child;
60118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        child->fPrevSibling = child;
6023d978075f2db743a197e42486483a11ab780e409reed@google.com    } else {
60318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        child->fNextSibling = fFirstChild;
60418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        child->fPrevSibling = fFirstChild->fPrevSibling;
60518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fFirstChild->fPrevSibling->fNextSibling = child;
60618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fFirstChild->fPrevSibling = child;
60718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
608bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
60918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    child->fParent = this;
61018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    child->inval(NULL);
611bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
6123d978075f2db743a197e42486483a11ab780e409reed@google.com    this->validate();
61318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->invokeLayout();
614bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comDONE:
61518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return child;
616bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
617bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
6183d978075f2db743a197e42486483a11ab780e409reed@google.comvoid SkView::detachAllChildren() {
6193d978075f2db743a197e42486483a11ab780e409reed@google.com    this->validate();
62018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    while (fFirstChild)
62118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fFirstChild->detachFromParent_NoLayout();
622bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
623bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
6243d978075f2db743a197e42486483a11ab780e409reed@google.comvoid SkView::localToGlobal(SkMatrix* matrix) const {
625f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com    if (matrix) {
626f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        matrix->reset();
627f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        const SkView* view = this;
628f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        while (view)
629f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        {
630f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com            matrix->preConcat(view->getLocalMatrix());
631f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com            matrix->preTranslate(-view->fLoc.fX, -view->fLoc.fY);
632f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com            view = view->fParent;
633f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        }
634f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com    }
635f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com}
636b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.combool SkView::globalToLocal(SkScalar x, SkScalar y, SkPoint* local) const
637bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
638b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    SkASSERT(this);
639b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com
640b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    if (NULL != local) {
641f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        SkMatrix m;
642f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        this->localToGlobal(&m);
643b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        if (!m.invert(&m)) {
644b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com            return false;
645b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        }
646f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        SkPoint p;
647f7746a409892a668b2afe365c279a29dd5033ad1reed@google.com        m.mapXY(x, y, &p);
648b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com        local->set(p.fX, p.fY);
649b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    }
650b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com
651b95d181c40ebf8d640b5a7b381f6127ee5b5d6c2robertphillips@google.com    return true;
652bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
653bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
654bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////
655bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
656dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com/*    Even if the subclass overrides onInflate, they should always be
65718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    sure to call the inherited method, so that we get called.
658bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com*/
6593d978075f2db743a197e42486483a11ab780e409reed@google.comvoid SkView::onInflate(const SkDOM& dom, const SkDOM::Node* node) {
66018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkScalar x, y;
661bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
66218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    x = this->locX();
66318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    y = this->locY();
66418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    (void)dom.findScalar(node, "x", &x);
66518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    (void)dom.findScalar(node, "y", &y);
66618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->setLoc(x, y);
667bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
66818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    x = this->width();
66918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    y = this->height();
67018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    (void)dom.findScalar(node, "width", &x);
67118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    (void)dom.findScalar(node, "height", &y);
67218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->setSize(x, y);
673bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
67418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    // inflate the flags
675bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
67618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    static const char* gFlagNames[] = {
67718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        "visible", "enabled", "focusable", "flexH", "flexV"
67818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    };
67918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkASSERT(SK_ARRAY_COUNT(gFlagNames) == kFlagShiftCount);
680bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
68118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    bool     b;
68218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    uint32_t flags = this->getFlags();
68318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    for (unsigned i = 0; i < SK_ARRAY_COUNT(gFlagNames); i++)
68418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (dom.findBool(node, gFlagNames[i], &b))
68518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            flags = SkSetClearShift(flags, b, i);
68618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->setFlags(flags);
687bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
688bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
6893d978075f2db743a197e42486483a11ab780e409reed@google.comvoid SkView::inflate(const SkDOM& dom, const SkDOM::Node* node) {
69018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->onInflate(dom, node);
691bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
692bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
6933d978075f2db743a197e42486483a11ab780e409reed@google.comvoid SkView::onPostInflate(const SkTDict<SkView*>&) {
69418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    // override in subclass as needed
695bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
696bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
6973d978075f2db743a197e42486483a11ab780e409reed@google.comvoid SkView::postInflate(const SkTDict<SkView*>& dict) {
69818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    this->onPostInflate(dict);
699bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
700dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com    B2FIter    iter(this);
701dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com    SkView*    child;
70218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    while ((child = iter.next()) != NULL)
70318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        child->postInflate(dict);
704bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
705bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
706bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////
707bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
7083d978075f2db743a197e42486483a11ab780e409reed@google.comSkView* SkView::sendEventToParents(const SkEvent& evt) {
70918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkView* parent = fParent;
710dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
7113d978075f2db743a197e42486483a11ab780e409reed@google.com    while (parent) {
7123d978075f2db743a197e42486483a11ab780e409reed@google.com        if (parent->doEvent(evt)) {
71318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            return parent;
7143d978075f2db743a197e42486483a11ab780e409reed@google.com        }
71518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        parent = parent->fParent;
71618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
71718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return NULL;
718bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
719bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
72046950312935b989f0e5c30b5ed79da4a3459de5creed@android.comSkView* SkView::sendQueryToParents(SkEvent* evt) {
72118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkView* parent = fParent;
722dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
72318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    while (parent) {
72418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (parent->doQuery(evt)) {
72518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            return parent;
72646950312935b989f0e5c30b5ed79da4a3459de5creed@android.com        }
72718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        parent = parent->fParent;
72818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
72918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return NULL;
73046950312935b989f0e5c30b5ed79da4a3459de5creed@android.com}
73146950312935b989f0e5c30b5ed79da4a3459de5creed@android.com
732bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////
733bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////
734bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
7353d978075f2db743a197e42486483a11ab780e409reed@google.comSkView::F2BIter::F2BIter(const SkView* parent) {
73618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fFirstChild = parent ? parent->fFirstChild : NULL;
73718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fChild = fFirstChild ? fFirstChild->fPrevSibling : NULL;
738bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
739bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
7403d978075f2db743a197e42486483a11ab780e409reed@google.comSkView* SkView::F2BIter::next() {
74118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkView* curr = fChild;
742bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
7433d978075f2db743a197e42486483a11ab780e409reed@google.com    if (fChild) {
7443d978075f2db743a197e42486483a11ab780e409reed@google.com        if (fChild == fFirstChild) {
74518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            fChild = NULL;
7463d978075f2db743a197e42486483a11ab780e409reed@google.com        } else {
74718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            fChild = fChild->fPrevSibling;
7483d978075f2db743a197e42486483a11ab780e409reed@google.com        }
74918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
75018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return curr;
751bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
752bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
7533d978075f2db743a197e42486483a11ab780e409reed@google.comSkView::B2FIter::B2FIter(const SkView* parent) {
75418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fFirstChild = parent ? parent->fFirstChild : NULL;
75518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    fChild = fFirstChild;
756bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
757bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
7583d978075f2db743a197e42486483a11ab780e409reed@google.comSkView* SkView::B2FIter::next() {
75918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkView* curr = fChild;
760bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
7613d978075f2db743a197e42486483a11ab780e409reed@google.com    if (fChild) {
76218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        SkView* next = fChild->fNextSibling;
76318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (next == fFirstChild)
76418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            next = NULL;
76518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        fChild = next;
76618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
76718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    return curr;
768bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
769bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
770bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////
771bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com//////////////////////////////////////////////////////////////////
772bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
773bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_DEBUG
774bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
7753d978075f2db743a197e42486483a11ab780e409reed@google.comvoid SkView::validate() const {
77668797c96334867afacbc898e965b14984e33a0a2reed@google.com//    SkASSERT(this->getRefCnt() > 0 && this->getRefCnt() < 100);
7773d978075f2db743a197e42486483a11ab780e409reed@google.com    if (fParent) {
7783d978075f2db743a197e42486483a11ab780e409reed@google.com        SkASSERT(fNextSibling);
7793d978075f2db743a197e42486483a11ab780e409reed@google.com        SkASSERT(fPrevSibling);
7803d978075f2db743a197e42486483a11ab780e409reed@google.com    } else {
7813d978075f2db743a197e42486483a11ab780e409reed@google.com        bool nextNull = NULL == fNextSibling;
7823d978075f2db743a197e42486483a11ab780e409reed@google.com        bool prevNull = NULL == fNextSibling;
7835e840fbba56349e06e5833e1bec50545b3d0dbe8reed@google.com        SkASSERT(nextNull == prevNull);
7843d978075f2db743a197e42486483a11ab780e409reed@google.com    }
7853d978075f2db743a197e42486483a11ab780e409reed@google.com}
7863d978075f2db743a197e42486483a11ab780e409reed@google.com
787bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic inline void show_if_nonzero(const char name[], SkScalar value)
788bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
78918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (value)
79018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        SkDebugf("%s=\"%g\"", name, value/65536.);
791bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
792bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
793bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic void tab(int level)
794bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
79518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    for (int i = 0; i < level; i++)
79618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        SkDebugf("    ");
797bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
798bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
799bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic void dumpview(const SkView* view, int level, bool recurse)
800bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
80118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    tab(level);
80218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
80318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    SkDebugf("<view");
80418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    show_if_nonzero(" x", view->locX());
80518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    show_if_nonzero(" y", view->locY());
80618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    show_if_nonzero(" width", view->width());
80718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    show_if_nonzero(" height", view->height());
80818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
80918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    if (recurse)
81018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
811dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        SkView::B2FIter    iter(view);
812dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        SkView*            child;
813dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com        bool            noChildren = true;
81418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
81518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        while ((child = iter.next()) != NULL)
81618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        {
81718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            if (noChildren)
81818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com                SkDebugf(">\n");
81918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            noChildren = false;
82018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            dumpview(child, level + 1, true);
82118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        }
82218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
82318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        if (!noChildren)
82418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        {
82518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            tab(level);
82618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            SkDebugf("</view>\n");
82718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        }
82818723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        else
82918723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com            goto ONELINER;
83018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
83118723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    else
83218723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    {
83318723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    ONELINER:
83418723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com        SkDebugf(" />\n");
83518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    }
836bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
837bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
838bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid SkView::dump(bool recurse) const
839bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{
84018723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    dumpview(this, 0, recurse);
841bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com}
842bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com
843bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#endif
844