Chromium Code Reviews| Index: samplecode/OverView.cpp |
| diff --git a/samplecode/OverView.cpp b/samplecode/OverView.cpp |
| index 5346c1a18cedd54ba34b586067022ada0c6d0067..67967fe44a7aed6a8573a07e78c565fcef46c027 100644 |
| --- a/samplecode/OverView.cpp |
| +++ b/samplecode/OverView.cpp |
| @@ -6,24 +6,55 @@ |
| */ |
| #include "OverView.h" |
| - |
| #include "SampleCode.h" |
| - |
| #include "SkCanvas.h" |
| #include "SkView.h" |
| -static const int N = 8; |
| -static const SkScalar kWidth = SkIntToScalar(640); |
| -static const SkScalar kHeight = SkIntToScalar(480); |
| static const char gIsOverview[] = "is-overview"; |
| +static int to_lower(int c) { |
| + if ('A' <= c && c <= 'Z') { |
| + c = c - 'A' + 'a'; |
| + } |
| + return c; |
| +} |
| + |
| +static bool case_insensitive_eq(int charA, int charB) { |
| + return to_lower(charA) == to_lower(charB); |
| +} |
| + |
| +static bool case_insensitive_find(const char str[], const char sub[]) { |
| + while (*str) { |
| + if (case_insensitive_eq(*str, *sub)) { |
| + for (;;) { |
| + str++; |
| + sub++; |
| + if (0 == *sub) { |
| + return true; |
| + } |
| + if (!case_insensitive_eq(*str, *sub)) { |
| + return false; |
| + } |
| + } |
| + } |
| + str++; |
| + } |
| + return false; |
| +} |
| + |
| +static bool draw_this_name(const SkString& name, const SkString& filter) { |
| + if (filter.isEmpty()) { |
| + return true; |
| + } |
| + return case_insensitive_find(name.c_str(), filter.c_str()); |
|
djsollen
2015/02/03 18:22:38
why not just use strcasecomp or call tolower on bo
reed1
2015/02/03 19:53:16
slower (due to mallocs) but Done.
|
| +} |
| + |
| class OverView : public SkView { |
| public: |
| OverView(int count, const SkViewFactory* factories[]); |
| virtual ~OverView(); |
| protected: |
| - // Overridden from SkEventSink: |
| bool onEvent(const SkEvent&) SK_OVERRIDE; |
| bool onQuery(SkEvent* evt) SK_OVERRIDE { |
| if (SampleCode::TitleQ(*evt)) { |
| @@ -33,29 +64,34 @@ protected: |
| if (evt->isType(gIsOverview)) { |
| return true; |
| } |
| + SkUnichar uni; |
| + if (SampleCode::CharQ(*evt, &uni)) { |
| + fMatchStr.appendUnichar(uni); |
| + this->inval(NULL); |
| + return true; |
| + } |
| return this->INHERITED::onQuery(evt); |
| } |
| - |
| - // Overridden from SkView: |
| - void onSizeChange() SK_OVERRIDE; |
| - void onDraw(SkCanvas* canvas) SK_OVERRIDE { |
| - canvas->drawColor(SK_ColorLTGRAY); |
| - } |
| - |
| - SkCanvas* beforeChildren(SkCanvas*) SK_OVERRIDE; |
| + void onDraw(SkCanvas* canvas) SK_OVERRIDE; |
| bool onSendClickToChildren(SkScalar x, SkScalar y, unsigned modi) SK_OVERRIDE { |
| return false; |
| } |
| - Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) SK_OVERRIDE { |
| - int ix = (int)(SkScalarDiv(x * N, kWidth)); |
| - int iy = (int)(SkScalarDiv(y * N, kHeight)); |
| - if (ix >= 0 && iy >= 0) { |
| - SkEvent evt("set-curr-index"); |
| - evt.setFast32(iy * N + ix); |
| - this->sendEventToParents(evt); |
| + Click* onFindClickHandler(SkScalar cx, SkScalar cy, unsigned modi) SK_OVERRIDE { |
| + const SkRect crect = SkRect::MakeXYWH(cx - 0.5f, cy - 0.5f, 1, 1); |
| + SkPoint loc = this->start(); |
| + for (int i = 0; i < fCount; ++i) { |
| + if (draw_this_name(fNames[i], fMatchStr)) { |
| + if (this->bounds(loc).intersects(crect)) { |
| + SkEvent evt("set-curr-index"); |
| + evt.setFast32(i); |
| + this->sendEventToParents(evt); |
| + break; |
| + } |
| + this->next(&loc); |
| + } |
| } |
| return NULL; |
| } |
| @@ -63,6 +99,28 @@ protected: |
| private: |
| int fCount; |
| const SkViewFactory** fFactories; |
| + SkString* fNames; |
| + SkString fMatchStr; |
| + SkPaint fNamePaint; |
| + SkPaint::FontMetrics fNameMetrics; |
| + SkScalar fNameW; |
| + SkScalar fNameH; |
| + |
| + SkRect bounds(const SkPoint& loc) const { |
| + return SkRect::MakeXYWH(loc.x(), loc.y() + fNameMetrics.fAscent, fNameW, fNameH); |
| + } |
| + |
| + SkPoint start() const { |
| + return SkPoint::Make(10, -fNameMetrics.fTop); |
| + } |
| + |
| + void next(SkPoint* loc) const { |
| + loc->fY += fNameH; |
| + if (loc->fY > this->height() - fNameMetrics.fBottom) { |
| + loc->fY = -fNameMetrics.fTop; |
| + loc->fX += fNameW; |
| + } |
| + } |
| typedef SkView INHERITED; |
| }; |
| @@ -79,35 +137,44 @@ bool is_overview(SkView* view) { |
| OverView::OverView(int count, const SkViewFactory* factories[]) { |
| fCount = count; |
| fFactories = factories; |
| + |
| + fNames = new SkString[count]; |
| + for (int i = 0; i < count; ++i) { |
| + SkView* view = (*fFactories[i])(); |
| + if (view) { |
| + (void)SampleCode::RequestTitle(view, &fNames[i]); |
| + if (0 == fNames[i].find("GM:")) { |
| + fNames[i].remove(0, 3); |
| + } |
| + } |
| + } |
| + |
| + fNamePaint.setAntiAlias(true); |
| + fNamePaint.setTextSize(12); |
| + fNameW = 160; |
| + fNameH = fNamePaint.getFontMetrics(&fNameMetrics); |
| } |
| OverView::~OverView() { |
| + delete[] fNames; |
| } |
| bool OverView::onEvent(const SkEvent& evt) { |
| return this->INHERITED::onEvent(evt); |
| } |
| -void OverView::onSizeChange() { |
| - this->detachAllChildren(); |
| - |
| - SkScalar locX = 0; |
| - SkScalar locY = 0; |
| - for (int i = 0; i < fCount; i++) { |
| - SkView* view = (*fFactories[i])(); |
| - view->setVisibleP(true); |
| - this->attachChildToBack(view)->unref(); |
| - view->setLoc(locX, locY); |
| - view->setSize(kWidth, kHeight); |
| - locX += kWidth; |
| - if ((i % N) == N - 1) { |
| - locY += kHeight; |
| - locX = 0; |
| +void OverView::onDraw(SkCanvas* canvas) { |
| + SkPaint paint; |
| + paint.setColor(0xFFF8F8F8); |
| + canvas->drawPaint(paint); |
| + |
| + SkPoint loc = this->start(); |
| + for (int i = 0; i < fCount; ++i) { |
| + if (draw_this_name(fNames[i], fMatchStr)) { |
| + canvas->drawRect(this->bounds(loc), paint); |
| + canvas->drawText(fNames[i].c_str(), fNames[i].size(), loc.x(), loc.y(), fNamePaint); |
| + this->next(&loc); |
| } |
| } |
| } |
| -SkCanvas* OverView::beforeChildren(SkCanvas* canvas) { |
| - canvas->scale(SK_Scalar1 / N, SK_Scalar1 / N); |
| - return canvas; |
| -} |