1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "SampleCode.h" 9 #include "SkView.h" 10 #include "SkCanvas.h" 11 #include "SkDevice.h" 12 #include "SkPaint.h" 13 #include "SkUnitMappers.h" 14 #include "SkCubicInterval.h" 15 16 #include "SkWidgetViews.h" 17 18 static SkStaticTextView* make_textview(SkView* parent, 19 const SkRect& bounds, 20 const SkPaint& paint) { 21 SkStaticTextView* view = new SkStaticTextView; 22 view->setMode(SkStaticTextView::kFixedSize_Mode); 23 view->setPaint(paint); 24 view->setVisibleP(true); 25 view->setSize(bounds.width(), bounds.height()); 26 view->setLoc(bounds.fLeft, bounds.fTop); 27 parent->attachChildToFront(view)->unref(); 28 return view; 29 } 30 31 static void set_scalar(SkStaticTextView* view, SkScalar value) { 32 SkString str; 33 str.appendScalar(value); 34 view->setText(str); 35 } 36 37 class UnitMapperView : public SampleView { 38 SkPoint fPts[4]; 39 SkMatrix fMatrix; 40 SkStaticTextView* fViews[4]; 41 42 void setViews() { 43 set_scalar(fViews[0], fPts[1].fX); 44 set_scalar(fViews[1], fPts[1].fY); 45 set_scalar(fViews[2], fPts[2].fX); 46 set_scalar(fViews[3], fPts[2].fY); 47 } 48 49 public: 50 UnitMapperView() { 51 fPts[0].set(0, 0); 52 fPts[1].set(SK_Scalar1 / 3, SK_Scalar1 / 3); 53 fPts[2].set(SK_Scalar1 * 2 / 3, SK_Scalar1 * 2 / 3); 54 fPts[3].set(SK_Scalar1, SK_Scalar1); 55 56 fMatrix.setScale(SK_Scalar1 * 200, -SK_Scalar1 * 200); 57 fMatrix.postTranslate(SkIntToScalar(100), SkIntToScalar(300)); 58 59 SkRect r = { 60 SkIntToScalar(350), SkIntToScalar(100), 61 SkIntToScalar(500), SkIntToScalar(130) 62 }; 63 SkPaint paint; 64 paint.setAntiAlias(true); 65 paint.setTextSize(SkIntToScalar(25)); 66 for (int i = 0; i < 4; i++) { 67 fViews[i] = make_textview(this, r, paint); 68 r.offset(0, r.height()); 69 } 70 this->setViews(); 71 } 72 73 protected: 74 // overrides from SkEventSink 75 virtual bool onQuery(SkEvent* evt) { 76 if (SampleCode::TitleQ(*evt)) { 77 SampleCode::TitleR(evt, "UnitMapper"); 78 return true; 79 } 80 return this->INHERITED::onQuery(evt); 81 } 82 83 virtual void onDrawContent(SkCanvas* canvas) { 84 SkPaint paint; 85 paint.setAntiAlias(true); 86 paint.setColor(0xFF8888FF); 87 88 SkRect r = { 0, 0, SK_Scalar1, SK_Scalar1 }; 89 90 canvas->concat(fMatrix); 91 canvas->drawRect(r, paint); 92 93 paint.setColor(SK_ColorBLACK); 94 paint.setStyle(SkPaint::kStroke_Style); 95 paint.setStrokeWidth(0); 96 paint.setStrokeCap(SkPaint::kRound_Cap); 97 98 SkPath path; 99 path.moveTo(fPts[0]); 100 path.cubicTo(fPts[1], fPts[2], fPts[3]); 101 canvas->drawPath(path, paint); 102 103 paint.setColor(SK_ColorRED); 104 paint.setStrokeWidth(0); 105 canvas->drawLine(0, 0, SK_Scalar1, SK_Scalar1, paint); 106 107 paint.setColor(SK_ColorBLUE); 108 paint.setStrokeWidth(SK_Scalar1 / 60); 109 for (int i = 0; i < 50; i++) { 110 SkScalar x = i * SK_Scalar1 / 49; 111 canvas->drawPoint(x, SkEvalCubicInterval(&fPts[1], x), paint); 112 } 113 114 paint.setStrokeWidth(SK_Scalar1 / 20); 115 paint.setColor(SK_ColorGREEN); 116 canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, &fPts[1], paint); 117 } 118 119 SkPoint invertPt(SkScalar x, SkScalar y) { 120 SkPoint pt; 121 SkMatrix m; 122 fMatrix.invert(&m); 123 m.mapXY(x, y, &pt); 124 return pt; 125 } 126 127 int hittest(SkScalar x, SkScalar y) { 128 SkPoint target = { x, y }; 129 SkPoint pts[2] = { fPts[1], fPts[2] }; 130 fMatrix.mapPoints(pts, 2); 131 for (int i = 0; i < 2; i++) { 132 if (SkPoint::Distance(pts[i], target) < SkIntToScalar(4)) { 133 return i + 1; 134 } 135 } 136 return -1; 137 } 138 139 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { 140 fDragIndex = hittest(x, y); 141 return fDragIndex >= 0 ? new Click(this) : NULL; 142 } 143 144 virtual bool onClick(Click* click) { 145 if (fDragIndex >= 0) { 146 fPts[fDragIndex] = invertPt(click->fCurr.fX, click->fCurr.fY); 147 this->setViews(); 148 this->inval(NULL); 149 return true; 150 } 151 return false; 152 } 153 154 private: 155 int fDragIndex; 156 157 typedef SampleView INHERITED; 158 }; 159 160 ////////////////////////////////////////////////////////////////////////////// 161 162 static SkView* MyFactory() { return new UnitMapperView; } 163 static SkViewRegister reg(MyFactory); 164 165