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 17 SkEvent* SkListSource::getEvent(int index) 18 { 19 return NULL; 20 } 21 22 #include "SkOSFile.h" 23 24 class SkDirListSource : public SkListSource { 25 public: 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 98 private: 99 SkString fPath, fSuffix; 100 SkString fTarget; 101 SkOSFile::Iter fIter; 102 int fCount; 103 int fIndex; 104 }; 105 106 SkListSource* SkListSource::CreateFromDir(const char path[], const char suffix[], const char target[]) 107 { 108 return new SkDirListSource(path, suffix, target); 109 } 110 111 ////////////////////////////////////////////////////////////////// 112 113 class SkDOMListSource : public SkListSource { 114 public: 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 196 private: 197 int fCount; 198 ItemRec* fList; 199 SkString fDirTail; 200 }; 201 202 SkListSource* SkListSource::CreateFromDOM(const SkDOM& dom, const SkDOM::Node* node) 203 { 204 return new SkDOMListSource(dom, node); 205 } 206 207 ////////////////////////////////////////////////////////////////// 208 ////////////////////////////////////////////////////////////////// 209 210 SkListView::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 226 SkListView::~SkListView() 227 { 228 delete[] fStrCache; 229 fSource->safeUnref(); 230 } 231 232 void 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 244 void 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 262 void 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 275 void 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 288 void SkListView::invalSelection() 289 { 290 SkRect r; 291 if (this->getRowRect(fCurrIndex, &r)) 292 this->inval(&r); 293 } 294 295 void 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 318 bool 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 336 SkPaint& SkListView::paint(Attr attr) 337 { 338 SkASSERT((unsigned)attr < kAttrCount); 339 return fPaint[attr]; 340 } 341 342 SkListSource* 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 354 void 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 402 void 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 419 void SkListView::dirtyStrCache() 420 { 421 if (fStrCache) 422 { 423 delete[] fStrCache; 424 fStrCache = NULL; 425 } 426 } 427 428 void 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 440 bool 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 474 void 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 518 class SkScrollBarView : public SkView { 519 public: 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 } 533 protected: 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 } 545 private: 546 SkBitmapRef* fBGRef, *fFGRef; 547 }; 548 549 SkGridView::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 566 SkGridView::~SkGridView() 567 { 568 fSource->safeUnref(); 569 } 570 571 void SkGridView::getCellSize(SkPoint* size) const 572 { 573 if (size) 574 *size = fCellSize; 575 } 576 577 void 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 588 void 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 607 void 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 620 void 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 633 void 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 648 void 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 672 bool 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 698 SkPaint& SkGridView::paint(Attr attr) 699 { 700 SkASSERT((unsigned)attr < kAttrCount); 701 return fPaint[attr]; 702 } 703 704 SkListSource* 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 718 static 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 737 void 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 796 static 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 804 void 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 831 bool 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 863 void 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