1 #include "SkWidget.h" 2 #include "SkCanvas.h" 3 #include "SkInterpolator.h" 4 #include "SkTime.h" 5 #include "SkParsePaint.h" 6 7 #if 0 8 SkWidgetView::SkWidgetView(U32 flags) : SkView(flags) 9 { 10 } 11 12 SkWidgetView::~SkWidgetView() 13 { 14 } 15 16 const char* SkWidgetView::GetEventType() 17 { 18 return "SkWidgetView"; 19 } 20 21 ///////////////////////////////////////////////////////////////////////////// 22 ///////////////////////////////////////////////////////////////////////////// 23 24 class SkTextView::Interp { 25 public: 26 Interp(const SkString& old, SkMSec now, SkMSec dur, AnimaDir dir) : fOldText(old), fInterp(1, 2) 27 { 28 SkScalar x = 0; 29 fInterp.setKeyFrame(0, now, &x, 0); 30 x = SK_Scalar1; 31 if (dir == kBackward_AnimDir) 32 x = -x; 33 fInterp.setKeyFrame(1, now + dur, &x); 34 } 35 bool draw(SkCanvas* canvas, const SkString& newText, SkScalar x, SkScalar y, SkPaint& paint) 36 { 37 SkScalar scale; 38 39 if (fInterp.timeToValues(SkTime::GetMSecs(), &scale) == SkInterpolator::kFreezeEnd_Result) 40 { 41 canvas->drawText(newText.c_str(), newText.size(), x, y, paint); 42 return false; 43 } 44 else 45 { 46 U8 alpha = paint.getAlpha(); 47 SkScalar above, below; 48 (void)paint.measureText(NULL, 0, &above, &below); 49 SkScalar height = below - above; 50 SkScalar dy = SkScalarMul(height, scale); 51 if (scale < 0) 52 height = -height; 53 54 // draw the old 55 paint.setAlpha((U8)SkScalarMul(alpha, SK_Scalar1 - SkScalarAbs(scale))); 56 canvas->drawText(fOldText.c_str(), fOldText.size(), x, y - dy, paint); 57 // draw the new 58 paint.setAlpha((U8)SkScalarMul(alpha, SkScalarAbs(scale))); 59 canvas->drawText(newText.c_str(), newText.size(), x, y + height - dy, paint); 60 // restore the paint 61 paint.setAlpha(alpha); 62 return true; 63 } 64 } 65 66 private: 67 SkString fOldText; 68 SkInterpolator fInterp; 69 }; 70 71 SkTextView::SkTextView(U32 flags) : SkView(flags), fInterp(NULL), fDoInterp(false) 72 { 73 fMargin.set(0, 0); 74 } 75 76 SkTextView::~SkTextView() 77 { 78 delete fInterp; 79 } 80 81 void SkTextView::getText(SkString* str) const 82 { 83 if (str) 84 str->set(fText); 85 } 86 87 void SkTextView::setText(const char text[], AnimaDir dir) 88 { 89 if (!fText.equals(text)) 90 { 91 SkString tmp(text); 92 this->privSetText(tmp, dir); 93 } 94 } 95 96 void SkTextView::setText(const char text[], size_t len, AnimaDir dir) 97 { 98 if (!fText.equals(text)) 99 { 100 SkString tmp(text, len); 101 this->privSetText(tmp, dir); 102 } 103 } 104 105 void SkTextView::setText(const SkString& src, AnimaDir dir) 106 { 107 if (fText != src) 108 this->privSetText(src, dir); 109 } 110 111 void SkTextView::privSetText(const SkString& src, AnimaDir dir) 112 { 113 SkASSERT(fText != src); 114 115 if (fDoInterp) 116 { 117 if (fInterp) 118 delete fInterp; 119 fInterp = new Interp(fText, SkTime::GetMSecs(), 500, dir); 120 } 121 fText = src; 122 this->inval(NULL); 123 } 124 125 ///////////////////////////////////////////////////////////////// 126 127 void SkTextView::getMargin(SkPoint* margin) const 128 { 129 if (margin) 130 *margin = fMargin; 131 } 132 133 void SkTextView::setMargin(const SkPoint& margin) 134 { 135 if (fMargin != margin) 136 { 137 fMargin = margin; 138 this->inval(NULL); 139 } 140 } 141 142 void SkTextView::onDraw(SkCanvas* canvas) 143 { 144 this->INHERITED::onDraw(canvas); 145 146 if (fText.size() == 0) 147 return; 148 149 SkPaint::Align align = fPaint.getTextAlign(); 150 SkScalar x, y; 151 152 switch (align) { 153 case SkPaint::kLeft_Align: 154 x = fMargin.fX; 155 break; 156 case SkPaint::kCenter_Align: 157 x = SkScalarHalf(this->width()); 158 break; 159 default: 160 SkASSERT(align == SkPaint::kRight_Align); 161 x = this->width() - fMargin.fX; 162 break; 163 } 164 165 fPaint.measureText(NULL, 0, &y, NULL); 166 y = fMargin.fY - y; 167 168 if (fInterp) 169 { 170 if (fInterp->draw(canvas, fText, x, y, fPaint)) 171 this->inval(NULL); 172 else 173 { 174 delete fInterp; 175 fInterp = NULL; 176 } 177 } 178 else 179 canvas->drawText(fText.c_str(), fText.size(), x, y, fPaint); 180 } 181 182 ////////////////////////////////////////////////////////////////////////////////////// 183 184 void SkTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node) 185 { 186 this->INHERITED::onInflate(dom, node); 187 188 const char* text = dom.findAttr(node, "text"); 189 if (text) 190 this->setText(text); 191 192 SkPoint margin; 193 if (dom.findScalars(node, "margin", (SkScalar*)&margin, 2)) 194 this->setMargin(margin); 195 (void)dom.findBool(node, "do-interp", &fDoInterp); 196 197 SkPaint_Inflate(&fPaint, dom, node); 198 } 199 200 ////////////////////////////////////////////////////////////////////////////////////// 201 202 SkSliderView::SkSliderView(U32 flags) : SkWidgetView(flags) 203 { 204 fValue = 0; 205 fMax = 0; 206 } 207 208 static U16 actual_value(U16CPU value, U16CPU max) 209 { 210 return SkToU16(SkMax32(0, SkMin32(value, max))); 211 } 212 213 void SkSliderView::setMax(U16CPU max) 214 { 215 if (fMax != max) 216 { 217 fMax = SkToU16(max); 218 if (fValue > 0) 219 this->inval(NULL); 220 } 221 } 222 223 void SkSliderView::setValue(U16CPU value) 224 { 225 if (fValue != value) 226 { 227 U16 prev = actual_value(fValue, fMax); 228 U16 next = actual_value(value, fMax); 229 230 fValue = SkToU16(value); 231 if (prev != next) 232 { 233 this->inval(NULL); 234 235 if (this->hasListeners()) 236 { 237 SkEvent evt; 238 239 evt.setType(SkWidgetView::GetEventType()); 240 evt.setFast32(this->getSinkID()); 241 evt.setS32("sliderValue", next); 242 this->postToListeners(evt); 243 } 244 } 245 } 246 } 247 248 #include "SkGradientShader.h" 249 250 static void setgrad(SkPaint* paint, const SkRect& r) 251 { 252 SkPoint pts[2]; 253 SkColor colors[2]; 254 255 #if 0 256 pts[0].set(r.fLeft, r.fTop); 257 pts[1].set(r.fLeft + r.height(), r.fBottom); 258 #else 259 pts[0].set(r.fRight, r.fBottom); 260 pts[1].set(r.fRight - r.height(), r.fTop); 261 #endif 262 colors[0] = SK_ColorBLUE; 263 colors[1] = SK_ColorWHITE; 264 265 paint->setShader(SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kMirror_TileMode))->unref(); 266 } 267 268 void SkSliderView::onDraw(SkCanvas* canvas) 269 { 270 this->INHERITED::onDraw(canvas); 271 272 U16CPU value = SkMax32(0, SkMin32(fValue, fMax)); 273 274 SkRect r; 275 SkPaint p; 276 277 r.set(0, 0, this->width(), this->height()); 278 279 p.setAntiAliasOn(true); 280 p.setStyle(SkPaint::kStroke_Style); 281 p.setStrokeWidth(SK_Scalar1); 282 r.inset(SK_Scalar1/2, SK_Scalar1/2); 283 canvas->drawRect(r, p); 284 285 if (fMax) 286 { 287 SkFixed percent = SkFixedDiv(value, fMax); 288 289 r.inset(SK_Scalar1/2, SK_Scalar1/2); 290 r.fRight = r.fLeft + SkScalarMul(r.width(), SkFixedToScalar(percent)); 291 p.setStyle(SkPaint::kFill_Style); 292 setgrad(&p, r); 293 canvas->drawRect(r, p); 294 } 295 296 #if 0 297 r.set(0, 0, this->width(), this->height()); 298 r.inset(SK_Scalar1, SK_Scalar1); 299 r.inset(r.width()/2, 0); 300 p.setColor(SK_ColorBLACK); 301 canvas->drawLine(*(SkPoint*)&r.fLeft, *(SkPoint*)&r.fRight, p); 302 #endif 303 } 304 305 SkView::Click* SkSliderView::onFindClickHandler(SkScalar x, SkScalar y) 306 { 307 return new Click(this); 308 } 309 310 bool SkSliderView::onClick(Click* click) 311 { 312 if (fMax) 313 { 314 SkScalar percent = SkScalarDiv(click->fCurr.fX + SK_Scalar1, this->width() - SK_Scalar1*2); 315 percent = SkMaxScalar(0, SkMinScalar(percent, SK_Scalar1)); 316 this->setValue(SkScalarRound(percent * fMax)); 317 return true; 318 } 319 return false; 320 } 321 322 #endif 323 324