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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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

mercurial