зеркало из https://github.com/mozilla/moz-skia.git
Delete SkListView.cpp, which has been #ifdef'ed out for 4+ years
Review URL: https://codereview.appspot.com/6550062 git-svn-id: http://skia.googlecode.com/svn/trunk@5667 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
3686c9d90a
Коммит
4e2d4ff99d
|
@ -26,7 +26,6 @@
|
|||
|
||||
'../src/views/animated/SkBorderView.cpp',
|
||||
'../src/views/animated/SkImageView.cpp',
|
||||
'../src/views/animated/SkListView.cpp',
|
||||
'../src/views/animated/SkListWidget.cpp',
|
||||
'../src/views/animated/SkProgressBarView.cpp',
|
||||
'../src/views/animated/SkScrollBarView.cpp',
|
||||
|
@ -34,7 +33,6 @@
|
|||
'../src/views/animated/SkWidgetViews.cpp',
|
||||
],
|
||||
'sources!' : [
|
||||
'../src/views/animated/SkListView.cpp', #depends on missing SkListSource implementation
|
||||
'../src/views/animated/SkListWidget.cpp', #depends on missing SkListSource implementation
|
||||
],
|
||||
'conditions': [
|
||||
|
|
|
@ -1,902 +0,0 @@
|
|||
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#include "SkWidget.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkEvent.h"
|
||||
#include "SkKey.h"
|
||||
#include "SkParsePaint.h"
|
||||
#include "SkSystemEventTypes.h"
|
||||
|
||||
#if 0
|
||||
|
||||
SkEvent* SkListSource::getEvent(int index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include "SkOSFile.h"
|
||||
|
||||
class SkDirListSource : public SkListSource {
|
||||
public:
|
||||
SkDirListSource(const char path[], const char suffix[], const char target[])
|
||||
: fPath(path), fSuffix(suffix), fTarget(target)
|
||||
{
|
||||
fCount = -1;
|
||||
}
|
||||
virtual int countRows()
|
||||
{
|
||||
if (fCount < 0)
|
||||
{
|
||||
fCount = 0;
|
||||
fIter.reset(fPath.c_str(), fSuffix.c_str());
|
||||
while (fIter.next(NULL))
|
||||
fCount += 1;
|
||||
fIter.reset(fPath.c_str(), fSuffix.c_str());
|
||||
fIndex = 0;
|
||||
}
|
||||
return fCount;
|
||||
}
|
||||
virtual void getRow(int index, SkString* left, SkString* right)
|
||||
{
|
||||
(void)this->countRows();
|
||||
SkASSERT((unsigned)index < (unsigned)fCount);
|
||||
|
||||
if (fIndex > index)
|
||||
{
|
||||
fIter.reset(fPath.c_str(), fSuffix.c_str());
|
||||
fIndex = 0;
|
||||
}
|
||||
|
||||
while (fIndex < index)
|
||||
{
|
||||
fIter.next(NULL);
|
||||
fIndex += 1;
|
||||
}
|
||||
|
||||
if (fIter.next(left))
|
||||
{
|
||||
if (left)
|
||||
left->remove(left->size() - fSuffix.size(), fSuffix.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left)
|
||||
left->reset();
|
||||
}
|
||||
if (right) // only set to ">" if we know we're on a sub-directory
|
||||
right->reset();
|
||||
|
||||
fIndex += 1;
|
||||
}
|
||||
virtual SkEvent* getEvent(int index)
|
||||
{
|
||||
SkASSERT((unsigned)index < (unsigned)fCount);
|
||||
|
||||
SkEvent* evt = new SkEvent();
|
||||
SkString label;
|
||||
|
||||
this->getRow(index, &label, NULL);
|
||||
evt->setString("name", label.c_str());
|
||||
|
||||
int c = fPath.c_str()[fPath.size() - 1];
|
||||
if (c != '/' && c != '\\')
|
||||
label.prepend("/");
|
||||
label.prepend(fPath);
|
||||
label.append(fSuffix);
|
||||
evt->setString("path", label.c_str());
|
||||
evt->setS32("index", index);
|
||||
evt->setS32("duration", 22);
|
||||
evt->setType(fTarget);
|
||||
return evt;
|
||||
}
|
||||
|
||||
private:
|
||||
SkString fPath, fSuffix;
|
||||
SkString fTarget;
|
||||
SkOSFile::Iter fIter;
|
||||
int fCount;
|
||||
int fIndex;
|
||||
};
|
||||
|
||||
SkListSource* SkListSource::CreateFromDir(const char path[], const char suffix[], const char target[])
|
||||
{
|
||||
return new SkDirListSource(path, suffix, target);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkDOMListSource : public SkListSource {
|
||||
public:
|
||||
enum Type {
|
||||
kUnknown_Type,
|
||||
kDir_Type,
|
||||
kToggle_Type
|
||||
};
|
||||
struct ItemRec {
|
||||
SkString fLabel;
|
||||
SkString fTail, fAltTail;
|
||||
SkString fTarget;
|
||||
Type fType;
|
||||
};
|
||||
|
||||
SkDOMListSource(const SkDOM& dom, const SkDOM::Node* node) : fDirTail(">")
|
||||
{
|
||||
const SkDOM::Node* child = dom.getFirstChild(node, "item");
|
||||
int count = 0;
|
||||
|
||||
while (child)
|
||||
{
|
||||
count += 1;
|
||||
child = dom.getNextSibling(child, "item");
|
||||
}
|
||||
|
||||
fCount = count;
|
||||
fList = NULL;
|
||||
if (count)
|
||||
{
|
||||
ItemRec* rec = fList = new ItemRec[count];
|
||||
|
||||
child = dom.getFirstChild(node, "item");
|
||||
while (child)
|
||||
{
|
||||
rec->fLabel.set(dom.findAttr(child, "label"));
|
||||
rec->fTail.set(dom.findAttr(child, "tail"));
|
||||
rec->fAltTail.set(dom.findAttr(child, "alt-tail"));
|
||||
rec->fTarget.set(dom.findAttr(child, "target"));
|
||||
rec->fType = kUnknown_Type;
|
||||
|
||||
int index = dom.findList(child, "type", "dir,toggle");
|
||||
if (index >= 0)
|
||||
rec->fType = (Type)(index + 1);
|
||||
|
||||
child = dom.getNextSibling(child, "item");
|
||||
rec += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual ~SkDOMListSource()
|
||||
{
|
||||
delete[] fList;
|
||||
}
|
||||
virtual int countRows()
|
||||
{
|
||||
return fCount;
|
||||
}
|
||||
virtual void getRow(int index, SkString* left, SkString* right)
|
||||
{
|
||||
SkASSERT((unsigned)index < (unsigned)fCount);
|
||||
|
||||
if (left)
|
||||
*left = fList[index].fLabel;
|
||||
if (right)
|
||||
*right = fList[index].fType == kDir_Type ? fDirTail : fList[index].fTail;
|
||||
}
|
||||
virtual SkEvent* getEvent(int index)
|
||||
{
|
||||
SkASSERT((unsigned)index < (unsigned)fCount);
|
||||
|
||||
if (fList[index].fType == kDir_Type)
|
||||
{
|
||||
SkEvent* evt = new SkEvent();
|
||||
evt->setType(fList[index].fTarget);
|
||||
evt->setFast32(index);
|
||||
return evt;
|
||||
}
|
||||
if (fList[index].fType == kToggle_Type)
|
||||
fList[index].fTail.swap(fList[index].fAltTail);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
int fCount;
|
||||
ItemRec* fList;
|
||||
SkString fDirTail;
|
||||
};
|
||||
|
||||
SkListSource* SkListSource::CreateFromDOM(const SkDOM& dom, const SkDOM::Node* node)
|
||||
{
|
||||
return new SkDOMListSource(dom, node);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
SkListView::SkListView(U32 flags) : SkWidgetView(flags)
|
||||
{
|
||||
fSource = NULL;
|
||||
fScrollIndex = 0;
|
||||
fCurrIndex = -1;
|
||||
fRowHeight = SkIntToScalar(16);
|
||||
fVisibleRowCount = 0;
|
||||
fStrCache = NULL;
|
||||
|
||||
fPaint[kBG_Attr].setColor(0);
|
||||
fPaint[kNormalText_Attr].setTextSize(SkIntToScalar(14));
|
||||
fPaint[kHiliteText_Attr].setTextSize(SkIntToScalar(14));
|
||||
fPaint[kHiliteText_Attr].setColor(SK_ColorWHITE);
|
||||
fPaint[kHiliteCell_Attr].setColor(SK_ColorBLUE);
|
||||
}
|
||||
|
||||
SkListView::~SkListView()
|
||||
{
|
||||
delete[] fStrCache;
|
||||
fSource->safeUnref();
|
||||
}
|
||||
|
||||
void SkListView::setRowHeight(SkScalar height)
|
||||
{
|
||||
SkASSERT(height >= 0);
|
||||
|
||||
if (fRowHeight != height)
|
||||
{
|
||||
fRowHeight = height;
|
||||
this->inval(NULL);
|
||||
this->onSizeChange();
|
||||
}
|
||||
}
|
||||
|
||||
void SkListView::setSelection(int index)
|
||||
{
|
||||
if (fCurrIndex != index)
|
||||
{
|
||||
this->invalSelection();
|
||||
fCurrIndex = index;
|
||||
this->invalSelection();
|
||||
this->ensureSelectionIsVisible();
|
||||
|
||||
{
|
||||
SkEvent evt;
|
||||
evt.setType("listview-selection");
|
||||
evt.setFast32(index);
|
||||
this->sendEventToParents(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkListView::moveSelectionUp()
|
||||
{
|
||||
if (fSource)
|
||||
{
|
||||
int index = fCurrIndex;
|
||||
if (index < 0) // no selection
|
||||
index = fSource->countRows() - 1;
|
||||
else
|
||||
index = SkMax32(index - 1, 0);
|
||||
this->setSelection(index);
|
||||
}
|
||||
}
|
||||
|
||||
void SkListView::moveSelectionDown()
|
||||
{
|
||||
if (fSource)
|
||||
{
|
||||
int index = fCurrIndex;
|
||||
if (index < 0) // no selection
|
||||
index = 0;
|
||||
else
|
||||
index = SkMin32(index + 1, fSource->countRows() - 1);
|
||||
this->setSelection(index);
|
||||
}
|
||||
}
|
||||
|
||||
void SkListView::invalSelection()
|
||||
{
|
||||
SkRect r;
|
||||
if (this->getRowRect(fCurrIndex, &r))
|
||||
this->inval(&r);
|
||||
}
|
||||
|
||||
void SkListView::ensureSelectionIsVisible()
|
||||
{
|
||||
if (fSource == NULL)
|
||||
return;
|
||||
|
||||
if ((unsigned)fCurrIndex < (unsigned)fSource->countRows())
|
||||
{
|
||||
int index = this->logicalToVisualIndex(fCurrIndex);
|
||||
|
||||
if ((unsigned)index >= (unsigned)fVisibleRowCount) // need to scroll
|
||||
{
|
||||
if (index < 0) // too high
|
||||
fScrollIndex = fCurrIndex;
|
||||
else
|
||||
fScrollIndex = fCurrIndex - fVisibleRowCount + 1;
|
||||
SkASSERT((unsigned)fScrollIndex < (unsigned)fSource->countRows());
|
||||
|
||||
this->dirtyStrCache();
|
||||
this->inval(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SkListView::getRowRect(int index, SkRect* r) const
|
||||
{
|
||||
SkASSERT(r);
|
||||
index = this->logicalToVisualIndex(index);
|
||||
if (index >= 0)
|
||||
{
|
||||
SkScalar top = index * fRowHeight;
|
||||
|
||||
if (top < this->height())
|
||||
{
|
||||
if (r)
|
||||
r->set(0, top, this->width(), top + fRowHeight);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SkPaint& SkListView::paint(Attr attr)
|
||||
{
|
||||
SkASSERT((unsigned)attr < kAttrCount);
|
||||
return fPaint[attr];
|
||||
}
|
||||
|
||||
SkListSource* SkListView::setListSource(SkListSource* src)
|
||||
{
|
||||
if (fSource != src)
|
||||
{
|
||||
SkRefCnt_SafeAssign(fSource, src);
|
||||
this->dirtyStrCache();
|
||||
this->ensureSelectionIsVisible();
|
||||
this->inval(NULL);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
void SkListView::onDraw(SkCanvas* canvas)
|
||||
{
|
||||
this->INHERITED::onDraw(canvas);
|
||||
|
||||
canvas->drawPaint(fPaint[kBG_Attr]);
|
||||
|
||||
int visibleCount = SkMin32(fVisibleRowCount, fSource->countRows() - fScrollIndex);
|
||||
if (visibleCount == 0)
|
||||
return;
|
||||
|
||||
this->ensureStrCache(visibleCount);
|
||||
int currIndex = this->logicalToVisualIndex(fCurrIndex);
|
||||
|
||||
if ((unsigned)currIndex < (unsigned)visibleCount)
|
||||
{
|
||||
SkAutoCanvasRestore restore(canvas, true);
|
||||
SkRect r;
|
||||
|
||||
canvas->translate(0, currIndex * fRowHeight);
|
||||
(void)this->getRowRect(fScrollIndex, &r);
|
||||
canvas->drawRect(r, fPaint[kHiliteCell_Attr]);
|
||||
}
|
||||
|
||||
SkPaint* p;
|
||||
SkScalar y, x = SkIntToScalar(6);
|
||||
SkScalar rite = this->width() - x;
|
||||
|
||||
{
|
||||
SkScalar ascent, descent;
|
||||
fPaint[kNormalText_Attr].measureText(0, NULL, &ascent, &descent);
|
||||
y = SkScalarHalf(fRowHeight - descent + ascent) - ascent;
|
||||
}
|
||||
|
||||
for (int i = 0; i < visibleCount; i++)
|
||||
{
|
||||
if (i == currIndex)
|
||||
p = &fPaint[kHiliteText_Attr];
|
||||
else
|
||||
p = &fPaint[kNormalText_Attr];
|
||||
|
||||
p->setTextAlign(SkPaint::kLeft_Align);
|
||||
canvas->drawText(fStrCache[i].c_str(), fStrCache[i].size(), x, y, *p);
|
||||
p->setTextAlign(SkPaint::kRight_Align);
|
||||
canvas->drawText(fStrCache[i + visibleCount].c_str(), fStrCache[i + visibleCount].size(), rite, y, *p);
|
||||
canvas->translate(0, fRowHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void SkListView::onSizeChange()
|
||||
{
|
||||
SkScalar count = SkScalarDiv(this->height(), fRowHeight);
|
||||
int n = SkScalarFloor(count);
|
||||
|
||||
// only want to show rows that are mostly visible
|
||||
if (n == 0 || count - SkIntToScalar(n) > SK_Scalar1*75/100)
|
||||
n += 1;
|
||||
|
||||
if (fVisibleRowCount != n)
|
||||
{
|
||||
fVisibleRowCount = n;
|
||||
this->ensureSelectionIsVisible();
|
||||
this->dirtyStrCache();
|
||||
}
|
||||
}
|
||||
|
||||
void SkListView::dirtyStrCache()
|
||||
{
|
||||
if (fStrCache)
|
||||
{
|
||||
delete[] fStrCache;
|
||||
fStrCache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SkListView::ensureStrCache(int count)
|
||||
{
|
||||
if (fStrCache == NULL)
|
||||
{
|
||||
fStrCache = new SkString[count << 1];
|
||||
|
||||
if (fSource)
|
||||
for (int i = 0; i < count; i++)
|
||||
fSource->getRow(i + fScrollIndex, &fStrCache[i], &fStrCache[i + count]);
|
||||
}
|
||||
}
|
||||
|
||||
bool SkListView::onEvent(const SkEvent& evt)
|
||||
{
|
||||
if (evt.isType(SK_EventType_Key))
|
||||
{
|
||||
switch (evt.getFast32()) {
|
||||
case kUp_SkKey:
|
||||
this->moveSelectionUp();
|
||||
return true;
|
||||
case kDown_SkKey:
|
||||
this->moveSelectionDown();
|
||||
return true;
|
||||
case kRight_SkKey:
|
||||
case kOK_SkKey:
|
||||
if (fSource && fCurrIndex >= 0)
|
||||
{
|
||||
SkEvent* evt = fSource->getEvent(fCurrIndex);
|
||||
if (evt)
|
||||
{
|
||||
SkView* view = this->sendEventToParents(*evt);
|
||||
delete evt;
|
||||
return view != NULL;
|
||||
}
|
||||
else // hack to make toggle work
|
||||
{
|
||||
this->dirtyStrCache();
|
||||
this->inval(NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this->INHERITED::onEvent(evt);
|
||||
}
|
||||
|
||||
void SkListView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
|
||||
{
|
||||
this->INHERITED::onInflate(dom, node);
|
||||
|
||||
SkScalar x;
|
||||
const SkDOM::Node* child;
|
||||
|
||||
if (dom.findScalar(node, "row-height", &x))
|
||||
this->setRowHeight(x);
|
||||
|
||||
if ((child = dom.getFirstChild(node, "hilite-paint")) != NULL)
|
||||
SkPaint_Inflate(&this->paint(kHiliteCell_Attr), dom, child);
|
||||
|
||||
// look for a listsource
|
||||
{
|
||||
SkListSource* src = NULL;
|
||||
|
||||
if ((child = dom.getFirstChild(node, "file-listsource")) != NULL)
|
||||
{
|
||||
const char* path = dom.findAttr(child, "path");
|
||||
if (path)
|
||||
src = SkListSource::CreateFromDir( path,
|
||||
dom.findAttr(child, "filter"),
|
||||
dom.findAttr(child, "target"));
|
||||
}
|
||||
else if ((child = dom.getFirstChild(node, "xml-listsource")) != NULL)
|
||||
{
|
||||
src = SkListSource::CreateFromDOM(dom, child);
|
||||
}
|
||||
|
||||
if (src)
|
||||
{
|
||||
this->setListSource(src)->unref();
|
||||
this->setSelection(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkImageDecoder.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
class SkScrollBarView : public SkView {
|
||||
public:
|
||||
SkScrollBarView(const char bg[], const char fg[])
|
||||
{
|
||||
fBGRef = SkBitmapRef::Decode(bg, true);
|
||||
fFGRef = SkBitmapRef::Decode(fg, true);
|
||||
|
||||
if (fBGRef)
|
||||
this->setWidth(SkIntToScalar(fBGRef->bitmap().width()));
|
||||
}
|
||||
~SkScrollBarView()
|
||||
{
|
||||
delete fBGRef;
|
||||
delete fFGRef;
|
||||
}
|
||||
protected:
|
||||
virtual void onDraw(SkCanvas* canvas)
|
||||
{
|
||||
if (fBGRef == NULL) return;
|
||||
|
||||
SkPaint paint;
|
||||
|
||||
SkShader* shader = SkShader::CreateBitmapShader(fBGRef->bitmap(), false, SkPaint::kNo_FilterType, SkShader::kClamp_TileMode);
|
||||
paint.setShader(shader)->unref();
|
||||
|
||||
canvas->drawPaint(paint);
|
||||
}
|
||||
private:
|
||||
SkBitmapRef* fBGRef, *fFGRef;
|
||||
};
|
||||
|
||||
SkGridView::SkGridView(U32 flags) : SkWidgetView(flags)
|
||||
{
|
||||
fSource = NULL;
|
||||
fCurrIndex = -1;
|
||||
fVisibleCount.set(0, 0);
|
||||
|
||||
fPaint[kBG_Attr].setColor(SK_ColorWHITE);
|
||||
fPaint[kHiliteCell_Attr].setColor(SK_ColorYELLOW);
|
||||
fPaint[kHiliteCell_Attr].setStyle(SkPaint::kStroke_Style);
|
||||
fPaint[kHiliteCell_Attr].setAntiAliasOn(true);
|
||||
fPaint[kHiliteCell_Attr].setStrokeWidth(SK_Scalar1*3);
|
||||
|
||||
fScrollBar = new SkScrollBarView("icons/scrollbarGrey.jpg", "icons/scrollbarBlue.jpg");
|
||||
this->attachChildToFront(fScrollBar)->unref();
|
||||
fScrollBar->setVisibleP(true);
|
||||
}
|
||||
|
||||
SkGridView::~SkGridView()
|
||||
{
|
||||
fSource->safeUnref();
|
||||
}
|
||||
|
||||
void SkGridView::getCellSize(SkPoint* size) const
|
||||
{
|
||||
if (size)
|
||||
*size = fCellSize;
|
||||
}
|
||||
|
||||
void SkGridView::setCellSize(SkScalar x, SkScalar y)
|
||||
{
|
||||
SkASSERT(x >= 0 && y >= 0);
|
||||
|
||||
if (!fCellSize.equals(x, y))
|
||||
{
|
||||
fCellSize.set(x, y);
|
||||
this->inval(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void SkGridView::setSelection(int index)
|
||||
{
|
||||
if (fCurrIndex != index)
|
||||
{
|
||||
this->invalSelection();
|
||||
fCurrIndex = index;
|
||||
this->invalSelection();
|
||||
this->ensureSelectionIsVisible();
|
||||
|
||||
// this generates the click
|
||||
{
|
||||
SkEvent evt;
|
||||
evt.setType("listview-selection");
|
||||
evt.setFast32(index);
|
||||
this->sendEventToParents(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkGridView::moveSelectionUp()
|
||||
{
|
||||
if (fSource)
|
||||
{
|
||||
int index = fCurrIndex;
|
||||
if (index < 0) // no selection
|
||||
index = fSource->countRows() - 1;
|
||||
else
|
||||
index = SkMax32(index - 1, 0);
|
||||
this->setSelection(index);
|
||||
}
|
||||
}
|
||||
|
||||
void SkGridView::moveSelectionDown()
|
||||
{
|
||||
if (fSource)
|
||||
{
|
||||
int index = fCurrIndex;
|
||||
if (index < 0) // no selection
|
||||
index = 0;
|
||||
else
|
||||
index = SkMin32(index + 1, fSource->countRows() - 1);
|
||||
this->setSelection(index);
|
||||
}
|
||||
}
|
||||
|
||||
void SkGridView::invalSelection()
|
||||
{
|
||||
SkRect r;
|
||||
if (this->getCellRect(fCurrIndex, &r))
|
||||
{
|
||||
SkScalar inset = 0;
|
||||
if (fPaint[kHiliteCell_Attr].getStyle() != SkPaint::kFill_Style)
|
||||
inset += fPaint[kHiliteCell_Attr].getStrokeWidth() / 2;
|
||||
if (fPaint[kHiliteCell_Attr].isAntiAliasOn())
|
||||
inset += SK_Scalar1;
|
||||
r.inset(-inset, -inset);
|
||||
this->inval(&r);
|
||||
}
|
||||
}
|
||||
|
||||
void SkGridView::ensureSelectionIsVisible()
|
||||
{
|
||||
if (fSource == NULL)
|
||||
return;
|
||||
#if 0
|
||||
if ((unsigned)fCurrIndex < (unsigned)fSource->countRows())
|
||||
{
|
||||
int index = this->logicalToVisualIndex(fCurrIndex);
|
||||
|
||||
if ((unsigned)index >= (unsigned)fVisibleRowCount) // need to scroll
|
||||
{
|
||||
if (index < 0) // too high
|
||||
fScrollIndex = fCurrIndex;
|
||||
else
|
||||
fScrollIndex = fCurrIndex - fVisibleRowCount + 1;
|
||||
SkASSERT((unsigned)fScrollIndex < (unsigned)fSource->countRows());
|
||||
|
||||
this->dirtyStrCache();
|
||||
this->inval(NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SkGridView::getCellRect(int index, SkRect* r) const
|
||||
{
|
||||
if (fVisibleCount.fY == 0)
|
||||
return false;
|
||||
|
||||
index = this->logicalToVisualIndex(index);
|
||||
if (index >= 0)
|
||||
{
|
||||
SkRect bounds;
|
||||
int row = index / fVisibleCount.fY;
|
||||
int col = index % fVisibleCount.fY;
|
||||
|
||||
bounds.set(0, 0, fCellSize.fX, fCellSize.fY);
|
||||
bounds.offset(col * (fCellSize.fX + SkIntToScalar(col > 0)),
|
||||
row * (fCellSize.fY + SkIntToScalar(row > 0)));
|
||||
|
||||
if (bounds.fTop < this->height())
|
||||
{
|
||||
if (r)
|
||||
*r = bounds;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SkPaint& SkGridView::paint(Attr attr)
|
||||
{
|
||||
SkASSERT((unsigned)attr < kAttrCount);
|
||||
return fPaint[attr];
|
||||
}
|
||||
|
||||
SkListSource* SkGridView::setListSource(SkListSource* src)
|
||||
{
|
||||
if (fSource != src)
|
||||
{
|
||||
SkRefCnt_SafeAssign(fSource, src);
|
||||
// this->dirtyStrCache();
|
||||
this->ensureSelectionIsVisible();
|
||||
this->inval(NULL);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
static void copybits(SkCanvas* canvas, const SkBitmap& bm, const SkRect& dst, const SkPaint& paint)
|
||||
{
|
||||
SkRect src;
|
||||
SkMatrix matrix;
|
||||
|
||||
src.set(0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()));
|
||||
if (matrix.setRectToRect(src, dst))
|
||||
{
|
||||
SkPaint p(paint);
|
||||
SkShader* shader = SkShader::CreateBitmapShader(bm, false, SkPaint::kNo_FilterType, SkShader::kClamp_TileMode);
|
||||
p.setShader(shader)->unref();
|
||||
|
||||
shader->setLocalMatrix(matrix);
|
||||
canvas->drawRect(dst, p);
|
||||
}
|
||||
}
|
||||
|
||||
#include "SkImageDecoder.h"
|
||||
|
||||
void SkGridView::onDraw(SkCanvas* canvas)
|
||||
{
|
||||
this->INHERITED::onDraw(canvas);
|
||||
|
||||
canvas->drawPaint(fPaint[kBG_Attr]);
|
||||
|
||||
if (fSource == NULL)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
int visibleCount = SkMin32(fVisibleRowCount, fSource->countRows() - fScrollIndex);
|
||||
if (visibleCount == 0)
|
||||
return;
|
||||
|
||||
this->ensureStrCache(visibleCount);
|
||||
int currIndex = this->logicalToVisualIndex(fCurrIndex);
|
||||
#endif
|
||||
|
||||
SkPaint p;
|
||||
for (int i = 0; i < fSource->countRows(); i++)
|
||||
{
|
||||
bool forced = false;
|
||||
SkEvent* evt = fSource->getEvent(i);
|
||||
SkASSERT(evt);
|
||||
SkString path(evt->findString("path"));
|
||||
delete evt;
|
||||
|
||||
SkBitmapRef* bmr = SkBitmapRef::Decode(path.c_str(), false);
|
||||
if (bmr == NULL)
|
||||
{
|
||||
bmr = SkBitmapRef::Decode(path.c_str(), true);
|
||||
if (bmr)
|
||||
forced = true;
|
||||
}
|
||||
|
||||
if (bmr)
|
||||
{
|
||||
SkAutoTDelete<SkBitmapRef> autoRef(bmr);
|
||||
SkRect r;
|
||||
if (!this->getCellRect(i, &r))
|
||||
break;
|
||||
copybits(canvas, bmr->bitmap(), r, p);
|
||||
}
|
||||
// only draw one forced bitmap at a time
|
||||
if (forced)
|
||||
{
|
||||
this->inval(NULL); // could inval only the remaining visible cells...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// draw the hilite
|
||||
{
|
||||
SkRect r;
|
||||
if (fCurrIndex >= 0 && this->getCellRect(fCurrIndex, &r))
|
||||
canvas->drawRect(r, fPaint[kHiliteCell_Attr]);
|
||||
}
|
||||
}
|
||||
|
||||
static int check_count(int n, SkScalar s)
|
||||
{
|
||||
// only want to show cells that are mostly visible
|
||||
if (n == 0 || s - SkIntToScalar(n) > SK_Scalar1*75/100)
|
||||
n += 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
void SkGridView::onSizeChange()
|
||||
{
|
||||
fScrollBar->setHeight(this->height());
|
||||
fScrollBar->setLoc(this->locX() + this->width() - fScrollBar->width(), 0);
|
||||
|
||||
if (fCellSize.equals(0, 0))
|
||||
{
|
||||
fVisibleCount.set(0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
SkScalar rows = SkScalarDiv(this->height(), fCellSize.fY);
|
||||
SkScalar cols = SkScalarDiv(this->width(), fCellSize.fX);
|
||||
int y = SkScalarFloor(rows);
|
||||
int x = SkScalarFloor(cols);
|
||||
|
||||
y = check_count(y, rows);
|
||||
x = check_count(x, cols);
|
||||
|
||||
if (!fVisibleCount.equals(x, y))
|
||||
{
|
||||
fVisibleCount.set(x, y);
|
||||
this->ensureSelectionIsVisible();
|
||||
// this->dirtyStrCache();
|
||||
}
|
||||
}
|
||||
|
||||
bool SkGridView::onEvent(const SkEvent& evt)
|
||||
{
|
||||
if (evt.isType(SK_EventType_Key))
|
||||
{
|
||||
switch (evt.getFast32()) {
|
||||
case kUp_SkKey:
|
||||
this->moveSelectionUp();
|
||||
return true;
|
||||
case kDown_SkKey:
|
||||
this->moveSelectionDown();
|
||||
return true;
|
||||
case kRight_SkKey:
|
||||
case kOK_SkKey:
|
||||
if (fSource && fCurrIndex >= 0)
|
||||
{
|
||||
SkEvent* evt = fSource->getEvent(fCurrIndex);
|
||||
if (evt)
|
||||
{
|
||||
// augment the event with our local rect
|
||||
(void)this->getCellRect(fCurrIndex, (SkRect*)evt->setScalars("local-rect", 4, NULL));
|
||||
|
||||
SkView* view = this->sendEventToParents(*evt);
|
||||
delete evt;
|
||||
return view != NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this->INHERITED::onEvent(evt);
|
||||
}
|
||||
|
||||
void SkGridView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
|
||||
{
|
||||
this->INHERITED::onInflate(dom, node);
|
||||
|
||||
SkScalar x[2];
|
||||
const SkDOM::Node* child;
|
||||
|
||||
if (dom.findScalars(node, "cell-size", x, 2))
|
||||
this->setCellSize(x[0], x[1]);
|
||||
|
||||
if ((child = dom.getFirstChild(node, "hilite-paint")) != NULL)
|
||||
SkPaint_Inflate(&this->paint(kHiliteCell_Attr), dom, child);
|
||||
|
||||
// look for a listsource
|
||||
{
|
||||
SkListSource* src = NULL;
|
||||
|
||||
if ((child = dom.getFirstChild(node, "file-listsource")) != NULL)
|
||||
{
|
||||
const char* path = dom.findAttr(child, "path");
|
||||
if (path)
|
||||
src = SkListSource::CreateFromDir( path,
|
||||
dom.findAttr(child, "filter"),
|
||||
dom.findAttr(child, "target"));
|
||||
}
|
||||
else if ((child = dom.getFirstChild(node, "xml-listsource")) != NULL)
|
||||
{
|
||||
src = SkListSource::CreateFromDOM(dom, child);
|
||||
}
|
||||
|
||||
if (src)
|
||||
{
|
||||
this->setListSource(src)->unref();
|
||||
this->setSelection(0);
|
||||
}
|
||||
}
|
||||
this->onSizeChange();
|
||||
}
|
||||
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче