gfx/skia/trunk/src/views/SkView.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/views/SkView.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,843 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2011 Google Inc.
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +#include "SkView.h"
    1.12 +#include "SkCanvas.h"
    1.13 +
    1.14 +////////////////////////////////////////////////////////////////////////
    1.15 +
    1.16 +SkView::SkView(uint32_t flags) : fFlags(SkToU8(flags))
    1.17 +{
    1.18 +    fWidth = fHeight = 0;
    1.19 +    fLoc.set(0, 0);
    1.20 +    fParent = fFirstChild = fNextSibling = fPrevSibling = NULL;
    1.21 +    fMatrix.setIdentity();
    1.22 +    fContainsFocus = 0;
    1.23 +}
    1.24 +
    1.25 +SkView::~SkView()
    1.26 +{
    1.27 +    this->detachAllChildren();
    1.28 +}
    1.29 +
    1.30 +void SkView::setFlags(uint32_t flags)
    1.31 +{
    1.32 +    SkASSERT((flags & ~kAllFlagMasks) == 0);
    1.33 +
    1.34 +    uint32_t diff = fFlags ^ flags;
    1.35 +
    1.36 +    if (diff & kVisible_Mask)
    1.37 +        this->inval(NULL);
    1.38 +
    1.39 +    fFlags = SkToU8(flags);
    1.40 +
    1.41 +    if (diff & kVisible_Mask)
    1.42 +    {
    1.43 +        this->inval(NULL);
    1.44 +    }
    1.45 +}
    1.46 +
    1.47 +void SkView::setVisibleP(bool pred)
    1.48 +{
    1.49 +    this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift));
    1.50 +}
    1.51 +
    1.52 +void SkView::setEnabledP(bool pred)
    1.53 +{
    1.54 +    this->setFlags(SkSetClearShift(fFlags, pred, kEnabled_Shift));
    1.55 +}
    1.56 +
    1.57 +void SkView::setFocusableP(bool pred)
    1.58 +{
    1.59 +    this->setFlags(SkSetClearShift(fFlags, pred, kFocusable_Shift));
    1.60 +}
    1.61 +
    1.62 +void SkView::setClipToBounds(bool pred) {
    1.63 +    this->setFlags(SkSetClearShift(fFlags, !pred, kNoClip_Shift));
    1.64 +}
    1.65 +
    1.66 +void SkView::setSize(SkScalar width, SkScalar height)
    1.67 +{
    1.68 +    width = SkMaxScalar(0, width);
    1.69 +    height = SkMaxScalar(0, height);
    1.70 +
    1.71 +    if (fWidth != width || fHeight != height)
    1.72 +    {
    1.73 +        this->inval(NULL);
    1.74 +        fWidth = width;
    1.75 +        fHeight = height;
    1.76 +        this->inval(NULL);
    1.77 +        this->onSizeChange();
    1.78 +        this->invokeLayout();
    1.79 +    }
    1.80 +}
    1.81 +
    1.82 +void SkView::setLoc(SkScalar x, SkScalar y)
    1.83 +{
    1.84 +    if (fLoc.fX != x || fLoc.fY != y)
    1.85 +    {
    1.86 +        this->inval(NULL);
    1.87 +        fLoc.set(x, y);
    1.88 +        this->inval(NULL);
    1.89 +    }
    1.90 +}
    1.91 +
    1.92 +void SkView::offset(SkScalar dx, SkScalar dy)
    1.93 +{
    1.94 +    if (dx || dy)
    1.95 +        this->setLoc(fLoc.fX + dx, fLoc.fY + dy);
    1.96 +}
    1.97 +
    1.98 +void SkView::setLocalMatrix(const SkMatrix& matrix)
    1.99 +{
   1.100 +    this->inval(NULL);
   1.101 +    fMatrix = matrix;
   1.102 +    this->inval(NULL);
   1.103 +}
   1.104 +
   1.105 +void SkView::draw(SkCanvas* canvas)
   1.106 +{
   1.107 +    if (fWidth && fHeight && this->isVisible())
   1.108 +    {
   1.109 +        SkRect    r;
   1.110 +        r.set(fLoc.fX, fLoc.fY, fLoc.fX + fWidth, fLoc.fY + fHeight);
   1.111 +        if (this->isClipToBounds() &&
   1.112 +            canvas->quickReject(r)) {
   1.113 +                return;
   1.114 +        }
   1.115 +
   1.116 +        SkAutoCanvasRestore    as(canvas, true);
   1.117 +
   1.118 +        if (this->isClipToBounds()) {
   1.119 +            canvas->clipRect(r);
   1.120 +        }
   1.121 +
   1.122 +        canvas->translate(fLoc.fX, fLoc.fY);
   1.123 +        canvas->concat(fMatrix);
   1.124 +
   1.125 +        if (fParent) {
   1.126 +            fParent->beforeChild(this, canvas);
   1.127 +        }
   1.128 +
   1.129 +        int sc = canvas->save();
   1.130 +        this->onDraw(canvas);
   1.131 +        canvas->restoreToCount(sc);
   1.132 +
   1.133 +        if (fParent) {
   1.134 +            fParent->afterChild(this, canvas);
   1.135 +        }
   1.136 +
   1.137 +        B2FIter    iter(this);
   1.138 +        SkView*    child;
   1.139 +
   1.140 +        SkCanvas* childCanvas = this->beforeChildren(canvas);
   1.141 +
   1.142 +        while ((child = iter.next()) != NULL)
   1.143 +            child->draw(childCanvas);
   1.144 +
   1.145 +        this->afterChildren(canvas);
   1.146 +    }
   1.147 +}
   1.148 +
   1.149 +void SkView::inval(SkRect* rect) {
   1.150 +    SkView*    view = this;
   1.151 +    SkRect storage;
   1.152 +
   1.153 +    for (;;) {
   1.154 +        if (!view->isVisible()) {
   1.155 +            return;
   1.156 +        }
   1.157 +        if (view->isClipToBounds()) {
   1.158 +            SkRect bounds;
   1.159 +            view->getLocalBounds(&bounds);
   1.160 +            if (rect && !bounds.intersect(*rect)) {
   1.161 +                return;
   1.162 +            }
   1.163 +            storage = bounds;
   1.164 +            rect = &storage;
   1.165 +        }
   1.166 +        if (view->handleInval(rect)) {
   1.167 +            return;
   1.168 +        }
   1.169 +
   1.170 +        SkView* parent = view->fParent;
   1.171 +        if (parent == NULL) {
   1.172 +            return;
   1.173 +        }
   1.174 +
   1.175 +        if (rect) {
   1.176 +            rect->offset(view->fLoc.fX, view->fLoc.fY);
   1.177 +        }
   1.178 +        view = parent;
   1.179 +    }
   1.180 +}
   1.181 +
   1.182 +////////////////////////////////////////////////////////////////////////////
   1.183 +
   1.184 +bool SkView::setFocusView(SkView* fv)
   1.185 +{
   1.186 +    SkView* view = this;
   1.187 +
   1.188 +    do {
   1.189 +        if (view->onSetFocusView(fv))
   1.190 +            return true;
   1.191 +    } while ((view = view->fParent) != NULL);
   1.192 +    return false;
   1.193 +}
   1.194 +
   1.195 +SkView* SkView::getFocusView() const
   1.196 +{
   1.197 +    SkView*            focus = NULL;
   1.198 +    const SkView*    view = this;
   1.199 +    do {
   1.200 +        if (view->onGetFocusView(&focus))
   1.201 +            break;
   1.202 +    } while ((view = view->fParent) != NULL);
   1.203 +    return focus;
   1.204 +}
   1.205 +
   1.206 +bool SkView::hasFocus() const
   1.207 +{
   1.208 +    return this == this->getFocusView();
   1.209 +}
   1.210 +
   1.211 +bool SkView::acceptFocus()
   1.212 +{
   1.213 +    return this->isFocusable() && this->setFocusView(this);
   1.214 +}
   1.215 +
   1.216 +/*
   1.217 +    Try to give focus to this view, or its children
   1.218 +*/
   1.219 +SkView* SkView::acceptFocus(FocusDirection dir)
   1.220 +{
   1.221 +    if (dir == kNext_FocusDirection)
   1.222 +    {
   1.223 +        if (this->acceptFocus())
   1.224 +            return this;
   1.225 +
   1.226 +        B2FIter    iter(this);
   1.227 +        SkView*    child, *focus;
   1.228 +        while ((child = iter.next()) != NULL)
   1.229 +            if ((focus = child->acceptFocus(dir)) != NULL)
   1.230 +                return focus;
   1.231 +    }
   1.232 +    else // prev
   1.233 +    {
   1.234 +        F2BIter    iter(this);
   1.235 +        SkView*    child, *focus;
   1.236 +        while ((child = iter.next()) != NULL)
   1.237 +            if ((focus = child->acceptFocus(dir)) != NULL)
   1.238 +                return focus;
   1.239 +
   1.240 +        if (this->acceptFocus())
   1.241 +            return this;
   1.242 +    }
   1.243 +
   1.244 +    return NULL;
   1.245 +}
   1.246 +
   1.247 +SkView* SkView::moveFocus(FocusDirection dir)
   1.248 +{
   1.249 +    SkView* focus = this->getFocusView();
   1.250 +
   1.251 +    if (focus == NULL)
   1.252 +    {    // start with the root
   1.253 +        focus = this;
   1.254 +        while (focus->fParent)
   1.255 +            focus = focus->fParent;
   1.256 +    }
   1.257 +
   1.258 +    SkView*    child, *parent;
   1.259 +
   1.260 +    if (dir == kNext_FocusDirection)
   1.261 +    {
   1.262 +        parent = focus;
   1.263 +        child = focus->fFirstChild;
   1.264 +        if (child)
   1.265 +            goto FIRST_CHILD;
   1.266 +        else
   1.267 +            goto NEXT_SIB;
   1.268 +
   1.269 +        do {
   1.270 +            while (child != parent->fFirstChild)
   1.271 +            {
   1.272 +    FIRST_CHILD:
   1.273 +                if ((focus = child->acceptFocus(dir)) != NULL)
   1.274 +                    return focus;
   1.275 +                child = child->fNextSibling;
   1.276 +            }
   1.277 +    NEXT_SIB:
   1.278 +            child = parent->fNextSibling;
   1.279 +            parent = parent->fParent;
   1.280 +        } while (parent != NULL);
   1.281 +    }
   1.282 +    else    // prevfocus
   1.283 +    {
   1.284 +        parent = focus->fParent;
   1.285 +        if (parent == NULL)    // we're the root
   1.286 +            return focus->acceptFocus(dir);
   1.287 +        else
   1.288 +        {
   1.289 +            child = focus;
   1.290 +            while (parent)
   1.291 +            {
   1.292 +                while (child != parent->fFirstChild)
   1.293 +                {
   1.294 +                    child = child->fPrevSibling;
   1.295 +                    if ((focus = child->acceptFocus(dir)) != NULL)
   1.296 +                        return focus;
   1.297 +                }
   1.298 +                if (parent->acceptFocus())
   1.299 +                    return parent;
   1.300 +
   1.301 +                child = parent;
   1.302 +                parent = parent->fParent;
   1.303 +            }
   1.304 +        }
   1.305 +    }
   1.306 +    return NULL;
   1.307 +}
   1.308 +
   1.309 +void SkView::onFocusChange(bool gainFocusP)
   1.310 +{
   1.311 +    this->inval(NULL);
   1.312 +}
   1.313 +
   1.314 +////////////////////////////////////////////////////////////////////////////
   1.315 +
   1.316 +SkView::Click::Click(SkView* target)
   1.317 +{
   1.318 +    SkASSERT(target);
   1.319 +    fTargetID = target->getSinkID();
   1.320 +    fType = NULL;
   1.321 +    fWeOwnTheType = false;
   1.322 +    fOwner = NULL;
   1.323 +}
   1.324 +
   1.325 +SkView::Click::~Click()
   1.326 +{
   1.327 +    this->resetType();
   1.328 +}
   1.329 +
   1.330 +void SkView::Click::resetType()
   1.331 +{
   1.332 +    if (fWeOwnTheType)
   1.333 +    {
   1.334 +        sk_free(fType);
   1.335 +        fWeOwnTheType = false;
   1.336 +    }
   1.337 +    fType = NULL;
   1.338 +}
   1.339 +
   1.340 +bool SkView::Click::isType(const char type[]) const
   1.341 +{
   1.342 +    const char* t = fType;
   1.343 +
   1.344 +    if (type == t)
   1.345 +        return true;
   1.346 +
   1.347 +    if (type == NULL)
   1.348 +        type = "";
   1.349 +    if (t == NULL)
   1.350 +        t = "";
   1.351 +    return !strcmp(t, type);
   1.352 +}
   1.353 +
   1.354 +void SkView::Click::setType(const char type[])
   1.355 +{
   1.356 +    this->resetType();
   1.357 +    fType = (char*)type;
   1.358 +}
   1.359 +
   1.360 +void SkView::Click::copyType(const char type[])
   1.361 +{
   1.362 +    if (fType != type)
   1.363 +    {
   1.364 +        this->resetType();
   1.365 +        if (type)
   1.366 +        {
   1.367 +            size_t    len = strlen(type) + 1;
   1.368 +            fType = (char*)sk_malloc_throw(len);
   1.369 +            memcpy(fType, type, len);
   1.370 +            fWeOwnTheType = true;
   1.371 +        }
   1.372 +    }
   1.373 +}
   1.374 +
   1.375 +SkView::Click* SkView::findClickHandler(SkScalar x, SkScalar y, unsigned modi) {
   1.376 +    if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) {
   1.377 +        return NULL;
   1.378 +    }
   1.379 +
   1.380 +    if (this->onSendClickToChildren(x, y, modi)) {
   1.381 +        F2BIter    iter(this);
   1.382 +        SkView*    child;
   1.383 +
   1.384 +        while ((child = iter.next()) != NULL)
   1.385 +        {
   1.386 +            SkPoint p;
   1.387 +            if (!child->globalToLocal(x, y, &p)) {
   1.388 +                continue;
   1.389 +            }
   1.390 +
   1.391 +            Click* click = child->findClickHandler(p.fX, p.fY, modi);
   1.392 +
   1.393 +            if (click) {
   1.394 +                return click;
   1.395 +            }
   1.396 +        }
   1.397 +    }
   1.398 +
   1.399 +    return this->onFindClickHandler(x, y, modi);
   1.400 +}
   1.401 +
   1.402 +void SkView::DoClickDown(Click* click, int x, int y, unsigned modi)
   1.403 +{
   1.404 +    SkASSERT(click);
   1.405 +
   1.406 +    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
   1.407 +    if (NULL == target) {
   1.408 +        return;
   1.409 +    }
   1.410 +
   1.411 +    click->fIOrig.set(x, y);
   1.412 +    click->fICurr = click->fIPrev = click->fIOrig;
   1.413 +
   1.414 +    click->fOrig.iset(x, y);
   1.415 +    if (!target->globalToLocal(&click->fOrig)) {
   1.416 +        // no history to let us recover from this failure
   1.417 +        return;
   1.418 +    }
   1.419 +    click->fPrev = click->fCurr = click->fOrig;
   1.420 +
   1.421 +    click->fState = Click::kDown_State;
   1.422 +    click->fModifierKeys = modi;
   1.423 +    target->onClick(click);
   1.424 +}
   1.425 +
   1.426 +void SkView::DoClickMoved(Click* click, int x, int y, unsigned modi)
   1.427 +{
   1.428 +    SkASSERT(click);
   1.429 +
   1.430 +    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
   1.431 +    if (NULL == target) {
   1.432 +        return;
   1.433 +    }
   1.434 +
   1.435 +    click->fIPrev = click->fICurr;
   1.436 +    click->fICurr.set(x, y);
   1.437 +
   1.438 +    click->fPrev = click->fCurr;
   1.439 +    click->fCurr.iset(x, y);
   1.440 +    if (!target->globalToLocal(&click->fCurr)) {
   1.441 +        // on failure pretend the mouse didn't move
   1.442 +        click->fCurr = click->fPrev;
   1.443 +    }
   1.444 +
   1.445 +    click->fState = Click::kMoved_State;
   1.446 +    click->fModifierKeys = modi;
   1.447 +    target->onClick(click);
   1.448 +}
   1.449 +
   1.450 +void SkView::DoClickUp(Click* click, int x, int y, unsigned modi)
   1.451 +{
   1.452 +    SkASSERT(click);
   1.453 +
   1.454 +    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
   1.455 +    if (NULL == target) {
   1.456 +        return;
   1.457 +    }
   1.458 +
   1.459 +    click->fIPrev = click->fICurr;
   1.460 +    click->fICurr.set(x, y);
   1.461 +
   1.462 +    click->fPrev = click->fCurr;
   1.463 +    click->fCurr.iset(x, y);
   1.464 +    if (!target->globalToLocal(&click->fCurr)) {
   1.465 +        // on failure pretend the mouse didn't move
   1.466 +        click->fCurr = click->fPrev;
   1.467 +    }
   1.468 +
   1.469 +    click->fState = Click::kUp_State;
   1.470 +    click->fModifierKeys = modi;
   1.471 +    target->onClick(click);
   1.472 +}
   1.473 +
   1.474 +//////////////////////////////////////////////////////////////////////
   1.475 +
   1.476 +void SkView::invokeLayout() {
   1.477 +    SkView::Layout* layout = this->getLayout();
   1.478 +
   1.479 +    if (layout) {
   1.480 +        layout->layoutChildren(this);
   1.481 +    }
   1.482 +}
   1.483 +
   1.484 +void SkView::onDraw(SkCanvas* canvas) {
   1.485 +    Artist* artist = this->getArtist();
   1.486 +
   1.487 +    if (artist) {
   1.488 +        artist->draw(this, canvas);
   1.489 +    }
   1.490 +}
   1.491 +
   1.492 +void SkView::onSizeChange() {}
   1.493 +
   1.494 +bool SkView::onSendClickToChildren(SkScalar x, SkScalar y, unsigned modi) {
   1.495 +    return true;
   1.496 +}
   1.497 +
   1.498 +SkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
   1.499 +    return NULL;
   1.500 +}
   1.501 +
   1.502 +bool SkView::onClick(Click*) {
   1.503 +    return false;
   1.504 +}
   1.505 +
   1.506 +bool SkView::handleInval(const SkRect*) {
   1.507 +    return false;
   1.508 +}
   1.509 +
   1.510 +//////////////////////////////////////////////////////////////////////
   1.511 +
   1.512 +void SkView::getLocalBounds(SkRect* bounds) const {
   1.513 +    if (bounds) {
   1.514 +        bounds->set(0, 0, fWidth, fHeight);
   1.515 +    }
   1.516 +}
   1.517 +
   1.518 +//////////////////////////////////////////////////////////////////////
   1.519 +//////////////////////////////////////////////////////////////////////
   1.520 +
   1.521 +void SkView::detachFromParent_NoLayout() {
   1.522 +    this->validate();
   1.523 +    if (fParent == NULL) {
   1.524 +        return;
   1.525 +    }
   1.526 +
   1.527 +    if (fContainsFocus) {
   1.528 +        (void)this->setFocusView(NULL);
   1.529 +    }
   1.530 +
   1.531 +    this->inval(NULL);
   1.532 +
   1.533 +    SkView* next = NULL;
   1.534 +
   1.535 +    if (fNextSibling != this) {   // do we have any siblings
   1.536 +        fNextSibling->fPrevSibling = fPrevSibling;
   1.537 +        fPrevSibling->fNextSibling = fNextSibling;
   1.538 +        next = fNextSibling;
   1.539 +    }
   1.540 +
   1.541 +    if (fParent->fFirstChild == this) {
   1.542 +        fParent->fFirstChild = next;
   1.543 +    }
   1.544 +
   1.545 +    fParent = fNextSibling = fPrevSibling = NULL;
   1.546 +
   1.547 +    this->validate();
   1.548 +    this->unref();
   1.549 +}
   1.550 +
   1.551 +void SkView::detachFromParent() {
   1.552 +    this->validate();
   1.553 +    SkView* parent = fParent;
   1.554 +
   1.555 +    if (parent) {
   1.556 +        this->detachFromParent_NoLayout();
   1.557 +        parent->invokeLayout();
   1.558 +    }
   1.559 +}
   1.560 +
   1.561 +SkView* SkView::attachChildToBack(SkView* child) {
   1.562 +    this->validate();
   1.563 +    SkASSERT(child != this);
   1.564 +
   1.565 +    if (child == NULL || fFirstChild == child)
   1.566 +        goto DONE;
   1.567 +
   1.568 +    child->ref();
   1.569 +    child->detachFromParent_NoLayout();
   1.570 +
   1.571 +    if (fFirstChild == NULL) {
   1.572 +        child->fNextSibling = child;
   1.573 +        child->fPrevSibling = child;
   1.574 +    } else {
   1.575 +        child->fNextSibling = fFirstChild;
   1.576 +        child->fPrevSibling = fFirstChild->fPrevSibling;
   1.577 +        fFirstChild->fPrevSibling->fNextSibling = child;
   1.578 +        fFirstChild->fPrevSibling = child;
   1.579 +    }
   1.580 +
   1.581 +    fFirstChild = child;
   1.582 +    child->fParent = this;
   1.583 +    child->inval(NULL);
   1.584 +
   1.585 +    this->validate();
   1.586 +    this->invokeLayout();
   1.587 +DONE:
   1.588 +    return child;
   1.589 +}
   1.590 +
   1.591 +SkView* SkView::attachChildToFront(SkView* child) {
   1.592 +    this->validate();
   1.593 +    SkASSERT(child != this);
   1.594 +
   1.595 +    if (child == NULL || (fFirstChild && fFirstChild->fPrevSibling == child))
   1.596 +        goto DONE;
   1.597 +
   1.598 +    child->ref();
   1.599 +    child->detachFromParent_NoLayout();
   1.600 +
   1.601 +    if (fFirstChild == NULL) {
   1.602 +        fFirstChild = child;
   1.603 +        child->fNextSibling = child;
   1.604 +        child->fPrevSibling = child;
   1.605 +    } else {
   1.606 +        child->fNextSibling = fFirstChild;
   1.607 +        child->fPrevSibling = fFirstChild->fPrevSibling;
   1.608 +        fFirstChild->fPrevSibling->fNextSibling = child;
   1.609 +        fFirstChild->fPrevSibling = child;
   1.610 +    }
   1.611 +
   1.612 +    child->fParent = this;
   1.613 +    child->inval(NULL);
   1.614 +
   1.615 +    this->validate();
   1.616 +    this->invokeLayout();
   1.617 +DONE:
   1.618 +    return child;
   1.619 +}
   1.620 +
   1.621 +void SkView::detachAllChildren() {
   1.622 +    this->validate();
   1.623 +    while (fFirstChild)
   1.624 +        fFirstChild->detachFromParent_NoLayout();
   1.625 +}
   1.626 +
   1.627 +void SkView::localToGlobal(SkMatrix* matrix) const {
   1.628 +    if (matrix) {
   1.629 +        matrix->reset();
   1.630 +        const SkView* view = this;
   1.631 +        while (view)
   1.632 +        {
   1.633 +            matrix->preConcat(view->getLocalMatrix());
   1.634 +            matrix->preTranslate(-view->fLoc.fX, -view->fLoc.fY);
   1.635 +            view = view->fParent;
   1.636 +        }
   1.637 +    }
   1.638 +}
   1.639 +bool SkView::globalToLocal(SkScalar x, SkScalar y, SkPoint* local) const
   1.640 +{
   1.641 +    SkASSERT(this);
   1.642 +
   1.643 +    if (NULL != local) {
   1.644 +        SkMatrix m;
   1.645 +        this->localToGlobal(&m);
   1.646 +        if (!m.invert(&m)) {
   1.647 +            return false;
   1.648 +        }
   1.649 +        SkPoint p;
   1.650 +        m.mapXY(x, y, &p);
   1.651 +        local->set(p.fX, p.fY);
   1.652 +    }
   1.653 +
   1.654 +    return true;
   1.655 +}
   1.656 +
   1.657 +//////////////////////////////////////////////////////////////////
   1.658 +
   1.659 +/*    Even if the subclass overrides onInflate, they should always be
   1.660 +    sure to call the inherited method, so that we get called.
   1.661 +*/
   1.662 +void SkView::onInflate(const SkDOM& dom, const SkDOM::Node* node) {
   1.663 +    SkScalar x, y;
   1.664 +
   1.665 +    x = this->locX();
   1.666 +    y = this->locY();
   1.667 +    (void)dom.findScalar(node, "x", &x);
   1.668 +    (void)dom.findScalar(node, "y", &y);
   1.669 +    this->setLoc(x, y);
   1.670 +
   1.671 +    x = this->width();
   1.672 +    y = this->height();
   1.673 +    (void)dom.findScalar(node, "width", &x);
   1.674 +    (void)dom.findScalar(node, "height", &y);
   1.675 +    this->setSize(x, y);
   1.676 +
   1.677 +    // inflate the flags
   1.678 +
   1.679 +    static const char* gFlagNames[] = {
   1.680 +        "visible", "enabled", "focusable", "flexH", "flexV"
   1.681 +    };
   1.682 +    SkASSERT(SK_ARRAY_COUNT(gFlagNames) == kFlagShiftCount);
   1.683 +
   1.684 +    bool     b;
   1.685 +    uint32_t flags = this->getFlags();
   1.686 +    for (unsigned i = 0; i < SK_ARRAY_COUNT(gFlagNames); i++)
   1.687 +        if (dom.findBool(node, gFlagNames[i], &b))
   1.688 +            flags = SkSetClearShift(flags, b, i);
   1.689 +    this->setFlags(flags);
   1.690 +}
   1.691 +
   1.692 +void SkView::inflate(const SkDOM& dom, const SkDOM::Node* node) {
   1.693 +    this->onInflate(dom, node);
   1.694 +}
   1.695 +
   1.696 +void SkView::onPostInflate(const SkTDict<SkView*>&) {
   1.697 +    // override in subclass as needed
   1.698 +}
   1.699 +
   1.700 +void SkView::postInflate(const SkTDict<SkView*>& dict) {
   1.701 +    this->onPostInflate(dict);
   1.702 +
   1.703 +    B2FIter    iter(this);
   1.704 +    SkView*    child;
   1.705 +    while ((child = iter.next()) != NULL)
   1.706 +        child->postInflate(dict);
   1.707 +}
   1.708 +
   1.709 +//////////////////////////////////////////////////////////////////
   1.710 +
   1.711 +SkView* SkView::sendEventToParents(const SkEvent& evt) {
   1.712 +    SkView* parent = fParent;
   1.713 +
   1.714 +    while (parent) {
   1.715 +        if (parent->doEvent(evt)) {
   1.716 +            return parent;
   1.717 +        }
   1.718 +        parent = parent->fParent;
   1.719 +    }
   1.720 +    return NULL;
   1.721 +}
   1.722 +
   1.723 +SkView* SkView::sendQueryToParents(SkEvent* evt) {
   1.724 +    SkView* parent = fParent;
   1.725 +
   1.726 +    while (parent) {
   1.727 +        if (parent->doQuery(evt)) {
   1.728 +            return parent;
   1.729 +        }
   1.730 +        parent = parent->fParent;
   1.731 +    }
   1.732 +    return NULL;
   1.733 +}
   1.734 +
   1.735 +//////////////////////////////////////////////////////////////////
   1.736 +//////////////////////////////////////////////////////////////////
   1.737 +
   1.738 +SkView::F2BIter::F2BIter(const SkView* parent) {
   1.739 +    fFirstChild = parent ? parent->fFirstChild : NULL;
   1.740 +    fChild = fFirstChild ? fFirstChild->fPrevSibling : NULL;
   1.741 +}
   1.742 +
   1.743 +SkView* SkView::F2BIter::next() {
   1.744 +    SkView* curr = fChild;
   1.745 +
   1.746 +    if (fChild) {
   1.747 +        if (fChild == fFirstChild) {
   1.748 +            fChild = NULL;
   1.749 +        } else {
   1.750 +            fChild = fChild->fPrevSibling;
   1.751 +        }
   1.752 +    }
   1.753 +    return curr;
   1.754 +}
   1.755 +
   1.756 +SkView::B2FIter::B2FIter(const SkView* parent) {
   1.757 +    fFirstChild = parent ? parent->fFirstChild : NULL;
   1.758 +    fChild = fFirstChild;
   1.759 +}
   1.760 +
   1.761 +SkView* SkView::B2FIter::next() {
   1.762 +    SkView* curr = fChild;
   1.763 +
   1.764 +    if (fChild) {
   1.765 +        SkView* next = fChild->fNextSibling;
   1.766 +        if (next == fFirstChild)
   1.767 +            next = NULL;
   1.768 +        fChild = next;
   1.769 +    }
   1.770 +    return curr;
   1.771 +}
   1.772 +
   1.773 +//////////////////////////////////////////////////////////////////
   1.774 +//////////////////////////////////////////////////////////////////
   1.775 +
   1.776 +#ifdef SK_DEBUG
   1.777 +
   1.778 +void SkView::validate() const {
   1.779 +//    SkASSERT(this->getRefCnt() > 0 && this->getRefCnt() < 100);
   1.780 +    if (fParent) {
   1.781 +        SkASSERT(fNextSibling);
   1.782 +        SkASSERT(fPrevSibling);
   1.783 +    } else {
   1.784 +        bool nextNull = NULL == fNextSibling;
   1.785 +        bool prevNull = NULL == fNextSibling;
   1.786 +        SkASSERT(nextNull == prevNull);
   1.787 +    }
   1.788 +}
   1.789 +
   1.790 +static inline void show_if_nonzero(const char name[], SkScalar value)
   1.791 +{
   1.792 +    if (value)
   1.793 +        SkDebugf("%s=\"%g\"", name, value/65536.);
   1.794 +}
   1.795 +
   1.796 +static void tab(int level)
   1.797 +{
   1.798 +    for (int i = 0; i < level; i++)
   1.799 +        SkDebugf("    ");
   1.800 +}
   1.801 +
   1.802 +static void dumpview(const SkView* view, int level, bool recurse)
   1.803 +{
   1.804 +    tab(level);
   1.805 +
   1.806 +    SkDebugf("<view");
   1.807 +    show_if_nonzero(" x", view->locX());
   1.808 +    show_if_nonzero(" y", view->locY());
   1.809 +    show_if_nonzero(" width", view->width());
   1.810 +    show_if_nonzero(" height", view->height());
   1.811 +
   1.812 +    if (recurse)
   1.813 +    {
   1.814 +        SkView::B2FIter    iter(view);
   1.815 +        SkView*            child;
   1.816 +        bool            noChildren = true;
   1.817 +
   1.818 +        while ((child = iter.next()) != NULL)
   1.819 +        {
   1.820 +            if (noChildren)
   1.821 +                SkDebugf(">\n");
   1.822 +            noChildren = false;
   1.823 +            dumpview(child, level + 1, true);
   1.824 +        }
   1.825 +
   1.826 +        if (!noChildren)
   1.827 +        {
   1.828 +            tab(level);
   1.829 +            SkDebugf("</view>\n");
   1.830 +        }
   1.831 +        else
   1.832 +            goto ONELINER;
   1.833 +    }
   1.834 +    else
   1.835 +    {
   1.836 +    ONELINER:
   1.837 +        SkDebugf(" />\n");
   1.838 +    }
   1.839 +}
   1.840 +
   1.841 +void SkView::dump(bool recurse) const
   1.842 +{
   1.843 +    dumpview(this, 0, recurse);
   1.844 +}
   1.845 +
   1.846 +#endif

mercurial