1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "SkWidget.h" 9#include "SkCanvas.h" 10#include "SkEvent.h" 11#include "SkKey.h" 12#include "SkParsePaint.h" 13#include "SkSystemEventTypes.h" 14 15#if 0 16 17SkEvent* SkListSource::getEvent(int index) 18{ 19 return NULL; 20} 21 22#include "SkOSFile.h" 23 24class SkDirListSource : public SkListSource { 25public: 26 SkDirListSource(const char path[], const char suffix[], const char target[]) 27 : fPath(path), fSuffix(suffix), fTarget(target) 28 { 29 fCount = -1; 30 } 31 virtual int countRows() 32 { 33 if (fCount < 0) 34 { 35 fCount = 0; 36 fIter.reset(fPath.c_str(), fSuffix.c_str()); 37 while (fIter.next(NULL)) 38 fCount += 1; 39 fIter.reset(fPath.c_str(), fSuffix.c_str()); 40 fIndex = 0; 41 } 42 return fCount; 43 } 44 virtual void getRow(int index, SkString* left, SkString* right) 45 { 46 (void)this->countRows(); 47 SkASSERT((unsigned)index < (unsigned)fCount); 48 49 if (fIndex > index) 50 { 51 fIter.reset(fPath.c_str(), fSuffix.c_str()); 52 fIndex = 0; 53 } 54 55 while (fIndex < index) 56 { 57 fIter.next(NULL); 58 fIndex += 1; 59 } 60 61 if (fIter.next(left)) 62 { 63 if (left) 64 left->remove(left->size() - fSuffix.size(), fSuffix.size()); 65 } 66 else 67 { 68 if (left) 69 left->reset(); 70 } 71 if (right) // only set to ">" if we know we're on a sub-directory 72 right->reset(); 73 74 fIndex += 1; 75 } 76 virtual SkEvent* getEvent(int index) 77 { 78 SkASSERT((unsigned)index < (unsigned)fCount); 79 80 SkEvent* evt = new SkEvent(); 81 SkString label; 82 83 this->getRow(index, &label, NULL); 84 evt->setString("name", label.c_str()); 85 86 int c = fPath.c_str()[fPath.size() - 1]; 87 if (c != '/' && c != '\\') 88 label.prepend("/"); 89 label.prepend(fPath); 90 label.append(fSuffix); 91 evt->setString("path", label.c_str()); 92 evt->setS32("index", index); 93 evt->setS32("duration", 22); 94 evt->setType(fTarget); 95 return evt; 96 } 97 98private: 99 SkString fPath, fSuffix; 100 SkString fTarget; 101 SkOSFile::Iter fIter; 102 int fCount; 103 int fIndex; 104}; 105 106SkListSource* SkListSource::CreateFromDir(const char path[], const char suffix[], const char target[]) 107{ 108 return new SkDirListSource(path, suffix, target); 109} 110 111////////////////////////////////////////////////////////////////// 112 113class SkDOMListSource : public SkListSource { 114public: 115 enum Type { 116 kUnknown_Type, 117 kDir_Type, 118 kToggle_Type 119 }; 120 struct ItemRec { 121 SkString fLabel; 122 SkString fTail, fAltTail; 123 SkString fTarget; 124 Type fType; 125 }; 126 127 SkDOMListSource(const SkDOM& dom, const SkDOM::Node* node) : fDirTail(">") 128 { 129 const SkDOM::Node* child = dom.getFirstChild(node, "item"); 130 int count = 0; 131 132 while (child) 133 { 134 count += 1; 135 child = dom.getNextSibling(child, "item"); 136 } 137 138 fCount = count; 139 fList = NULL; 140 if (count) 141 { 142 ItemRec* rec = fList = new ItemRec[count]; 143 144 child = dom.getFirstChild(node, "item"); 145 while (child) 146 { 147 rec->fLabel.set(dom.findAttr(child, "label")); 148 rec->fTail.set(dom.findAttr(child, "tail")); 149 rec->fAltTail.set(dom.findAttr(child, "alt-tail")); 150 rec->fTarget.set(dom.findAttr(child, "target")); 151 rec->fType = kUnknown_Type; 152 153 int index = dom.findList(child, "type", "dir,toggle"); 154 if (index >= 0) 155 rec->fType = (Type)(index + 1); 156 157 child = dom.getNextSibling(child, "item"); 158 rec += 1; 159 } 160 } 161 } 162 virtual ~SkDOMListSource() 163 { 164 delete[] fList; 165 } 166 virtual int countRows() 167 { 168 return fCount; 169 } 170 virtual void getRow(int index, SkString* left, SkString* right) 171 { 172 SkASSERT((unsigned)index < (unsigned)fCount); 173 174 if (left) 175 *left = fList[index].fLabel; 176 if (right) 177 *right = fList[index].fType == kDir_Type ? fDirTail : fList[index].fTail; 178 } 179 virtual SkEvent* getEvent(int index) 180 { 181 SkASSERT((unsigned)index < (unsigned)fCount); 182 183 if (fList[index].fType == kDir_Type) 184 { 185 SkEvent* evt = new SkEvent(); 186 evt->setType(fList[index].fTarget); 187 evt->setFast32(index); 188 return evt; 189 } 190 if (fList[index].fType == kToggle_Type) 191 fList[index].fTail.swap(fList[index].fAltTail); 192 193 return NULL; 194 } 195 196private: 197 int fCount; 198 ItemRec* fList; 199 SkString fDirTail; 200}; 201 202SkListSource* SkListSource::CreateFromDOM(const SkDOM& dom, const SkDOM::Node* node) 203{ 204 return new SkDOMListSource(dom, node); 205} 206 207////////////////////////////////////////////////////////////////// 208////////////////////////////////////////////////////////////////// 209 210SkListView::SkListView(U32 flags) : SkWidgetView(flags) 211{ 212 fSource = NULL; 213 fScrollIndex = 0; 214 fCurrIndex = -1; 215 fRowHeight = SkIntToScalar(16); 216 fVisibleRowCount = 0; 217 fStrCache = NULL; 218 219 fPaint[kBG_Attr].setColor(0); 220 fPaint[kNormalText_Attr].setTextSize(SkIntToScalar(14)); 221 fPaint[kHiliteText_Attr].setTextSize(SkIntToScalar(14)); 222 fPaint[kHiliteText_Attr].setColor(SK_ColorWHITE); 223 fPaint[kHiliteCell_Attr].setColor(SK_ColorBLUE); 224} 225 226SkListView::~SkListView() 227{ 228 delete[] fStrCache; 229 fSource->safeUnref(); 230} 231 232void SkListView::setRowHeight(SkScalar height) 233{ 234 SkASSERT(height >= 0); 235 236 if (fRowHeight != height) 237 { 238 fRowHeight = height; 239 this->inval(NULL); 240 this->onSizeChange(); 241 } 242} 243 244void SkListView::setSelection(int index) 245{ 246 if (fCurrIndex != index) 247 { 248 this->invalSelection(); 249 fCurrIndex = index; 250 this->invalSelection(); 251 this->ensureSelectionIsVisible(); 252 253 { 254 SkEvent evt; 255 evt.setType("listview-selection"); 256 evt.setFast32(index); 257 this->sendEventToParents(evt); 258 } 259 } 260} 261 262void SkListView::moveSelectionUp() 263{ 264 if (fSource) 265 { 266 int index = fCurrIndex; 267 if (index < 0) // no selection 268 index = fSource->countRows() - 1; 269 else 270 index = SkMax32(index - 1, 0); 271 this->setSelection(index); 272 } 273} 274 275void SkListView::moveSelectionDown() 276{ 277 if (fSource) 278 { 279 int index = fCurrIndex; 280 if (index < 0) // no selection 281 index = 0; 282 else 283 index = SkMin32(index + 1, fSource->countRows() - 1); 284 this->setSelection(index); 285 } 286} 287 288void SkListView::invalSelection() 289{ 290 SkRect r; 291 if (this->getRowRect(fCurrIndex, &r)) 292 this->inval(&r); 293} 294 295void SkListView::ensureSelectionIsVisible() 296{ 297 if (fSource == NULL) 298 return; 299 300 if ((unsigned)fCurrIndex < (unsigned)fSource->countRows()) 301 { 302 int index = this->logicalToVisualIndex(fCurrIndex); 303 304 if ((unsigned)index >= (unsigned)fVisibleRowCount) // need to scroll 305 { 306 if (index < 0) // too high 307 fScrollIndex = fCurrIndex; 308 else 309 fScrollIndex = fCurrIndex - fVisibleRowCount + 1; 310 SkASSERT((unsigned)fScrollIndex < (unsigned)fSource->countRows()); 311 312 this->dirtyStrCache(); 313 this->inval(NULL); 314 } 315 } 316} 317 318bool SkListView::getRowRect(int index, SkRect* r) const 319{ 320 SkASSERT(r); 321 index = this->logicalToVisualIndex(index); 322 if (index >= 0) 323 { 324 SkScalar top = index * fRowHeight; 325 326 if (top < this->height()) 327 { 328 if (r) 329 r->set(0, top, this->width(), top + fRowHeight); 330 return true; 331 } 332 } 333 return false; 334} 335 336SkPaint& SkListView::paint(Attr attr) 337{ 338 SkASSERT((unsigned)attr < kAttrCount); 339 return fPaint[attr]; 340} 341 342SkListSource* SkListView::setListSource(SkListSource* src) 343{ 344 if (fSource != src) 345 { 346 SkRefCnt_SafeAssign(fSource, src); 347 this->dirtyStrCache(); 348 this->ensureSelectionIsVisible(); 349 this->inval(NULL); 350 } 351 return src; 352} 353 354void SkListView::onDraw(SkCanvas* canvas) 355{ 356 this->INHERITED::onDraw(canvas); 357 358 canvas->drawPaint(fPaint[kBG_Attr]); 359 360 int visibleCount = SkMin32(fVisibleRowCount, fSource->countRows() - fScrollIndex); 361 if (visibleCount == 0) 362 return; 363 364 this->ensureStrCache(visibleCount); 365 int currIndex = this->logicalToVisualIndex(fCurrIndex); 366 367 if ((unsigned)currIndex < (unsigned)visibleCount) 368 { 369 SkAutoCanvasRestore restore(canvas, true); 370 SkRect r; 371 372 canvas->translate(0, currIndex * fRowHeight); 373 (void)this->getRowRect(fScrollIndex, &r); 374 canvas->drawRect(r, fPaint[kHiliteCell_Attr]); 375 } 376 377 SkPaint* p; 378 SkScalar y, x = SkIntToScalar(6); 379 SkScalar rite = this->width() - x; 380 381 { 382 SkScalar ascent, descent; 383 fPaint[kNormalText_Attr].measureText(0, NULL, &ascent, &descent); 384 y = SkScalarHalf(fRowHeight - descent + ascent) - ascent; 385 } 386 387 for (int i = 0; i < visibleCount; i++) 388 { 389 if (i == currIndex) 390 p = &fPaint[kHiliteText_Attr]; 391 else 392 p = &fPaint[kNormalText_Attr]; 393 394 p->setTextAlign(SkPaint::kLeft_Align); 395 canvas->drawText(fStrCache[i].c_str(), fStrCache[i].size(), x, y, *p); 396 p->setTextAlign(SkPaint::kRight_Align); 397 canvas->drawText(fStrCache[i + visibleCount].c_str(), fStrCache[i + visibleCount].size(), rite, y, *p); 398 canvas->translate(0, fRowHeight); 399 } 400} 401 402void SkListView::onSizeChange() 403{ 404 SkScalar count = SkScalarDiv(this->height(), fRowHeight); 405 int n = SkScalarFloor(count); 406 407 // only want to show rows that are mostly visible 408 if (n == 0 || count - SkIntToScalar(n) > SK_Scalar1*75/100) 409 n += 1; 410 411 if (fVisibleRowCount != n) 412 { 413 fVisibleRowCount = n; 414 this->ensureSelectionIsVisible(); 415 this->dirtyStrCache(); 416 } 417} 418 419void SkListView::dirtyStrCache() 420{ 421 if (fStrCache) 422 { 423 delete[] fStrCache; 424 fStrCache = NULL; 425 } 426} 427 428void SkListView::ensureStrCache(int count) 429{ 430 if (fStrCache == NULL) 431 { 432 fStrCache = new SkString[count << 1]; 433 434 if (fSource) 435 for (int i = 0; i < count; i++) 436 fSource->getRow(i + fScrollIndex, &fStrCache[i], &fStrCache[i + count]); 437 } 438} 439 440bool SkListView::onEvent(const SkEvent& evt) 441{ 442 if (evt.isType(SK_EventType_Key)) 443 { 444 switch (evt.getFast32()) { 445 case kUp_SkKey: 446 this->moveSelectionUp(); 447 return true; 448 case kDown_SkKey: 449 this->moveSelectionDown(); 450 return true; 451 case kRight_SkKey: 452 case kOK_SkKey: 453 if (fSource && fCurrIndex >= 0) 454 { 455 SkEvent* evt = fSource->getEvent(fCurrIndex); 456 if (evt) 457 { 458 SkView* view = this->sendEventToParents(*evt); 459 delete evt; 460 return view != NULL; 461 } 462 else // hack to make toggle work 463 { 464 this->dirtyStrCache(); 465 this->inval(NULL); 466 } 467 } 468 break; 469 } 470 } 471 return this->INHERITED::onEvent(evt); 472} 473 474void SkListView::onInflate(const SkDOM& dom, const SkDOM::Node* node) 475{ 476 this->INHERITED::onInflate(dom, node); 477 478 SkScalar x; 479 const SkDOM::Node* child; 480 481 if (dom.findScalar(node, "row-height", &x)) 482 this->setRowHeight(x); 483 484 if ((child = dom.getFirstChild(node, "hilite-paint")) != NULL) 485 SkPaint_Inflate(&this->paint(kHiliteCell_Attr), dom, child); 486 487 // look for a listsource 488 { 489 SkListSource* src = NULL; 490 491 if ((child = dom.getFirstChild(node, "file-listsource")) != NULL) 492 { 493 const char* path = dom.findAttr(child, "path"); 494 if (path) 495 src = SkListSource::CreateFromDir( path, 496 dom.findAttr(child, "filter"), 497 dom.findAttr(child, "target")); 498 } 499 else if ((child = dom.getFirstChild(node, "xml-listsource")) != NULL) 500 { 501 src = SkListSource::CreateFromDOM(dom, child); 502 } 503 504 if (src) 505 { 506 this->setListSource(src)->unref(); 507 this->setSelection(0); 508 } 509 } 510} 511 512/////////////////////////////////////////////////////////////////////////////////////////// 513/////////////////////////////////////////////////////////////////////////////////////////// 514 515#include "SkImageDecoder.h" 516#include "SkShader.h" 517 518class SkScrollBarView : public SkView { 519public: 520 SkScrollBarView(const char bg[], const char fg[]) 521 { 522 fBGRef = SkBitmapRef::Decode(bg, true); 523 fFGRef = SkBitmapRef::Decode(fg, true); 524 525 if (fBGRef) 526 this->setWidth(SkIntToScalar(fBGRef->bitmap().width())); 527 } 528 ~SkScrollBarView() 529 { 530 delete fBGRef; 531 delete fFGRef; 532 } 533protected: 534 virtual void onDraw(SkCanvas* canvas) 535 { 536 if (fBGRef == NULL) return; 537 538 SkPaint paint; 539 540 SkShader* shader = SkShader::CreateBitmapShader(fBGRef->bitmap(), false, SkPaint::kNo_FilterType, SkShader::kClamp_TileMode); 541 paint.setShader(shader)->unref(); 542 543 canvas->drawPaint(paint); 544 } 545private: 546 SkBitmapRef* fBGRef, *fFGRef; 547}; 548 549SkGridView::SkGridView(U32 flags) : SkWidgetView(flags) 550{ 551 fSource = NULL; 552 fCurrIndex = -1; 553 fVisibleCount.set(0, 0); 554 555 fPaint[kBG_Attr].setColor(SK_ColorWHITE); 556 fPaint[kHiliteCell_Attr].setColor(SK_ColorYELLOW); 557 fPaint[kHiliteCell_Attr].setStyle(SkPaint::kStroke_Style); 558 fPaint[kHiliteCell_Attr].setAntiAliasOn(true); 559 fPaint[kHiliteCell_Attr].setStrokeWidth(SK_Scalar1*3); 560 561 fScrollBar = new SkScrollBarView("icons/scrollbarGrey.jpg", "icons/scrollbarBlue.jpg"); 562 this->attachChildToFront(fScrollBar)->unref(); 563 fScrollBar->setVisibleP(true); 564} 565 566SkGridView::~SkGridView() 567{ 568 fSource->safeUnref(); 569} 570 571void SkGridView::getCellSize(SkPoint* size) const 572{ 573 if (size) 574 *size = fCellSize; 575} 576 577void SkGridView::setCellSize(SkScalar x, SkScalar y) 578{ 579 SkASSERT(x >= 0 && y >= 0); 580 581 if (!fCellSize.equals(x, y)) 582 { 583 fCellSize.set(x, y); 584 this->inval(NULL); 585 } 586} 587 588void SkGridView::setSelection(int index) 589{ 590 if (fCurrIndex != index) 591 { 592 this->invalSelection(); 593 fCurrIndex = index; 594 this->invalSelection(); 595 this->ensureSelectionIsVisible(); 596 597 // this generates the click 598 { 599 SkEvent evt; 600 evt.setType("listview-selection"); 601 evt.setFast32(index); 602 this->sendEventToParents(evt); 603 } 604 } 605} 606 607void SkGridView::moveSelectionUp() 608{ 609 if (fSource) 610 { 611 int index = fCurrIndex; 612 if (index < 0) // no selection 613 index = fSource->countRows() - 1; 614 else 615 index = SkMax32(index - 1, 0); 616 this->setSelection(index); 617 } 618} 619 620void SkGridView::moveSelectionDown() 621{ 622 if (fSource) 623 { 624 int index = fCurrIndex; 625 if (index < 0) // no selection 626 index = 0; 627 else 628 index = SkMin32(index + 1, fSource->countRows() - 1); 629 this->setSelection(index); 630 } 631} 632 633void SkGridView::invalSelection() 634{ 635 SkRect r; 636 if (this->getCellRect(fCurrIndex, &r)) 637 { 638 SkScalar inset = 0; 639 if (fPaint[kHiliteCell_Attr].getStyle() != SkPaint::kFill_Style) 640 inset += fPaint[kHiliteCell_Attr].getStrokeWidth() / 2; 641 if (fPaint[kHiliteCell_Attr].isAntiAliasOn()) 642 inset += SK_Scalar1; 643 r.inset(-inset, -inset); 644 this->inval(&r); 645 } 646} 647 648void SkGridView::ensureSelectionIsVisible() 649{ 650 if (fSource == NULL) 651 return; 652#if 0 653 if ((unsigned)fCurrIndex < (unsigned)fSource->countRows()) 654 { 655 int index = this->logicalToVisualIndex(fCurrIndex); 656 657 if ((unsigned)index >= (unsigned)fVisibleRowCount) // need to scroll 658 { 659 if (index < 0) // too high 660 fScrollIndex = fCurrIndex; 661 else 662 fScrollIndex = fCurrIndex - fVisibleRowCount + 1; 663 SkASSERT((unsigned)fScrollIndex < (unsigned)fSource->countRows()); 664 665 this->dirtyStrCache(); 666 this->inval(NULL); 667 } 668 } 669#endif 670} 671 672bool SkGridView::getCellRect(int index, SkRect* r) const 673{ 674 if (fVisibleCount.fY == 0) 675 return false; 676 677 index = this->logicalToVisualIndex(index); 678 if (index >= 0) 679 { 680 SkRect bounds; 681 int row = index / fVisibleCount.fY; 682 int col = index % fVisibleCount.fY; 683 684 bounds.set(0, 0, fCellSize.fX, fCellSize.fY); 685 bounds.offset(col * (fCellSize.fX + SkIntToScalar(col > 0)), 686 row * (fCellSize.fY + SkIntToScalar(row > 0))); 687 688 if (bounds.fTop < this->height()) 689 { 690 if (r) 691 *r = bounds; 692 return true; 693 } 694 } 695 return false; 696} 697 698SkPaint& SkGridView::paint(Attr attr) 699{ 700 SkASSERT((unsigned)attr < kAttrCount); 701 return fPaint[attr]; 702} 703 704SkListSource* SkGridView::setListSource(SkListSource* src) 705{ 706 if (fSource != src) 707 { 708 SkRefCnt_SafeAssign(fSource, src); 709 // this->dirtyStrCache(); 710 this->ensureSelectionIsVisible(); 711 this->inval(NULL); 712 } 713 return src; 714} 715 716#include "SkShader.h" 717 718static void copybits(SkCanvas* canvas, const SkBitmap& bm, const SkRect& dst, const SkPaint& paint) 719{ 720 SkRect src; 721 SkMatrix matrix; 722 723 src.set(0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height())); 724 if (matrix.setRectToRect(src, dst)) 725 { 726 SkPaint p(paint); 727 SkShader* shader = SkShader::CreateBitmapShader(bm, false, SkPaint::kNo_FilterType, SkShader::kClamp_TileMode); 728 p.setShader(shader)->unref(); 729 730 shader->setLocalMatrix(matrix); 731 canvas->drawRect(dst, p); 732 } 733} 734 735#include "SkImageDecoder.h" 736 737void SkGridView::onDraw(SkCanvas* canvas) 738{ 739 this->INHERITED::onDraw(canvas); 740 741 canvas->drawPaint(fPaint[kBG_Attr]); 742 743 if (fSource == NULL) 744 return; 745 746#if 0 747 int visibleCount = SkMin32(fVisibleRowCount, fSource->countRows() - fScrollIndex); 748 if (visibleCount == 0) 749 return; 750 751 this->ensureStrCache(visibleCount); 752 int currIndex = this->logicalToVisualIndex(fCurrIndex); 753#endif 754 755 SkPaint p; 756 for (int i = 0; i < fSource->countRows(); i++) 757 { 758 bool forced = false; 759 SkEvent* evt = fSource->getEvent(i); 760 SkASSERT(evt); 761 SkString path(evt->findString("path")); 762 delete evt; 763 764 SkBitmapRef* bmr = SkBitmapRef::Decode(path.c_str(), false); 765 if (bmr == NULL) 766 { 767 bmr = SkBitmapRef::Decode(path.c_str(), true); 768 if (bmr) 769 forced = true; 770 } 771 772 if (bmr) 773 { 774 SkAutoTDelete<SkBitmapRef> autoRef(bmr); 775 SkRect r; 776 if (!this->getCellRect(i, &r)) 777 break; 778 copybits(canvas, bmr->bitmap(), r, p); 779 } 780 // only draw one forced bitmap at a time 781 if (forced) 782 { 783 this->inval(NULL); // could inval only the remaining visible cells... 784 break; 785 } 786 } 787 788 // draw the hilite 789 { 790 SkRect r; 791 if (fCurrIndex >= 0 && this->getCellRect(fCurrIndex, &r)) 792 canvas->drawRect(r, fPaint[kHiliteCell_Attr]); 793 } 794} 795 796static int check_count(int n, SkScalar s) 797{ 798 // only want to show cells that are mostly visible 799 if (n == 0 || s - SkIntToScalar(n) > SK_Scalar1*75/100) 800 n += 1; 801 return n; 802} 803 804void SkGridView::onSizeChange() 805{ 806 fScrollBar->setHeight(this->height()); 807 fScrollBar->setLoc(this->locX() + this->width() - fScrollBar->width(), 0); 808 809 if (fCellSize.equals(0, 0)) 810 { 811 fVisibleCount.set(0, 0); 812 return; 813 } 814 815 SkScalar rows = SkScalarDiv(this->height(), fCellSize.fY); 816 SkScalar cols = SkScalarDiv(this->width(), fCellSize.fX); 817 int y = SkScalarFloor(rows); 818 int x = SkScalarFloor(cols); 819 820 y = check_count(y, rows); 821 x = check_count(x, cols); 822 823 if (!fVisibleCount.equals(x, y)) 824 { 825 fVisibleCount.set(x, y); 826 this->ensureSelectionIsVisible(); 827 // this->dirtyStrCache(); 828 } 829} 830 831bool SkGridView::onEvent(const SkEvent& evt) 832{ 833 if (evt.isType(SK_EventType_Key)) 834 { 835 switch (evt.getFast32()) { 836 case kUp_SkKey: 837 this->moveSelectionUp(); 838 return true; 839 case kDown_SkKey: 840 this->moveSelectionDown(); 841 return true; 842 case kRight_SkKey: 843 case kOK_SkKey: 844 if (fSource && fCurrIndex >= 0) 845 { 846 SkEvent* evt = fSource->getEvent(fCurrIndex); 847 if (evt) 848 { 849 // augment the event with our local rect 850 (void)this->getCellRect(fCurrIndex, (SkRect*)evt->setScalars("local-rect", 4, NULL)); 851 852 SkView* view = this->sendEventToParents(*evt); 853 delete evt; 854 return view != NULL; 855 } 856 } 857 break; 858 } 859 } 860 return this->INHERITED::onEvent(evt); 861} 862 863void SkGridView::onInflate(const SkDOM& dom, const SkDOM::Node* node) 864{ 865 this->INHERITED::onInflate(dom, node); 866 867 SkScalar x[2]; 868 const SkDOM::Node* child; 869 870 if (dom.findScalars(node, "cell-size", x, 2)) 871 this->setCellSize(x[0], x[1]); 872 873 if ((child = dom.getFirstChild(node, "hilite-paint")) != NULL) 874 SkPaint_Inflate(&this->paint(kHiliteCell_Attr), dom, child); 875 876 // look for a listsource 877 { 878 SkListSource* src = NULL; 879 880 if ((child = dom.getFirstChild(node, "file-listsource")) != NULL) 881 { 882 const char* path = dom.findAttr(child, "path"); 883 if (path) 884 src = SkListSource::CreateFromDir( path, 885 dom.findAttr(child, "filter"), 886 dom.findAttr(child, "target")); 887 } 888 else if ((child = dom.getFirstChild(node, "xml-listsource")) != NULL) 889 { 890 src = SkListSource::CreateFromDOM(dom, child); 891 } 892 893 if (src) 894 { 895 this->setListSource(src)->unref(); 896 this->setSelection(0); 897 } 898 } 899 this->onSizeChange(); 900} 901 902#endif 903