/*
* 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 "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkPaint.h"
#include "SkUnitMappers.h"
#include "SkCubicInterval.h"
#include "SkWidgetViews.h"
static SkStaticTextView* make_textview(SkView* parent,
const SkRect& bounds,
const SkPaint& paint) {
SkStaticTextView* view = new SkStaticTextView;
view->setMode(SkStaticTextView::kFixedSize_Mode);
view->setPaint(paint);
view->setVisibleP(true);
view->setSize(bounds.width(), bounds.height());
view->setLoc(bounds.fLeft, bounds.fTop);
parent->attachChildToFront(view)->unref();
return view;
}
static void set_scalar(SkStaticTextView* view, SkScalar value) {
SkString str;
str.appendScalar(value);
view->setText(str);
}
class UnitMapperView : public SampleView {
SkPoint fPts[4];
SkMatrix fMatrix;
SkStaticTextView* fViews[4];
void setViews() {
set_scalar(fViews[0], fPts[1].fX);
set_scalar(fViews[1], fPts[1].fY);
set_scalar(fViews[2], fPts[2].fX);
set_scalar(fViews[3], fPts[2].fY);
}
public:
UnitMapperView() {
fPts[0].set(0, 0);
fPts[1].set(SK_Scalar1 / 3, SK_Scalar1 / 3);
fPts[2].set(SK_Scalar1 * 2 / 3, SK_Scalar1 * 2 / 3);
fPts[3].set(SK_Scalar1, SK_Scalar1);
fMatrix.setScale(SK_Scalar1 * 200, -SK_Scalar1 * 200);
fMatrix.postTranslate(SkIntToScalar(100), SkIntToScalar(300));
SkRect r = {
SkIntToScalar(350), SkIntToScalar(100),
SkIntToScalar(500), SkIntToScalar(130)
};
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(SkIntToScalar(25));
for (int i = 0; i < 4; i++) {
fViews[i] = make_textview(this, r, paint);
r.offset(0, r.height());
}
this->setViews();
}
protected:
// overrides from SkEventSink
virtual bool onQuery(SkEvent* evt) {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "UnitMapper");
return true;
}
return this->INHERITED::onQuery(evt);
}
virtual void onDrawContent(SkCanvas* canvas) {
SkPaint paint;
paint.setAntiAlias(true);
paint.setColor(0xFF8888FF);
SkRect r = { 0, 0, SK_Scalar1, SK_Scalar1 };
canvas->concat(fMatrix);
canvas->drawRect(r, paint);
paint.setColor(SK_ColorBLACK);
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeWidth(0);
paint.setStrokeCap(SkPaint::kRound_Cap);
SkPath path;
path.moveTo(fPts[0]);
path.cubicTo(fPts[1], fPts[2], fPts[3]);
canvas->drawPath(path, paint);
paint.setColor(SK_ColorRED);
paint.setStrokeWidth(0);
canvas->drawLine(0, 0, SK_Scalar1, SK_Scalar1, paint);
paint.setColor(SK_ColorBLUE);
paint.setStrokeWidth(SK_Scalar1 / 60);
for (int i = 0; i < 50; i++) {
SkScalar x = i * SK_Scalar1 / 49;
canvas->drawPoint(x, SkEvalCubicInterval(&fPts[1], x), paint);
}
paint.setStrokeWidth(SK_Scalar1 / 20);
paint.setColor(SK_ColorGREEN);
canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, &fPts[1], paint);
}
SkPoint invertPt(SkScalar x, SkScalar y) {
SkPoint pt;
SkMatrix m;
fMatrix.invert(&m);
m.mapXY(x, y, &pt);
return pt;
}
int hittest(SkScalar x, SkScalar y) {
SkPoint target = { x, y };
SkPoint pts[2] = { fPts[1], fPts[2] };
fMatrix.mapPoints(pts, 2);
for (int i = 0; i < 2; i++) {
if (SkPoint::Distance(pts[i], target) < SkIntToScalar(4)) {
return i + 1;
}
}
return -1;
}
virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
fDragIndex = hittest(x, y);
return fDragIndex >= 0 ? new Click(this) : NULL;
}
virtual bool onClick(Click* click) {
if (fDragIndex >= 0) {
fPts[fDragIndex] = invertPt(click->fCurr.fX, click->fCurr.fY);
this->setViews();
this->inval(NULL);
return true;
}
return false;
}
private:
int fDragIndex;
typedef SampleView INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
static SkView* MyFactory() { return new UnitMapperView; }
static SkViewRegister reg(MyFactory);