зеркало из 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/SkBorderView.cpp',
|
||||||
'../src/views/animated/SkImageView.cpp',
|
'../src/views/animated/SkImageView.cpp',
|
||||||
'../src/views/animated/SkListView.cpp',
|
|
||||||
'../src/views/animated/SkListWidget.cpp',
|
'../src/views/animated/SkListWidget.cpp',
|
||||||
'../src/views/animated/SkProgressBarView.cpp',
|
'../src/views/animated/SkProgressBarView.cpp',
|
||||||
'../src/views/animated/SkScrollBarView.cpp',
|
'../src/views/animated/SkScrollBarView.cpp',
|
||||||
|
@ -34,7 +33,6 @@
|
||||||
'../src/views/animated/SkWidgetViews.cpp',
|
'../src/views/animated/SkWidgetViews.cpp',
|
||||||
],
|
],
|
||||||
'sources!' : [
|
'sources!' : [
|
||||||
'../src/views/animated/SkListView.cpp', #depends on missing SkListSource implementation
|
|
||||||
'../src/views/animated/SkListWidget.cpp', #depends on missing SkListSource implementation
|
'../src/views/animated/SkListWidget.cpp', #depends on missing SkListSource implementation
|
||||||
],
|
],
|
||||||
'conditions': [
|
'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
|
|
Загрузка…
Ссылка в новой задаче