4
#include "SkParsePaint.h"
5
#include "SkSystemEventTypes.h"
11
static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
13
const char* value = dom.findAttr(node, attr);
15
SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
18
#define assert_no_attr(dom, node, attr)
21
#include "SkAnimator.h"
24
///////////////////////////////////////////////////////////////////////////////
37
for (int i = 0; i < kSkinTypeCount; i++)
41
SkAnimator* get(SkinType);
44
SkAnimator* fAnimators[kSkinTypeCount];
47
SkinSuite::SkinSuite()
49
static const char kSkinPath[] = "skins/";
51
static const char* gSkinNames[] = {
52
"pushbutton_skin.xml",
56
for (unsigned i = 0; i < SK_ARRAY_COUNT(gSkinNames); i++)
58
size_t len = strlen(gSkinNames[i]);
59
SkString path(sizeof(kSkinPath) - 1 + len);
61
memcpy(path.writable_str(), kSkinPath, sizeof(kSkinPath) - 1);
62
memcpy(path.writable_str() + sizeof(kSkinPath) - 1, gSkinNames[i], len);
64
fAnimators[i] = new SkAnimator;
65
if (!fAnimators[i]->decodeURI(path.c_str()))
73
SkAnimator* SkinSuite::get(SkinType st)
75
SkASSERT((unsigned)st < kSkinTypeCount);
76
return fAnimators[st];
79
static SkinSuite* gSkinSuite;
81
static SkAnimator* get_skin_animator(SkinType st)
84
if (gSkinSuite == nil)
85
gSkinSuite = new SkinSuite;
86
return gSkinSuite->get(st);
92
///////////////////////////////////////////////////////////////////////////////
103
void SkWidget::onEnabledChange()
108
void SkWidget::postWidgetEvent()
110
if (!fEvent.isType("") && this->hasListeners())
112
this->prepareWidgetEvent(&fEvent);
113
this->postToListeners(fEvent);
117
void SkWidget::prepareWidgetEvent(SkEvent*)
119
// override in subclass to add any additional fields before posting
122
void SkWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
124
this->INHERITED::onInflate(dom, node);
126
if ((node = dom.getFirstChild(node, "event")) != nil)
127
fEvent.inflate(dom, node);
130
///////////////////////////////////////////////////////////////////////////////
132
size_t SkHasLabelWidget::getLabel(SkString* str) const
136
return fLabel.size();
139
size_t SkHasLabelWidget::getLabel(char buffer[]) const
142
memcpy(buffer, fLabel.c_str(), fLabel.size());
143
return fLabel.size();
146
void SkHasLabelWidget::setLabel(const SkString& str)
148
this->setLabel(str.c_str(), str.size());
151
void SkHasLabelWidget::setLabel(const char label[])
153
this->setLabel(label, strlen(label));
156
void SkHasLabelWidget::setLabel(const char label[], size_t len)
158
if (!fLabel.equals(label, len))
160
fLabel.set(label, len);
161
this->onLabelChange();
165
void SkHasLabelWidget::onLabelChange()
167
// override in subclass
170
void SkHasLabelWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
172
this->INHERITED::onInflate(dom, node);
174
const char* text = dom.findAttr(node, "label");
176
this->setLabel(text);
179
/////////////////////////////////////////////////////////////////////////////////////
181
void SkButtonWidget::setButtonState(State state)
186
this->onButtonStateChange();
190
void SkButtonWidget::onButtonStateChange()
195
void SkButtonWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
197
this->INHERITED::onInflate(dom, node);
200
if ((index = dom.findList(node, "buttonState", "off,on,unknown")) >= 0)
201
this->setButtonState((State)index);
204
/////////////////////////////////////////////////////////////////////////////////////
206
bool SkPushButtonWidget::onEvent(const SkEvent& evt)
208
if (evt.isType(SK_EventType_Key) && evt.getFast32() == kOK_SkKey)
210
this->postWidgetEvent();
213
return this->INHERITED::onEvent(evt);
216
static const char* computeAnimatorState(int enabled, int focused, SkButtonWidget::State state)
220
if (state == SkButtonWidget::kOn_State)
223
return "enabled-pressed";
226
return "enabled-focused";
230
#include "SkBlurMaskFilter.h"
231
#include "SkEmbossMaskFilter.h"
233
static void create_emboss(SkPaint* paint, SkScalar radius, bool focus, bool pressed)
235
SkEmbossMaskFilter::Light light;
237
light.fDirection[0] = SK_Scalar1/2;
238
light.fDirection[1] = SK_Scalar1/2;
239
light.fDirection[2] = SK_Scalar1/3;
240
light.fAmbient = 0x48;
241
light.fSpecular = 0x80;
245
light.fDirection[0] = -light.fDirection[0];
246
light.fDirection[1] = -light.fDirection[1];
249
light.fDirection[2] += SK_Scalar1/4;
251
paint->setMaskFilter(new SkEmbossMaskFilter(light, radius))->unref();
254
void SkPushButtonWidget::onDraw(SkCanvas* canvas)
256
this->INHERITED::onDraw(canvas);
259
this->getLabel(&label);
261
SkAnimator* anim = get_skin_animator(kPushButton_SkinType);
267
evt.setString("id", "prime");
268
evt.setScalar("prime-width", this->width());
269
evt.setScalar("prime-height", this->height());
270
evt.setString("prime-text", label);
271
evt.setString("prime-state", computeAnimatorState(this->isEnabled(), this->hasFocus(), this->getButtonState()));
273
(void)anim->doUserEvent(evt);
275
anim->draw(canvas, &paint, SkTime::GetMSecs());
282
r.set(0, 0, this->width(), this->height());
283
p.setAntiAliasOn(true);
284
p.setColor(SK_ColorBLUE);
285
create_emboss(&p, SkIntToScalar(12)/5, this->hasFocus(), this->getButtonState() == kOn_State);
286
canvas->drawRoundRect(r, SkScalarHalf(this->height()), SkScalarHalf(this->height()), p);
287
p.setMaskFilter(nil);
289
p.setTextAlign(SkPaint::kCenter_Align);
292
box.setMode(SkTextBox::kOneLine_Mode);
293
box.setSpacingAlign(SkTextBox::kCenter_SpacingAlign);
294
box.setBox(0, 0, this->width(), this->height());
296
// if (this->getButtonState() == kOn_State)
297
// p.setColor(SK_ColorRED);
299
p.setColor(SK_ColorWHITE);
301
box.draw(canvas, label.c_str(), label.size(), p);
305
SkView::Click* SkPushButtonWidget::onFindClickHandler(SkScalar x, SkScalar y)
308
return new Click(this);
311
bool SkPushButtonWidget::onClick(Click* click)
314
State state = kOff_State;
316
this->getLocalBounds(&r);
317
if (r.contains(click->fCurr))
319
if (click->fState == Click::kUp_State)
320
this->postWidgetEvent();
324
this->setButtonState(state);
328
//////////////////////////////////////////////////////////////////////////////////////////
330
SkStaticTextView::SkStaticTextView(U32 flags) : SkView(flags)
333
fMode = kFixedSize_Mode;
334
fSpacingAlign = SkTextBox::kStart_SpacingAlign;
337
SkStaticTextView::~SkStaticTextView()
341
void SkStaticTextView::computeSize()
343
if (fMode == kAutoWidth_Mode)
345
SkScalar width = fPaint.measureText(fText.c_str(), fText.size(), nil, nil);
346
this->setWidth(width + fMargin.fX * 2);
348
else if (fMode == kAutoHeight_Mode)
350
SkScalar width = this->width() - fMargin.fX * 2;
351
int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0;
353
SkScalar before, after;
354
(void)fPaint.measureText(0, nil, &before, &after);
356
this->setHeight(lines * (after - before) + fMargin.fY * 2);
360
void SkStaticTextView::setMode(Mode mode)
362
SkASSERT((unsigned)mode < kModeCount);
366
fMode = SkToU8(mode);
371
void SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align)
373
fSpacingAlign = SkToU8(align);
377
void SkStaticTextView::getMargin(SkPoint* margin) const
383
void SkStaticTextView::setMargin(SkScalar dx, SkScalar dy)
385
if (fMargin.fX != dx || fMargin.fY != dy)
393
size_t SkStaticTextView::getText(SkString* text) const
400
size_t SkStaticTextView::getText(char text[]) const
403
memcpy(text, fText.c_str(), fText.size());
407
void SkStaticTextView::setText(const SkString& text)
409
this->setText(text.c_str(), text.size());
412
void SkStaticTextView::setText(const char text[])
414
this->setText(text, strlen(text));
417
void SkStaticTextView::setText(const char text[], size_t len)
419
if (!fText.equals(text, len))
421
fText.set(text, len);
427
void SkStaticTextView::getPaint(SkPaint* paint) const
433
void SkStaticTextView::setPaint(const SkPaint& paint)
443
void SkStaticTextView::onDraw(SkCanvas* canvas)
445
this->INHERITED::onDraw(canvas);
452
box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode);
453
box.setSpacingAlign(this->getSpacingAlign());
454
box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY);
455
box.draw(canvas, fText.c_str(), fText.size(), fPaint);
458
void SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
460
this->INHERITED::onInflate(dom, node);
463
if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0)
464
this->setMode((Mode)index);
466
assert_no_attr(dom, node, "mode");
468
if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0)
469
this->setSpacingAlign((SkTextBox::SpacingAlign)index);
471
assert_no_attr(dom, node, "mode");
474
if (dom.findScalars(node, "margin", s, 2))
475
this->setMargin(s[0], s[1]);
477
assert_no_attr(dom, node, "margin");
479
const char* text = dom.findAttr(node, "text");
483
if ((node = dom.getFirstChild(node, "paint")) != nil)
484
SkPaint_Inflate(&fPaint, dom, node);
487
/////////////////////////////////////////////////////////////////////////////////////////////////////
489
#include "SkImageDecoder.h"
491
SkBitmapView::SkBitmapView(U32 flags) : SkView(flags)
495
SkBitmapView::~SkBitmapView()
499
bool SkBitmapView::getBitmap(SkBitmap* bitmap) const
503
return fBitmap.getConfig() != SkBitmap::kNo_Config;
506
void SkBitmapView::setBitmap(const SkBitmap* bitmap, bool viewOwnsPixels)
511
fBitmap.setOwnsPixels(viewOwnsPixels);
515
bool SkBitmapView::loadBitmapFromFile(const char path[])
519
if (SkImageDecoder::DecodeFile(path, &bitmap))
521
this->setBitmap(&bitmap, true);
522
bitmap.setOwnsPixels(false);
528
void SkBitmapView::onDraw(SkCanvas* canvas)
530
if (fBitmap.getConfig() != SkBitmap::kNo_Config &&
531
fBitmap.width() && fBitmap.height())
533
SkAutoCanvasRestore restore(canvas, true);
536
p.setFilterType(SkPaint::kBilinear_FilterType);
537
canvas->scale( this->width() / fBitmap.width(),
538
this->height() / fBitmap.height(),
540
canvas->drawBitmap(fBitmap, 0, 0, p);
544
void SkBitmapView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
546
this->INHERITED::onInflate(dom, node);
548
const char* src = dom.findAttr(node, "src");
550
(void)this->loadBitmapFromFile(src);