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