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