Home | History | Annotate | Download | only in views
      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