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 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     SkAutoTDelete<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