11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 80b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkWidgetViews.h" 90b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkAnimator.h" 110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkScrollBarView.h" 120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerextern void init_skin_anim(const char name[], SkAnimator*); 140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstruct SkListView::BindingRec { 160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkString fSlotName; 170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int fFieldIndex; 180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}; 190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 200b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkListView::SkListView() 210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fSource = NULL; // our list-source 230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar = NULL; 240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnims = NULL; // array of animators[fVisibleRowCount] 250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBindings = NULL; // our fields->slot array 260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBindingCount = 0; // number of entries in fSlots array 270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollIndex = 0; // number of cells to skip before first visible cell 280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fCurrIndex = -1; // index of "selected" cell 290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fVisibleRowCount = 0; // number of cells that can fit in our bounds 300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimContentDirty = true; // true if fAnims[] have their correct content 310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimFocusDirty = true; 320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fHeights[kNormal_Height] = SkIntToScalar(16); 340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fHeights[kSelected_Height] = SkIntToScalar(16); 350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->setFlags(this->getFlags() | kFocusable_Mask); 370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 390b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkListView::~SkListView() 400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkSafeUnref(fScrollBar); 420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkSafeUnref(fSource); 430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger delete[] fAnims; 440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger delete[] fBindings; 450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkListView::setHasScrollBar(bool hasSB) 480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (hasSB != this->hasScrollBar()) 500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (hasSB) 520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(fScrollBar == NULL); 540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar = (SkScrollBarView*)SkWidgetFactory(kScroll_WidgetEnum); 550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar->setVisibleP(true); 560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->attachChildToFront(fScrollBar); 570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar->setHeight(this->height()); // assume it auto-sets its width 580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // fScrollBar->setLoc(this->getContentWidth(), 0); 590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar->setLoc(this->width()-SkIntToScalar(10), 0); 600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger else 620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(fScrollBar); 640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar->detachFromParent(); 650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar->unref(); 660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar = NULL; 670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->dirtyCache(kAnimContent_DirtyFlag); 690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkListView::setSelection(int index) 730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fCurrIndex != index) 750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimFocusDirty = true; 770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->inval(NULL); 780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->invalSelection(); 800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fCurrIndex = index; 810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->invalSelection(); 820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->ensureSelectionIsVisible(); 830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkListView::moveSelectionUp() 870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fSource) 890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int index = fCurrIndex; 910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (index < 0) // no selection 920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger index = fSource->countRecords() - 1; 930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger else 940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger index = SkMax32(index - 1, 0); 950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fCurrIndex != index) 970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->setSelection(index); 990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return true; 1000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return false; 1030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 1040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkListView::moveSelectionDown() 1060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 1070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fSource) 1080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 1090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int index = fCurrIndex; 1100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (index < 0) // no selection 1110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger index = 0; 1120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger else 1130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger index = SkMin32(index + 1, fSource->countRecords() - 1); 1140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fCurrIndex != index) 1160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 1170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->setSelection(index); 1180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return true; 1190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return false; 1220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 1230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkListView::invalSelection() 1250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 1260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkRect r; 1270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (this->getRowRect(fCurrIndex, &r)) 1280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->inval(&r); 1290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 1300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkListView::ensureSelectionIsVisible() 1320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 1330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fSource && (unsigned)fCurrIndex < (unsigned)fSource->countRecords()) 1340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 1350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int index = this->logicalToVisualIndex(fCurrIndex); 1360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if ((unsigned)index >= (unsigned)fVisibleRowCount) // need to scroll 1380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 1390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int newIndex; 1400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (index < 0) // too high 1420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger newIndex = fCurrIndex; 1430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger else 1440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger newIndex = fCurrIndex - fVisibleRowCount + 1; 1450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT((unsigned)newIndex < (unsigned)fSource->countRecords()); 1460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->inval(NULL); 1470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fScrollIndex != newIndex) 1490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 1500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollIndex = newIndex; 1510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fScrollBar) 1520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar->setStart(newIndex); 1530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->dirtyCache(kAnimContent_DirtyFlag); 1540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 1580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1590b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkScalar SkListView::getContentWidth() const 1600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 1610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar width = this->width(); 1620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fScrollBar) 1640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 1650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger width -= fScrollBar->width(); 1660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (width < 0) 1670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger width = 0; 1680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return width; 1700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 1710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkListView::getRowRect(int index, SkRect* r) const 1730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 1740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(r); 1750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger index = this->logicalToVisualIndex(index); 1770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (index >= 0) 1780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 1790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int selection = this->logicalToVisualIndex(fCurrIndex); 1800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar height = fHeights[index == selection ? kSelected_Height : kNormal_Height]; 1820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar top = index * fHeights[kNormal_Height]; 1830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (index > selection && selection >= 0) 1850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger top += fHeights[kSelected_Height] - fHeights[kNormal_Height]; 1860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (top < this->height()) 1880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 1890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (r) 1900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger r->set(0, top, this->getContentWidth(), top + height); 1910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return true; 1920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 1940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return false; 1950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 1960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 1970b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkListSource* SkListView::setListSource(SkListSource* src) 1980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 1990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fSource != src) 2000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkRefCnt_SafeAssign(fSource, src); 2020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->ensureSelectionIsVisible(); 2030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->inval(NULL); 2040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fScrollBar) 2060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar->setTotal(fSource->countRecords()); 2070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return src; 2090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 2100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkListView::dirtyCache(unsigned dirtyFlags) 2120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 2130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (dirtyFlags & kAnimCount_DirtyFlag) 2140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger delete fAnims; 2160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnims = NULL; 2170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimContentDirty = true; 2180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimFocusDirty = true; 2190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (dirtyFlags & kAnimContent_DirtyFlag) 2210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (!fAnimContentDirty) 2230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->inval(NULL); 2250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimContentDirty = true; 2260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimFocusDirty = true; 2280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 2300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkListView::ensureCache() 2320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 2330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fSkinName.size() == 0) 2340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return false; 2350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fAnims == NULL) 2370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int n = SkMax32(1, fVisibleRowCount); 2390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(fAnimContentDirty); 2410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnims = new SkAnimator[n]; 2420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < n; i++) 2430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnims[i].setHostEventSink(this); 2450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger init_skin_anim(fSkinName.c_str(), &fAnims[i]); 2460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fHeights[kNormal_Height] = fAnims[0].getScalar("idleHeight", "value"); 2490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fHeights[kSelected_Height] = fAnims[0].getScalar("focusedHeight", "value"); 2500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimFocusDirty = true; 2520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fAnimContentDirty && fSource) 2550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimContentDirty = false; 2570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkString str; 2590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkEvent evt("user"); 2600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger evt.setString("id", "setFields"); 2610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger evt.setS32("rowCount", fVisibleRowCount); 2620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkEvent dimEvt("user"); 2640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger dimEvt.setString("id", "setDim"); 2650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger dimEvt.setScalar("dimX", this->getContentWidth()); 2660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger dimEvt.setScalar("dimY", this->height()); 2670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = fScrollIndex; i < fScrollIndex + fVisibleRowCount; i++) 2690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger evt.setS32("relativeIndex", i - fScrollIndex); 2710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int j = 0; j < fBindingCount; j++) 2720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fSource->getRecord(i, fBindings[j].fFieldIndex, &str); 2740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger//SkDEBUGF(("getRecord(%d,%d,%s) slot(%s)\n", i, fBindings[j].fFieldIndex, str.c_str(), fBindings[j].fSlotName.c_str())); 2750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger evt.setString(fBindings[j].fSlotName.c_str(), str.c_str()); 2760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger (void)fAnims[i % fVisibleRowCount].doUserEvent(evt); 2780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger (void)fAnims[i % fVisibleRowCount].doUserEvent(dimEvt); 2790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimFocusDirty = true; 2810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fAnimFocusDirty) 2840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger//SkDEBUGF(("service fAnimFocusDirty\n")); 2860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fAnimFocusDirty = false; 2870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkEvent focusEvt("user"); 2890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger focusEvt.setString("id", "setFocus"); 2900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = fScrollIndex; i < fScrollIndex + fVisibleRowCount; i++) 2920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 2930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger focusEvt.setS32("FOCUS", i == fCurrIndex); 2940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger (void)fAnims[i % fVisibleRowCount].doUserEvent(focusEvt); 2950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 2970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 2980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return true; 2990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 3000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkListView::ensureVisibleRowCount() 3020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 3030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar height = this->height(); 3040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int n = 0; 3050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (height > 0) 3070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 3080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger n = 1; 3090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger height -= fHeights[kSelected_Height]; 3100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (height > 0) 3110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 3120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar count = SkScalarDiv(height, fHeights[kNormal_Height]); 3130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger n += SkScalarFloor(count); 3140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (count - SkIntToScalar(n) > SK_Scalar1*3/4) 3150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger n += 1; 3160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // SkDebugf("count %g, n %d\n", count/65536., n); 3180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 3190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 3200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fVisibleRowCount != n) 3220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 3230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fScrollBar) 3240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar->setShown(n); 3250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fVisibleRowCount = n; 3270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->ensureSelectionIsVisible(); 3280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->dirtyCache(kAnimCount_DirtyFlag | kAnimContent_DirtyFlag); 3290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 3300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 3310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////////// 3330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkSystemEventTypes.h" 3350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkTime.h" 3360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkListView::onSizeChange() 3380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 3390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->INHERITED::onSizeChange(); 3400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fScrollBar) 3420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fScrollBar->setLoc(this->width()-SkIntToScalar(10), 0); 3430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->ensureVisibleRowCount(); 3450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 3460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkListView::onDraw(SkCanvas* canvas) 3480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 3490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->INHERITED::onDraw(canvas); 3500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->ensureVisibleRowCount(); 3520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int visibleCount = SkMin32(fVisibleRowCount, fSource->countRecords() - fScrollIndex); 3540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (visibleCount == 0 || !this->ensureCache()) 3550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return; 3560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger//SkDebugf("visibleCount %d scrollIndex %d currIndex %d\n", visibleCount, fScrollIndex, fCurrIndex); 3580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkAutoCanvasRestore ar(canvas, true); 3600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkMSec now = SkTime::GetMSecs(); 3610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkRect bounds; 3620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger bounds.fLeft = 0; 3640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger bounds.fRight = this->getContentWidth(); 3650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger bounds.fBottom = 0; 3660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // assign bounds.fTop inside the loop 3670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // hack to reveal our bounds for debugging 3690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (this->hasFocus()) 3700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->drawARGB(0x11, 0, 0, 0xFF); 3710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger else 3720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->drawARGB(0x11, 0x88, 0x88, 0x88); 3730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = fScrollIndex; i < fScrollIndex + visibleCount; i++) 3750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 3760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkPaint paint; 3770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkScalar height = fHeights[i == fCurrIndex ? kSelected_Height : kNormal_Height]; 3780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger bounds.fTop = bounds.fBottom; 3800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger bounds.fBottom += height; 3810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->save(); 3830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fAnims[i % fVisibleRowCount].draw(canvas, &paint, now) != SkAnimator::kNotDifferent) 3840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->inval(&bounds); 3850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->restore(); 3860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger canvas->translate(0, height); 3880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 3890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 3900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 3910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerbool SkListView::onEvent(const SkEvent& evt) 3920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 3930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (evt.isType(SK_EventType_Key)) 3940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 3950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger switch (evt.getFast32()) { 3960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger case kUp_SkKey: 3970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return this->moveSelectionUp(); 3980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger case kDown_SkKey: 3990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return this->moveSelectionDown(); 4000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger case kRight_SkKey: 4010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger case kOK_SkKey: 4020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->postWidgetEvent(); 4030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return true; 4040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger default: 4050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger break; 4060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 4070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 4080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return this->INHERITED::onEvent(evt); 4090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 4100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////////// 4120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic const char gListViewEventSlot[] = "sk-listview-slot-name"; 4140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger/*virtual*/ bool SkListView::onPrepareWidgetEvent(SkEvent* evt) 4160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 4170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fSource && fCurrIndex >= 0 && this->INHERITED::onPrepareWidgetEvent(evt) && 4180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fSource->prepareWidgetEvent(evt, fCurrIndex)) 4190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 4200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger evt->setS32(gListViewEventSlot, fCurrIndex); 4210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return true; 4220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 4230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return false; 4240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 4250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerint SkListView::GetWidgetEventListIndex(const SkEvent& evt) 4270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 4280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int32_t index; 4290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return evt.findS32(gListViewEventSlot, &index) ? index : -1; 4310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 4320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////////// 4340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkListView::onInflate(const SkDOM& dom, const SkDOM::Node* node) 4360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 4370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->INHERITED::onInflate(dom, node); 4380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 4400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger bool hasScrollBar; 4410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (dom.findBool(node, "scrollBar", &hasScrollBar)) 4420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->setHasScrollBar(hasScrollBar); 4430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 4440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const SkDOM::Node* child; 4460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if ((child = dom.getFirstChild(node, "bindings")) != NULL) 4480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 4490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger delete[] fBindings; 4500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBindings = NULL; 4510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBindingCount = 0; 4520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkListSource* listSrc = SkListSource::Factory(dom.findAttr(child, "data-fields")); 4540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(listSrc); 4550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fSkinName.set(dom.findAttr(child, "skin-slots")); 4560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(fSkinName.size()); 4570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->setListSource(listSrc)->unref(); 4590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int count = dom.countChildren(child, "bind"); 4610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (count > 0) 4620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 4630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBindings = new BindingRec[count]; 4640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger count = 0; // reuse this to count up to the number of valid bindings 4650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger child = dom.getFirstChild(child, "bind"); 4670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(child); 4680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger do { 4690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const char* fieldName = dom.findAttr(child, "field"); 4700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const char* slotName = dom.findAttr(child, "slot"); 4710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fieldName && slotName) 4720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 4730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBindings[count].fFieldIndex = listSrc->findFieldIndex(fieldName); 4740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fBindings[count].fFieldIndex >= 0) 4750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBindings[count++].fSlotName.set(slotName); 4760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 4770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } while ((child = dom.getNextSibling(child, "bind")) != NULL); 4780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fBindingCount = SkToU16(count); 4800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (count == 0) 4810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 4820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkDEBUGF(("SkListView::onInflate: no valid <bind> elements in <listsource>\n")); 4830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger delete[] fBindings; 4840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 4850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 4860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->dirtyCache(kAnimCount_DirtyFlag); 4870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->setSelection(0); 4880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 4890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 4900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////////////////// 4920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////////////////// 4930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 4940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerclass SkXMLListSource : public SkListSource { 4950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerpublic: 4960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkXMLListSource(const char doc[], size_t len); 4970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual ~SkXMLListSource() 4980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 4990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger delete[] fFields; 5000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger delete[] fRecords; 5010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 5020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual int countFields() { return fFieldCount; } 5040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual void getFieldName(int index, SkString* field) 5050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 5060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT((unsigned)index < (unsigned)fFieldCount); 5070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (field) 5080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger *field = fFields[index]; 5090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 5100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual int findFieldIndex(const char field[]) 5110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 5120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < fFieldCount; i++) 5130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (fFields[i].equals(field)) 5140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return i; 5150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return -1; 5160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 5170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual int countRecords() { return fRecordCount; } 5190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual void getRecord(int rowIndex, int fieldIndex, SkString* data) 5200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 5210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT((unsigned)rowIndex < (unsigned)fRecordCount); 5220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT((unsigned)fieldIndex < (unsigned)fFieldCount); 5230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (data) 5240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger *data = fRecords[rowIndex * fFieldCount + fieldIndex]; 5250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 5260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger virtual bool prepareWidgetEvent(SkEvent* evt, int rowIndex) 5280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 5290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // hack, for testing right now. Need the xml to tell us what to jam in and where 5300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkString data; 5310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger this->getRecord(rowIndex, 0, &data); 5330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger evt->setString("xml-listsource", data.c_str()); 5340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return true; 5350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 5360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprivate: 5380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkString* fFields; // [fFieldCount] 5390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkString* fRecords; // [fRecordCount][fFieldCount] 5400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int fFieldCount, fRecordCount; 5410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}; 5420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkDOM.h" 5440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5450b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkXMLListSource::SkXMLListSource(const char doc[], size_t len) 5460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 5470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fFieldCount = fRecordCount = 0; 5480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fFields = fRecords = NULL; 5490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkDOM dom; 5510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const SkDOM::Node* node = dom.build(doc, len); 5530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(node); 5540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger const SkDOM::Node* child; 5550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger child = dom.getFirstChild(node, "fields"); 5570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (child) 5580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 5590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fFieldCount = dom.countChildren(child, "field"); 5600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fFields = new SkString[fFieldCount]; 5610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int n = 0; 5630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger child = dom.getFirstChild(child, "field"); 5640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger while (child) 5650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 5660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fFields[n].set(dom.findAttr(child, "name")); 5670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger child = dom.getNextSibling(child, "field"); 5680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger n += 1; 5690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 5700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(n == fFieldCount); 5710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 5720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger child = dom.getFirstChild(node, "records"); 5740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (child) 5750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 5760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fRecordCount = dom.countChildren(child, "record"); 5770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fRecords = new SkString[fRecordCount * fFieldCount]; 5780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger int n = 0; 5800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger child = dom.getFirstChild(child, "record"); 5810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger while (child) 5820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger { 5830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger for (int i = 0; i < fFieldCount; i++) 5840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger fRecords[n * fFieldCount + i].set(dom.findAttr(child, fFields[i].c_str())); 5850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger child = dom.getNextSibling(child, "record"); 5860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger n += 1; 5870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 5880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkASSERT(n == fRecordCount); 5890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 5900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 5910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////////////////// 5930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 5940b15698a8c76bb8abc1b555c1d91892669b4118fDerek SollenbergerSkListSource* SkListSource::Factory(const char name[]) 5950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ 5960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger static const char gDoc[] = 5970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<db name='contacts.db'>" 5980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<fields>" 5990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<field name='name'/>" 6000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<field name='work-num'/>" 6010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<field name='home-num'/>" 6020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<field name='type'/>" 6030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "</fields>" 6040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<records>" 6050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Andy McFadden' work-num='919 357-1234' home-num='919 123-4567' type='0'/>" 6060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Brian Swetland' work-num='919 123-1234' home-num='929 123-4567' type='1' />" 6070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Chris Desalvo' work-num='919 345-1234' home-num='949 123-4567' type='1' />" 6080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Chris White' work-num='919 234-1234' home-num='939 123-4567' type='2' />" 6090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Dan Bornstein' work-num='919 357-1234' home-num='919 123-4567' type='0' />" 6100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Don Cung' work-num='919 123-1234' home-num='929 123-4567' type='2' />" 6110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Eric Fischer' work-num='919 345-1234' home-num='949 123-4567' type='2' />" 6120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Ficus Kirkpatric' work-num='919 234-1234' home-num='939 123-4567' type='1' />" 6130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Jack Veenstra' work-num='919 234-1234' home-num='939 123-4567' type='2' />" 6140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Jeff Yaksick' work-num='919 234-1234' home-num='939 123-4567' type='0' />" 6150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Joe Onorato' work-num='919 234-1234' home-num='939 123-4567' type='0' />" 6160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Mathias Agopian' work-num='919 234-1234' home-num='939 123-4567' type='1' />" 6170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Mike Fleming' work-num='919 234-1234' home-num='939 123-4567' type='2' />" 6180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Nick Sears' work-num='919 234-1234' home-num='939 123-4567' type='1' />" 6190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Rich Miner' work-num='919 234-1234' home-num='939 123-4567' type='1' />" 6200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Tracey Cole' work-num='919 234-1234' home-num='939 123-4567' type='0' />" 6210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "<record name='Wei Huang' work-num='919 234-1234' home-num='939 123-4567' type='0' />" 6220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "</records>" 6230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger "</db>"; 6240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 6250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger//SkDebugf("doc size %d\n", sizeof(gDoc)-1); 6260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger return new SkXMLListSource(gDoc, sizeof(gDoc) - 1); 6270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger} 6280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 6290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 6300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 631