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