Home | History | Annotate | Download | only in views
      1 #include "SkWidgetViews.h"
      2 #include "SkAnimator.h"
      3 #include "SkCanvas.h"
      4 #include "SkPaint.h"
      5 #include "SkStream.h"
      6 #include "SkSystemEventTypes.h"
      7 
      8 #ifdef SK_DEBUG
      9 	static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
     10 	{
     11 		const char* value = dom.findAttr(node, attr);
     12 		if (value)
     13 			SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
     14 	}
     15 #else
     16 	#define assert_no_attr(dom, node, attr)
     17 #endif
     18 /*
     19 I have moved this to SkWidgetViews.h
     20 enum SkinEnum {
     21 	kButton_SkinEnum,
     22 	kProgress_SkinEnum,
     23 	kScroll_SkinEnum,
     24 	kStaticText_SkinEnum,
     25 
     26 	kSkinEnumCount
     27 };
     28 */
     29 
     30 const char* get_skin_enum_path(SkinEnum se)
     31 {
     32 	SkASSERT((unsigned)se < kSkinEnumCount);
     33 
     34 	static const char* gSkinPaths[] = {
     35             "common/default/default/skins/border3.xml",
     36             "common/default/default/skins/button.xml",
     37             "common/default/default/skins/progressBar.xml",
     38             "common/default/default/skins/scrollBar.xml",
     39             "common/default/default/skins/statictextpaint.xml"
     40 	};
     41 
     42 	return gSkinPaths[se];
     43 }
     44 
     45 void init_skin_anim(const char path[], SkAnimator* anim)
     46 {
     47 	SkASSERT(path && anim);
     48 
     49 	SkFILEStream	stream(path);
     50 
     51 	if (!stream.isValid())
     52 	{
     53 		SkDEBUGF(("init_skin_anim: loading skin failed <%s>\n", path));
     54 		sk_throw();
     55 	}
     56 
     57 	if (!anim->decodeStream(&stream))
     58 	{
     59 		SkDEBUGF(("init_skin_anim: decoding skin failed <%s>\n", path));
     60 		sk_throw();
     61 	}
     62 }
     63 
     64 void init_skin_anim(SkinEnum se, SkAnimator* anim)
     65 {
     66 	init_skin_anim(get_skin_enum_path(se), anim);
     67 }
     68 
     69 void init_skin_paint(SkinEnum se, SkPaint* paint)
     70 {
     71 	SkASSERT(paint);
     72 
     73 	SkAnimator	anim;
     74 	SkCanvas	canvas;
     75 
     76 	init_skin_anim(se, &anim);
     77 	anim.draw(&canvas, paint, 0);
     78 }
     79 
     80 void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint)
     81 {
     82 	SkASSERT(paint);
     83 
     84 	SkAnimator	anim;
     85 	SkCanvas	canvas;
     86 
     87 	if (!anim.decodeDOM(dom, node))
     88 	{
     89 		SkDEBUGF(("inflate_paint: decoding dom failed\n"));
     90 		SkDEBUGCODE(dom.dump(node);)
     91 		sk_throw();
     92 	}
     93 	anim.draw(&canvas, paint, 0);
     94 }
     95 
     96 ////////////////////////////////////////////////////////////////////////////////////////
     97 
     98 SkWidgetView::SkWidgetView() : SkView(SkView::kFocusable_Mask | SkView::kEnabled_Mask)
     99 {
    100 }
    101 
    102 const char* SkWidgetView::getLabel() const
    103 {
    104 	return fLabel.c_str();
    105 }
    106 
    107 void SkWidgetView::getLabel(SkString* label) const
    108 {
    109 	if (label)
    110 		*label = fLabel;
    111 }
    112 
    113 void SkWidgetView::setLabel(const char label[])
    114 {
    115 	this->setLabel(label, label ? strlen(label) : 0);
    116 }
    117 
    118 void SkWidgetView::setLabel(const char label[], size_t len)
    119 {
    120 	if (label == NULL && fLabel.size() != 0 || !fLabel.equals(label, len))
    121 	{
    122 		SkString	tmp(label, len);
    123 
    124 		this->onLabelChange(fLabel.c_str(), tmp.c_str());
    125 		fLabel.swap(tmp);
    126 	}
    127 }
    128 
    129 void SkWidgetView::setLabel(const SkString& label)
    130 {
    131 	if (fLabel != label)
    132 	{
    133 		this->onLabelChange(fLabel.c_str(), label.c_str());
    134 		fLabel = label;
    135 	}
    136 }
    137 
    138 bool SkWidgetView::postWidgetEvent()
    139 {
    140 	if (!fEvent.isType(""))
    141 	{
    142 		SkEvent	evt(fEvent);	// make a copy since onPrepareWidgetEvent may edit the event
    143 
    144 		if (this->onPrepareWidgetEvent(&evt))
    145 		{
    146 			SkDEBUGCODE(evt.dump("SkWidgetView::postWidgetEvent");)
    147 
    148 			this->postToListeners(evt);	// wonder if this should return true if there are > 0 listeners...
    149 			return true;
    150 		}
    151 	}
    152 	return false;
    153 }
    154 
    155 /*virtual*/ void SkWidgetView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
    156 {
    157 	this->INHERITED::onInflate(dom, node);
    158 
    159 	const char* label = dom.findAttr(node, "label");
    160 	if (label)
    161 		this->setLabel(label);
    162 
    163 	if ((node = dom.getFirstChild(node, "event")) != NULL)
    164 		fEvent.inflate(dom, node);
    165 }
    166 
    167 /*virtual*/ void SkWidgetView::onLabelChange(const char oldLabel[], const char newLabel[])
    168 {
    169 	this->inval(NULL);
    170 }
    171 
    172 static const char gWidgetEventSinkIDSlotName[] = "sk-widget-sinkid-slot";
    173 
    174 /*virtual*/ bool SkWidgetView::onPrepareWidgetEvent(SkEvent* evt)
    175 {
    176 	evt->setS32(gWidgetEventSinkIDSlotName, this->getSinkID());
    177 	return true;
    178 }
    179 
    180 SkEventSinkID SkWidgetView::GetWidgetEventSinkID(const SkEvent& evt)
    181 {
    182 	int32_t	sinkID;
    183 
    184 	return evt.findS32(gWidgetEventSinkIDSlotName, &sinkID) ? (SkEventSinkID)sinkID : 0;
    185 }
    186 
    187 ///////////////////////////////////////////////////////////////////////////////////////////////////
    188 
    189 /*virtual*/ bool SkButtonView::onEvent(const SkEvent& evt)
    190 {
    191 	if (evt.isType(SK_EventType_Key) && evt.getFast32() == kOK_SkKey)
    192 	{
    193 		this->postWidgetEvent();
    194 		return true;
    195 	}
    196 	return this->INHERITED::onEvent(evt);
    197 }
    198 
    199 ///////////////////////////////////////////////////////////////////////////////////////////////////
    200 
    201 SkCheckButtonView::SkCheckButtonView() : fCheckState(kOff_CheckState)
    202 {
    203 }
    204 
    205 void SkCheckButtonView::setCheckState(CheckState state)
    206 {
    207 	SkASSERT((unsigned)state <= kUnknown_CheckState);
    208 
    209 	if (fCheckState != state)
    210 	{
    211 		this->onCheckStateChange(this->getCheckState(), state);
    212 		fCheckState = SkToU8(state);
    213 	}
    214 }
    215 
    216 /*virtual*/ void SkCheckButtonView::onCheckStateChange(CheckState oldState, CheckState newState)
    217 {
    218 	this->inval(NULL);
    219 }
    220 
    221 /*virtual*/ void SkCheckButtonView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
    222 {
    223 	this->INHERITED::onInflate(dom, node);
    224 
    225 	int index = dom.findList(node, "check-state", "off,on,unknown");
    226 	if (index >= 0)
    227 		this->setCheckState((CheckState)index);
    228 }
    229 
    230 static const char gCheckStateSlotName[] = "sk-checkbutton-check-slot";
    231 
    232 /*virtual*/ bool SkCheckButtonView::onPrepareWidgetEvent(SkEvent* evt)
    233 {
    234 	// could check if we're "disabled", and return false...
    235 
    236 	evt->setS32(gCheckStateSlotName, this->getCheckState());
    237 	return true;
    238 }
    239 
    240 bool SkCheckButtonView::GetWidgetEventCheckState(const SkEvent& evt, CheckState* state)
    241 {
    242 	int32_t	state32;
    243 
    244 	if (evt.findS32(gCheckStateSlotName, &state32))
    245 	{
    246 		if (state)
    247 			*state = (CheckState)state32;
    248 		return true;
    249 	}
    250 	return false;
    251 }
    252 
    253 ///////////////////////////////////////////////////////////////////////////////////////////////////
    254 ///////////////////////////////////////////////////////////////////////////////////////////////////
    255 ///////////////////////////////////////////////////////////////////////////////////////////////////
    256 
    257 #include "SkTime.h"
    258 #include <stdio.h>
    259 
    260 class SkAnimButtonView : public SkButtonView {
    261 public:
    262 	SkAnimButtonView()
    263 	{
    264 		fAnim.setHostEventSink(this);
    265 		init_skin_anim(kButton_SkinEnum, &fAnim);
    266 	}
    267 
    268 protected:
    269 	virtual void onLabelChange(const char oldLabel[], const char newLabel[])
    270 	{
    271 		this->INHERITED::onLabelChange(oldLabel, newLabel);
    272 
    273 		SkEvent evt("user");
    274 		evt.setString("id", "setLabel");
    275 		evt.setString("LABEL", newLabel);
    276 		fAnim.doUserEvent(evt);
    277 	}
    278 
    279 	virtual void onFocusChange(bool gainFocus)
    280 	{
    281 		this->INHERITED::onFocusChange(gainFocus);
    282 
    283 		SkEvent evt("user");
    284 		evt.setString("id", "setFocus");
    285 		evt.setS32("FOCUS", gainFocus);
    286 		fAnim.doUserEvent(evt);
    287 	}
    288 
    289 	virtual void onSizeChange()
    290 	{
    291 		this->INHERITED::onSizeChange();
    292 
    293 		SkEvent evt("user");
    294 		evt.setString("id", "setDim");
    295 		evt.setScalar("dimX", this->width());
    296 		evt.setScalar("dimY", this->height());
    297 		fAnim.doUserEvent(evt);
    298 	}
    299 
    300 	virtual void onDraw(SkCanvas* canvas)
    301 	{
    302 		SkPaint						paint;
    303 		SkAnimator::DifferenceType	diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
    304 
    305 		if (diff == SkAnimator::kDifferent)
    306 			this->inval(NULL);
    307 		else if (diff == SkAnimator::kPartiallyDifferent)
    308 		{
    309 			SkRect	bounds;
    310 			fAnim.getInvalBounds(&bounds);
    311 			this->inval(&bounds);
    312 		}
    313 	}
    314 
    315 	virtual bool onEvent(const SkEvent& evt)
    316 	{
    317 		if (evt.isType(SK_EventType_Inval))
    318 		{
    319 			this->inval(NULL);
    320 			return true;
    321 		}
    322 		if (evt.isType("recommendDim"))
    323 		{
    324 			SkScalar	height;
    325 
    326 			if (evt.findScalar("y", &height))
    327 				this->setHeight(height);
    328 			return true;
    329 		}
    330 		return this->INHERITED::onEvent(evt);
    331 	}
    332 
    333 	virtual bool onPrepareWidgetEvent(SkEvent* evt)
    334 	{
    335 		if (this->INHERITED::onPrepareWidgetEvent(evt))
    336 		{
    337 			SkEvent	e("user");
    338 			e.setString("id", "handlePress");
    339 			(void)fAnim.doUserEvent(e);
    340 			return true;
    341 		}
    342 		return false;
    343 	}
    344 
    345 private:
    346 	SkAnimator	fAnim;
    347 
    348 	typedef SkButtonView INHERITED;
    349 };
    350 
    351 ////////////////////////////////////////////////////////////////////////////////////////////
    352 ////////////////////////////////////////////////////////////////////////////////////////////
    353 
    354 SkView* SkWidgetFactory(const char name[])
    355 {
    356 	if (name == NULL)
    357 		return NULL;
    358 
    359 	// must be in the same order as the SkSkinWidgetEnum is declared
    360 	static const char* gNames[] = {
    361 		"sk-border",
    362 		"sk-button",
    363 		"sk-image",
    364 		"sk-list",
    365 		"sk-progress",
    366 		"sk-scroll",
    367 		"sk-text"
    368 
    369 	};
    370 
    371 	for (int i = 0; i < SK_ARRAY_COUNT(gNames); i++)
    372 		if (!strcmp(gNames[i], name))
    373 			return SkWidgetFactory((SkWidgetEnum)i);
    374 
    375 	return NULL;
    376 }
    377 
    378 #include "SkImageView.h"
    379 #include "SkProgressBarView.h"
    380 #include "SkScrollBarView.h"
    381 #include "SkBorderView.h"
    382 
    383 SkView* SkWidgetFactory(SkWidgetEnum sw)
    384 {
    385 	switch (sw) {
    386 	case kBorder_WidgetEnum:
    387 		return new SkBorderView;
    388 	case kButton_WidgetEnum:
    389 		return new SkAnimButtonView;
    390 	case kImage_WidgetEnum:
    391 		return new SkImageView;
    392 	case kList_WidgetEnum:
    393 		return new SkListView;
    394 	case kProgress_WidgetEnum:
    395 		return new SkProgressBarView;
    396 	case kScroll_WidgetEnum:
    397 		return new SkScrollBarView;
    398 	case kText_WidgetEnum:
    399 		return new SkStaticTextView;
    400 	default:
    401 		SkASSERT(!"unknown enum passed to SkWidgetFactory");
    402 		break;
    403 	}
    404 	return NULL;
    405 }
    406