Remove circular dependency of views and animator.
authorbungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 23 Mar 2012 14:11:43 +0000 (14:11 +0000)
committerbungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 23 Mar 2012 14:11:43 +0000 (14:11 +0000)
http://codereview.appspot.com/5874056/

git-svn-id: http://skia.googlecode.com/svn/trunk@3473 2bbb7eff-a529-9590-31e7-b0007b416f81

20 files changed:
gyp/SampleApp.gyp
gyp/animator.gyp
gyp/views.gyp
gyp/views_animated.gyp [new file with mode: 0644]
include/views/SkWidgetViews.h [deleted file]
include/views/animated/SkWidgetViews.h [new file with mode: 0644]
src/views/SkBorderView.cpp [deleted file]
src/views/SkImageView.cpp [deleted file]
src/views/SkListWidget.cpp [deleted file]
src/views/SkProgressBarView.cpp [deleted file]
src/views/SkScrollBarView.cpp [deleted file]
src/views/SkStaticTextView.cpp [deleted file]
src/views/SkWidgetViews.cpp [deleted file]
src/views/animated/SkBorderView.cpp [new file with mode: 0644]
src/views/animated/SkImageView.cpp [new file with mode: 0644]
src/views/animated/SkListWidget.cpp [new file with mode: 0644]
src/views/animated/SkProgressBarView.cpp [new file with mode: 0644]
src/views/animated/SkScrollBarView.cpp [new file with mode: 0644]
src/views/animated/SkStaticTextView.cpp [new file with mode: 0644]
src/views/animated/SkWidgetViews.cpp [new file with mode: 0644]

index 2a38add318f1c73c9b2738220a064b79b1e5ee05..bdd46ed352c5706652a6ded4156a2c5297591b44 100644 (file)
         'gpu.gyp:gr',
         'gpu.gyp:skgr',
         'pdf.gyp:pdf',
+        'views_animated.gyp:views_animated',
       ],
       'conditions' : [
        [ 'skia_os in ["linux", "freebsd", "openbsd", "solaris"]', {
index 744cd372d29c22f06a2aacee76976bf5041507b7..b3c651cc3afa1947496c00f6fba3c21ed92c23bb 100644 (file)
@@ -1,3 +1,7 @@
+#Animator is basically Skia's (much saner) version of Flash.
+#On top of Views it provides a declarative UI model which can be updated
+#based on events which trigger changes or scripts.
+
 {
   'targets': [
     {
index 4056a467bb0456f0e4f21bce08dd1be081ee059f..f663f124abc714025b9094685b226ea09c64c8e3 100644 (file)
@@ -1,3 +1,9 @@
+#Views is the Skia windowing toolkit.
+#It provides
+#  * a portable means of creating native windows
+#  * events
+#  * basic widgets and controls
+
 {
   'targets': [
     {
@@ -10,7 +16,6 @@
         '../include/xml',
         '../include/utils',
         '../include/images',
-        '../include/animator',
         '../include/effects',
         '../include/views/unix',
       ],
         '../include/views/SkView.h',
         '../include/views/SkViewInflate.h',
         '../include/views/SkWidget.h',
-        '../include/views/SkWidgetViews.h',
         '../include/views/SkWindow.h',
 
         '../src/views/SkBGViewArtist.cpp',
-        '../src/views/SkBorderView.cpp',
         '../src/views/SkEvent.cpp',
         '../src/views/SkEventSink.cpp',
-        '../src/views/SkImageView.cpp',
         '../src/views/SkListView.cpp',
-        '../src/views/SkListWidget.cpp',
         '../src/views/SkOSMenu.cpp',
         '../src/views/SkParsePaint.cpp',
-        '../src/views/SkProgressBarView.cpp',
         '../src/views/SkProgressView.cpp',
-        '../src/views/SkScrollBarView.cpp',
         '../src/views/SkStackViewLayout.cpp',
-        '../src/views/SkStaticTextView.cpp',
         '../src/views/SkTagList.cpp',
         '../src/views/SkTagList.h',
         '../src/views/SkTextBox.cpp',
@@ -63,7 +61,6 @@
         '../src/views/SkViewPriv.h',
         '../src/views/SkWidget.cpp',
         '../src/views/SkWidgets.cpp',
-        '../src/views/SkWidgetViews.cpp',
         '../src/views/SkWindow.cpp',
 
         #mac
@@ -84,8 +81,6 @@
 
       ],
       'sources!' : [
-        '../src/views/SkListView.cpp',   #depends on missing SkListSource implementation
-        '../src/views/SkListWidget.cpp', #depends on missing SkListSource implementation
         '../src/views/SDL/SkOSWindow_SDL.cpp',
       ],
       'conditions': [
             '../src/views/win/skia_win.cpp',
           ],
         }],
-        [ 'skia_os == "android"', {
-          # Android does not support animator so we need to remove all files
-          # that have references to it.
-          'include_dirs!': [
-            '../include/animator',
-          ],
-          'sources!': [
-            '../src/views/SkBorderView.cpp',
-            '../src/views/SkImageView.cpp',
-            '../src/views/SkProgressBarView.cpp',
-            '../src/views/SkScrollBarView.cpp',
-            '../src/views/SkStaticTextView.cpp',
-            '../src/views/SkWidgetViews.cpp',
-          ],
-        }],
       ],
       'direct_dependent_settings': {
         'include_dirs': [
diff --git a/gyp/views_animated.gyp b/gyp/views_animated.gyp
new file mode 100644 (file)
index 0000000..f7cd052
--- /dev/null
@@ -0,0 +1,74 @@
+#Animated widgets are views which use animator.
+
+{
+  'targets': [
+    {
+      'target_name': 'views_animated',
+      'type': 'static_library',
+      'include_dirs': [
+        '../include/config',
+        '../include/core',
+        '../include/views',
+        '../include/xml',
+        '../include/utils',
+        '../include/images',
+        '../include/animator',
+        '../include/effects',
+        '../include/views/unix',
+        '../include/views/animated',
+      ],
+      'sources': [
+        '../include/views/animated/SkWidgetViews.h',
+
+        '../src/views/animated/SkBorderView.cpp',
+        '../src/views/animated/SkImageView.cpp',
+        '../src/views/animated/SkListWidget.cpp',
+        '../src/views/animated/SkProgressBarView.cpp',
+        '../src/views/animated/SkScrollBarView.cpp',
+        '../src/views/animated/SkStaticTextView.cpp',
+        '../src/views/animated/SkWidgetViews.cpp',
+      ],
+      'sources!' : [
+        '../src/views/animated/SkListView.cpp',   #depends on missing SkListSource implementation
+        '../src/views/animated/SkListWidget.cpp', #depends on missing SkListSource implementation
+      ],
+      'conditions': [
+        [ 'skia_os == "mac"', {
+          'link_settings': {
+            'libraries': [
+              '$(SDKROOT)/System/Library/Frameworks/Cocoa.framework',
+              '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
+            ],
+          },
+        }],
+        [ 'skia_os == "android"', {
+          # Android does not support animator so we need to remove all files
+          # that have references to it.
+          'include_dirs!': [
+            '../include/animator',
+          ],
+          'sources!': [
+            '../src/views/animated/SkBorderView.cpp',
+            '../src/views/animated/SkImageView.cpp',
+            '../src/views/animated/SkListWidget.cpp',
+            '../src/views/animated/SkProgressBarView.cpp',
+            '../src/views/animated/SkScrollBarView.cpp',
+            '../src/views/animated/SkStaticTextView.cpp',
+            '../src/views/animated/SkWidgetViews.cpp',
+          ],
+        }],
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '../include/views/animated',
+        ],
+      },
+    },
+  ],
+}
+
+# Local Variables:
+# tab-width:2
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=2 shiftwidth=2:
diff --git a/include/views/SkWidgetViews.h b/include/views/SkWidgetViews.h
deleted file mode 100644 (file)
index 295c101..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#ifndef SkWidgetViews_DEFINED
-#define SkWidgetViews_DEFINED
-
-#include "SkView.h"
-
-
-enum SkWidgetEnum {
-    kBorder_WidgetEnum,         //!< <sk-border>
-    kButton_WidgetEnum,         //!< <sk-button>
-    kImage_WidgetEnum,          //!< <sk-image>
-    kList_WidgetEnum,           //!< <sk-list>
-    kProgress_WidgetEnum,       //!< <sk-progress>
-    kScroll_WidgetEnum,         //!< <sk-scroll>
-    kText_WidgetEnum,           //!< <sk-text>
-    
-    kWidgetEnumCount
-};
-
-//determines which skin to use
-enum SkinEnum {
-    kBorder_SkinEnum,
-    kButton_SkinEnum,
-    kProgress_SkinEnum,
-    kScroll_SkinEnum,
-    kStaticText_SkinEnum,
-    
-    kSkinEnumCount
-};
-
-#include "SkAnimator.h"
-//used for inflates
-const char* get_skin_enum_path(SkinEnum se);
-void init_skin_anim(const char path[], SkAnimator* anim);
-void init_skin_anim(SkinEnum se, SkAnimator* anim);
-void init_skin_paint(SkinEnum se, SkPaint* paint);
-void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint);
-
-/** Given an enum value, return an instance of the specified widget.
-    If the enum is out of range, returns null
-*/
-SkView* SkWidgetFactory(SkWidgetEnum);
-/** Given the inflate/element name of a widget, return an instance of
-    the specified widget, or null if name does not match any known
-    widget type.
-*/
-SkView* SkWidgetFactory(const char name[]);
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SkWidgetView : public SkView {
-public:
-    SkWidgetView();
-
-    const char* getLabel() const;
-    void        getLabel(SkString* label) const;
-
-    void        setLabel(const char[]);
-    void        setLabel(const char[], size_t len);
-    void        setLabel(const SkString&);
-
-    SkEvent&        event() { return fEvent; }
-    const SkEvent&  event() const { return fEvent; }
-
-    /** Returns true if the widget can post its event to its listeners.
-    */
-    bool    postWidgetEvent();
-    
-    /** Returns the sinkID of the widgetview that posted the event, or 0
-    */
-    static SkEventSinkID GetWidgetEventSinkID(const SkEvent&);
-
-protected:
-    /** called when the label changes. override in subclasses. default action invals the view's bounds.
-        called with the old and new labels, before the label has actually changed.
-    */
-    virtual void onLabelChange(const char oldLabel[], const char newLabel[]);
-    /** called before posting the event to our listeners. Override to add slots to the event
-        before posting. Return true to proceed with posting, or false to not post the event to any
-        listener. Note: the event passed in may not be the same as calling this->event().
-        Be sure to call your INHERITED method as well, so that all classes in the hierarchy get a shot
-        at modifying the event (and possibly returning false to abort).
-    */
-    virtual bool onPrepareWidgetEvent(SkEvent* evt);
-
-    // overrides
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-    
-private:
-    SkString    fLabel;
-    SkEvent     fEvent;
-    
-    typedef SkView INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SkButtonView : public SkWidgetView {
-public:
-    // inflate: "sk-button"
-    
-protected:
-    // overrides
-    virtual bool onEvent(const SkEvent&);
-private:
-    typedef SkWidgetView INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SkCheckButtonView : public SkWidgetView {
-public:
-    SkCheckButtonView();
-
-    // inflate: "sk-checkbutton"
-    
-    enum CheckState {
-        kOff_CheckState,        //!< inflate: check-state="off"
-        kOn_CheckState,         //!< inflate: check-state="on"
-        kUnknown_CheckState     //!< inflate: check-state="unknown"
-    };
-    CheckState  getCheckState() const { return (CheckState)fCheckState; }
-    void        setCheckState(CheckState);
-
-    /** use this to extract the CheckState from an event (i.e. one that as posted
-        by a SkCheckButtonView). Returns true if the proper slot was present in the event,
-        and sets state to that value. If no proper slot is found, returns false and does not
-        modify state.
-    */
-    static bool GetWidgetEventCheckState(const SkEvent&, CheckState* state);
-
-protected:
-    // called when the check-state is about to change, but before it actually has
-    virtual void onCheckStateChange(CheckState oldState, CheckState newState);
-
-    // overrides
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-    virtual bool onPrepareWidgetEvent(SkEvent* evt);
-    
-private:
-    uint8_t  fCheckState;
-    
-    typedef SkWidgetView INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-#include "SkTextBox.h"
-
-class SkStaticTextView : public SkView {
-public:
-            SkStaticTextView();
-    virtual ~SkStaticTextView();
-
-    enum Mode {
-        kFixedSize_Mode,
-        kAutoWidth_Mode,
-        kAutoHeight_Mode,
-
-        kModeCount
-    };
-    Mode    getMode() const { return (Mode)fMode; }
-    void    setMode(Mode);
-
-    SkTextBox::SpacingAlign getSpacingAlign() const { return (SkTextBox::SpacingAlign)fSpacingAlign; }
-    void    setSpacingAlign(SkTextBox::SpacingAlign);
-
-    void    getMargin(SkPoint* margin) const;
-    void    setMargin(SkScalar dx, SkScalar dy);
-
-    size_t  getText(SkString* text = NULL) const;
-    size_t  getText(char text[] = NULL) const;
-    void    setText(const SkString&);
-    void    setText(const char text[]);
-    void    setText(const char text[], size_t len);
-
-    void    getPaint(SkPaint*) const;
-    void    setPaint(const SkPaint&);
-
-protected:
-    // overrides
-    virtual void onDraw(SkCanvas*);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
-
-private:
-    SkPoint     fMargin;
-    SkString    fText;
-    SkPaint     fPaint;
-    uint8_t     fMode;
-    uint8_t     fSpacingAlign;
-
-    void computeSize();
-
-    typedef SkView INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SkAnimator;
-class SkListSource;
-class SkScrollBarView;
-
-class SkListView : public SkWidgetView {
-public:
-            SkListView();
-    virtual ~SkListView();
-
-    bool    hasScrollBar() const { return fScrollBar != NULL; }
-    void    setHasScrollBar(bool);
-    
-    /** Return the number of visible rows
-    */
-    int     getVisibleRowCount() const { return fVisibleRowCount; }
-    /** Return the index of the selected row, or -1 if none
-    */
-    int     getSelection() const { return fCurrIndex; }
-    /** Set the index of the selected row, or -1 for none
-    */
-    void    setSelection(int);
-    /** If possible, move the selection up and return true,
-        else do nothing and return false
-        If nothing is selected, select the last item (unless there are no items).
-    */
-    bool    moveSelectionUp();
-    /** If possible, move the selection down and return true,
-        else do nothing and return false.
-        If nothing is selected, select the first item (unless there are no items).
-    */
-    bool    moveSelectionDown();
-
-    SkListSource*   getListSource() const { return fSource; }
-    SkListSource*   setListSource(SkListSource*);
-
-    /** Call this in your event handler. If the specified event is from a SkListView,
-        then it returns the index of the selected item in this list, otherwise it
-        returns -1
-    */
-    static int GetWidgetEventListIndex(const SkEvent&);
-
-protected:
-    // overrides
-    virtual void onDraw(SkCanvas*);
-    virtual void onSizeChange();
-    virtual bool onEvent(const SkEvent&);
-    virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
-    virtual bool onPrepareWidgetEvent(SkEvent*);
-
-private:
-    enum DirtyFlags {
-        kAnimCount_DirtyFlag    = 0x01,
-        kAnimContent_DirtyFlag  = 0x02
-    };
-    void    dirtyCache(unsigned dirtyFlags);
-    bool    ensureCache();
-
-    int     logicalToVisualIndex(int index) const { return index - fScrollIndex; }
-    void    invalSelection();
-    SkScalar getContentWidth() const;
-    bool    getRowRect(int index, SkRect*) const;
-    void    ensureSelectionIsVisible();
-    void    ensureVisibleRowCount();
-
-    struct BindingRec;
-
-    enum Heights {
-        kNormal_Height,
-        kSelected_Height
-    };
-    SkListSource*   fSource;
-    SkScrollBarView*    fScrollBar;
-    SkAnimator*     fAnims;
-    BindingRec*     fBindings;
-    SkString        fSkinName;
-    SkScalar        fHeights[2];
-    int16_t         fScrollIndex, fCurrIndex;
-    uint16_t        fVisibleRowCount, fBindingCount;
-    SkBool8         fAnimContentDirty;
-    SkBool8         fAnimFocusDirty;
-
-    typedef SkWidgetView INHERITED;
-};
-
-class SkListSource : public SkRefCnt {
-public:
-    virtual int countFields();
-    virtual void getFieldName(int index, SkString* field);
-    /** Return the index of the named field, or -1 if not found */
-    virtual int findFieldIndex(const char field[]);
-
-    virtual int countRecords();
-    virtual void getRecord(int rowIndex, int fieldIndex, SkString* data);
-
-    virtual bool prepareWidgetEvent(SkEvent*, int rowIndex);
-    
-    static SkListSource* Factory(const char name[]);
-};
-
-#endif
diff --git a/include/views/animated/SkWidgetViews.h b/include/views/animated/SkWidgetViews.h
new file mode 100644 (file)
index 0000000..295c101
--- /dev/null
@@ -0,0 +1,305 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkWidgetViews_DEFINED
+#define SkWidgetViews_DEFINED
+
+#include "SkView.h"
+
+
+enum SkWidgetEnum {
+    kBorder_WidgetEnum,         //!< <sk-border>
+    kButton_WidgetEnum,         //!< <sk-button>
+    kImage_WidgetEnum,          //!< <sk-image>
+    kList_WidgetEnum,           //!< <sk-list>
+    kProgress_WidgetEnum,       //!< <sk-progress>
+    kScroll_WidgetEnum,         //!< <sk-scroll>
+    kText_WidgetEnum,           //!< <sk-text>
+    
+    kWidgetEnumCount
+};
+
+//determines which skin to use
+enum SkinEnum {
+    kBorder_SkinEnum,
+    kButton_SkinEnum,
+    kProgress_SkinEnum,
+    kScroll_SkinEnum,
+    kStaticText_SkinEnum,
+    
+    kSkinEnumCount
+};
+
+#include "SkAnimator.h"
+//used for inflates
+const char* get_skin_enum_path(SkinEnum se);
+void init_skin_anim(const char path[], SkAnimator* anim);
+void init_skin_anim(SkinEnum se, SkAnimator* anim);
+void init_skin_paint(SkinEnum se, SkPaint* paint);
+void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint);
+
+/** Given an enum value, return an instance of the specified widget.
+    If the enum is out of range, returns null
+*/
+SkView* SkWidgetFactory(SkWidgetEnum);
+/** Given the inflate/element name of a widget, return an instance of
+    the specified widget, or null if name does not match any known
+    widget type.
+*/
+SkView* SkWidgetFactory(const char name[]);
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkWidgetView : public SkView {
+public:
+    SkWidgetView();
+
+    const char* getLabel() const;
+    void        getLabel(SkString* label) const;
+
+    void        setLabel(const char[]);
+    void        setLabel(const char[], size_t len);
+    void        setLabel(const SkString&);
+
+    SkEvent&        event() { return fEvent; }
+    const SkEvent&  event() const { return fEvent; }
+
+    /** Returns true if the widget can post its event to its listeners.
+    */
+    bool    postWidgetEvent();
+    
+    /** Returns the sinkID of the widgetview that posted the event, or 0
+    */
+    static SkEventSinkID GetWidgetEventSinkID(const SkEvent&);
+
+protected:
+    /** called when the label changes. override in subclasses. default action invals the view's bounds.
+        called with the old and new labels, before the label has actually changed.
+    */
+    virtual void onLabelChange(const char oldLabel[], const char newLabel[]);
+    /** called before posting the event to our listeners. Override to add slots to the event
+        before posting. Return true to proceed with posting, or false to not post the event to any
+        listener. Note: the event passed in may not be the same as calling this->event().
+        Be sure to call your INHERITED method as well, so that all classes in the hierarchy get a shot
+        at modifying the event (and possibly returning false to abort).
+    */
+    virtual bool onPrepareWidgetEvent(SkEvent* evt);
+
+    // overrides
+    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+    
+private:
+    SkString    fLabel;
+    SkEvent     fEvent;
+    
+    typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkButtonView : public SkWidgetView {
+public:
+    // inflate: "sk-button"
+    
+protected:
+    // overrides
+    virtual bool onEvent(const SkEvent&);
+private:
+    typedef SkWidgetView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkCheckButtonView : public SkWidgetView {
+public:
+    SkCheckButtonView();
+
+    // inflate: "sk-checkbutton"
+    
+    enum CheckState {
+        kOff_CheckState,        //!< inflate: check-state="off"
+        kOn_CheckState,         //!< inflate: check-state="on"
+        kUnknown_CheckState     //!< inflate: check-state="unknown"
+    };
+    CheckState  getCheckState() const { return (CheckState)fCheckState; }
+    void        setCheckState(CheckState);
+
+    /** use this to extract the CheckState from an event (i.e. one that as posted
+        by a SkCheckButtonView). Returns true if the proper slot was present in the event,
+        and sets state to that value. If no proper slot is found, returns false and does not
+        modify state.
+    */
+    static bool GetWidgetEventCheckState(const SkEvent&, CheckState* state);
+
+protected:
+    // called when the check-state is about to change, but before it actually has
+    virtual void onCheckStateChange(CheckState oldState, CheckState newState);
+
+    // overrides
+    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+    virtual bool onPrepareWidgetEvent(SkEvent* evt);
+    
+private:
+    uint8_t  fCheckState;
+    
+    typedef SkWidgetView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+#include "SkTextBox.h"
+
+class SkStaticTextView : public SkView {
+public:
+            SkStaticTextView();
+    virtual ~SkStaticTextView();
+
+    enum Mode {
+        kFixedSize_Mode,
+        kAutoWidth_Mode,
+        kAutoHeight_Mode,
+
+        kModeCount
+    };
+    Mode    getMode() const { return (Mode)fMode; }
+    void    setMode(Mode);
+
+    SkTextBox::SpacingAlign getSpacingAlign() const { return (SkTextBox::SpacingAlign)fSpacingAlign; }
+    void    setSpacingAlign(SkTextBox::SpacingAlign);
+
+    void    getMargin(SkPoint* margin) const;
+    void    setMargin(SkScalar dx, SkScalar dy);
+
+    size_t  getText(SkString* text = NULL) const;
+    size_t  getText(char text[] = NULL) const;
+    void    setText(const SkString&);
+    void    setText(const char text[]);
+    void    setText(const char text[], size_t len);
+
+    void    getPaint(SkPaint*) const;
+    void    setPaint(const SkPaint&);
+
+protected:
+    // overrides
+    virtual void onDraw(SkCanvas*);
+    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
+
+private:
+    SkPoint     fMargin;
+    SkString    fText;
+    SkPaint     fPaint;
+    uint8_t     fMode;
+    uint8_t     fSpacingAlign;
+
+    void computeSize();
+
+    typedef SkView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkAnimator;
+class SkListSource;
+class SkScrollBarView;
+
+class SkListView : public SkWidgetView {
+public:
+            SkListView();
+    virtual ~SkListView();
+
+    bool    hasScrollBar() const { return fScrollBar != NULL; }
+    void    setHasScrollBar(bool);
+    
+    /** Return the number of visible rows
+    */
+    int     getVisibleRowCount() const { return fVisibleRowCount; }
+    /** Return the index of the selected row, or -1 if none
+    */
+    int     getSelection() const { return fCurrIndex; }
+    /** Set the index of the selected row, or -1 for none
+    */
+    void    setSelection(int);
+    /** If possible, move the selection up and return true,
+        else do nothing and return false
+        If nothing is selected, select the last item (unless there are no items).
+    */
+    bool    moveSelectionUp();
+    /** If possible, move the selection down and return true,
+        else do nothing and return false.
+        If nothing is selected, select the first item (unless there are no items).
+    */
+    bool    moveSelectionDown();
+
+    SkListSource*   getListSource() const { return fSource; }
+    SkListSource*   setListSource(SkListSource*);
+
+    /** Call this in your event handler. If the specified event is from a SkListView,
+        then it returns the index of the selected item in this list, otherwise it
+        returns -1
+    */
+    static int GetWidgetEventListIndex(const SkEvent&);
+
+protected:
+    // overrides
+    virtual void onDraw(SkCanvas*);
+    virtual void onSizeChange();
+    virtual bool onEvent(const SkEvent&);
+    virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
+    virtual bool onPrepareWidgetEvent(SkEvent*);
+
+private:
+    enum DirtyFlags {
+        kAnimCount_DirtyFlag    = 0x01,
+        kAnimContent_DirtyFlag  = 0x02
+    };
+    void    dirtyCache(unsigned dirtyFlags);
+    bool    ensureCache();
+
+    int     logicalToVisualIndex(int index) const { return index - fScrollIndex; }
+    void    invalSelection();
+    SkScalar getContentWidth() const;
+    bool    getRowRect(int index, SkRect*) const;
+    void    ensureSelectionIsVisible();
+    void    ensureVisibleRowCount();
+
+    struct BindingRec;
+
+    enum Heights {
+        kNormal_Height,
+        kSelected_Height
+    };
+    SkListSource*   fSource;
+    SkScrollBarView*    fScrollBar;
+    SkAnimator*     fAnims;
+    BindingRec*     fBindings;
+    SkString        fSkinName;
+    SkScalar        fHeights[2];
+    int16_t         fScrollIndex, fCurrIndex;
+    uint16_t        fVisibleRowCount, fBindingCount;
+    SkBool8         fAnimContentDirty;
+    SkBool8         fAnimFocusDirty;
+
+    typedef SkWidgetView INHERITED;
+};
+
+class SkListSource : public SkRefCnt {
+public:
+    virtual int countFields();
+    virtual void getFieldName(int index, SkString* field);
+    /** Return the index of the named field, or -1 if not found */
+    virtual int findFieldIndex(const char field[]);
+
+    virtual int countRecords();
+    virtual void getRecord(int rowIndex, int fieldIndex, SkString* data);
+
+    virtual bool prepareWidgetEvent(SkEvent*, int rowIndex);
+    
+    static SkListSource* Factory(const char name[]);
+};
+
+#endif
diff --git a/src/views/SkBorderView.cpp b/src/views/SkBorderView.cpp
deleted file mode 100644 (file)
index cc1c08b..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkBorderView.h"
-#include "SkAnimator.h"
-#include "SkWidgetViews.h"
-#include "SkSystemEventTypes.h"
-#include "SkTime.h"
-#include "SkStackViewLayout.h"
-
-SkBorderView::SkBorderView() : fLeft(SkIntToScalar(0)),
-                               fRight(SkIntToScalar(0)),
-                               fTop(SkIntToScalar(0)),
-                               fBottom(SkIntToScalar(0))
-{
-       fAnim.setHostEventSink(this);
-       init_skin_anim(kBorder_SkinEnum, &fAnim);
-}
-
-SkBorderView::~SkBorderView()
-{
-       
-}
-
-void SkBorderView::setSkin(const char skin[])
-{
-       init_skin_anim(skin, &fAnim);
-}
-
-/* virtual */ void SkBorderView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-       this->INHERITED::onInflate(dom, node);
-}
-
-/*virtual*/ void SkBorderView::onSizeChange()
-{
-       this->INHERITED::onSizeChange();
-       SkEvent evt("user");
-       evt.setString("id", "setDim");
-       evt.setScalar("dimX", this->width());
-       evt.setScalar("dimY", this->height());
-       fAnim.doUserEvent(evt);
-}
-
-/*virtual*/ void SkBorderView::onDraw(SkCanvas* canvas)
-{
-       SkPaint                                         paint;          
-       SkAnimator::DifferenceType      diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
-       
-       if (diff == SkAnimator::kDifferent)
-               this->inval(NULL);
-       else if (diff == SkAnimator::kPartiallyDifferent)
-       {
-               SkRect  bounds;
-               fAnim.getInvalBounds(&bounds);
-               this->inval(&bounds);
-       }
-}
-
-/*virtual*/ bool SkBorderView::onEvent(const SkEvent& evt)
-{
-       if (evt.isType(SK_EventType_Inval))
-       {
-               this->inval(NULL);
-               return true;
-       }
-       if (evt.isType("recommendDim"))
-       {
-               evt.findScalar("leftMargin", &fLeft);
-               evt.findScalar("rightMargin", &fRight);
-               evt.findScalar("topMargin", &fTop);
-               evt.findScalar("bottomMargin", &fBottom);
-       
-               //setup_views.cpp uses SkView::Layout instead of SkStackViewLayout
-               //but that gives me an error
-               SkStackViewLayout* layout;
-               fMargin.set(fLeft, fTop, fRight, fBottom);
-               if (this->getLayout())
-               {
-                       layout = (SkStackViewLayout*)this->getLayout();
-                       layout->setMargin(fMargin);
-               }
-               else
-               {
-                       layout = new SkStackViewLayout;
-                       layout->setMargin(fMargin);
-                       this->setLayout(layout)->unref();
-               }
-               this->invokeLayout();
-       }
-       return this->INHERITED::onEvent(evt);
-}
diff --git a/src/views/SkImageView.cpp b/src/views/SkImageView.cpp
deleted file mode 100644 (file)
index 8924dd3..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkImageView.h"
-#include "SkAnimator.h"
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkImageDecoder.h"
-#include "SkMatrix.h"
-#include "SkSystemEventTypes.h"
-#include "SkTime.h"
-
-SkImageView::SkImageView()
-{
-       fMatrix         = NULL;
-       fScaleType      = kMatrix_ScaleType;
-
-       fData.fAnim     = NULL;         // handles initializing the other union values
-       fDataIsAnim     = true;
-       
-       fUriIsValid     = false;        // an empty string is not valid
-}
-
-SkImageView::~SkImageView()
-{
-       if (fMatrix)
-               sk_free(fMatrix);
-               
-       this->freeData();
-}
-
-void SkImageView::getUri(SkString* uri) const
-{
-       if (uri)
-               *uri = fUri;
-}
-
-void SkImageView::setUri(const char uri[])
-{
-       if (!fUri.equals(uri))
-       {
-               fUri.set(uri);
-               this->onUriChange();
-       }
-}
-
-void SkImageView::setUri(const SkString& uri)
-{
-       if (fUri != uri)
-       {
-               fUri = uri;
-               this->onUriChange();
-       }
-}
-
-void SkImageView::setScaleType(ScaleType st)
-{
-       SkASSERT((unsigned)st <= kFitEnd_ScaleType);
-
-       if ((ScaleType)fScaleType != st)
-       {
-               fScaleType = SkToU8(st);
-               if (fUriIsValid)
-                       this->inval(NULL);
-       }
-}
-
-bool SkImageView::getImageMatrix(SkMatrix* matrix) const
-{
-       if (fMatrix)
-       {
-               SkASSERT(!fMatrix->isIdentity());
-               if (matrix)
-                       *matrix = *fMatrix;
-               return true;
-       }
-       else
-       {
-               if (matrix)
-                       matrix->reset();
-               return false;
-       }
-}
-
-void SkImageView::setImageMatrix(const SkMatrix* matrix)
-{
-       bool changed = false;
-
-       if (matrix && !matrix->isIdentity())
-       {
-               if (fMatrix == NULL)
-                       fMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
-               *fMatrix = *matrix;
-               changed = true;
-       }
-       else    // set us to identity
-       {
-               if (fMatrix)
-               {
-                       SkASSERT(!fMatrix->isIdentity());
-                       sk_free(fMatrix);
-                       fMatrix = NULL;
-                       changed = true;
-               }
-       }
-
-       // only redraw if we changed our matrix and we're not in scaleToFit mode
-       if (changed && this->getScaleType() == kMatrix_ScaleType && fUriIsValid)
-               this->inval(NULL);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-bool SkImageView::onEvent(const SkEvent& evt)
-{
-       if (evt.isType(SK_EventType_Inval))
-       {
-               if (fUriIsValid)
-                       this->inval(NULL);
-               return true;
-       }
-       return this->INHERITED::onEvent(evt);
-}
-
-static inline SkMatrix::ScaleToFit scaleTypeToScaleToFit(SkImageView::ScaleType st)
-{
-       SkASSERT(st != SkImageView::kMatrix_ScaleType);
-       SkASSERT((unsigned)st <= SkImageView::kFitEnd_ScaleType);
-
-       SkASSERT(SkImageView::kFitXY_ScaleType - 1 == SkMatrix::kFill_ScaleToFit);
-       SkASSERT(SkImageView::kFitStart_ScaleType - 1 == SkMatrix::kStart_ScaleToFit);
-       SkASSERT(SkImageView::kFitCenter_ScaleType - 1 == SkMatrix::kCenter_ScaleToFit);
-       SkASSERT(SkImageView::kFitEnd_ScaleType - 1 == SkMatrix::kEnd_ScaleToFit);
-       
-       return (SkMatrix::ScaleToFit)(st - 1);
-}
-
-void SkImageView::onDraw(SkCanvas* canvas)
-{
-       SkRect  src;
-       if (!this->getDataBounds(&src))
-       {
-               SkDEBUGCODE(canvas->drawColor(SK_ColorRED);)
-               return;         // nothing to draw
-       }
-               
-       SkAutoCanvasRestore     restore(canvas, true);
-       SkMatrix                        matrix;
-       
-       if (this->getScaleType() == kMatrix_ScaleType)
-               (void)this->getImageMatrix(&matrix);
-       else
-       {
-               SkRect  dst;            
-               dst.set(0, 0, this->width(), this->height());
-               matrix.setRectToRect(src, dst, scaleTypeToScaleToFit(this->getScaleType()));
-       }
-       canvas->concat(matrix);
-
-       SkPaint paint;
-       
-       paint.setAntiAlias(true);
-
-       if (fDataIsAnim)
-       {
-               SkMSec  now = SkTime::GetMSecs();
-               
-               SkAnimator::DifferenceType diff = fData.fAnim->draw(canvas, &paint, now);
-               
-SkDEBUGF(("SkImageView : now = %X[%12.3f], diff = %d\n", now, now/1000., diff));
-
-               if (diff == SkAnimator::kDifferent)
-                       this->inval(NULL);
-               else if (diff == SkAnimator::kPartiallyDifferent)
-               {
-                       SkRect  bounds;
-                       fData.fAnim->getInvalBounds(&bounds);
-                       matrix.mapRect(&bounds);        // get the bounds into view coordinates
-                       this->inval(&bounds);
-               }
-       }
-       else
-               canvas->drawBitmap(*fData.fBitmap, 0, 0, &paint);
-}
-
-void SkImageView::onInflate(const SkDOM& dom, const SkDOMNode* node)
-{
-       this->INHERITED::onInflate(dom, node);
-       
-       const char* src = dom.findAttr(node, "src");
-       if (src)
-               this->setUri(src);
-
-       int     index = dom.findList(node, "scaleType", "matrix,fitXY,fitStart,fitCenter,fitEnd");
-       if (index >= 0)
-               this->setScaleType((ScaleType)index);
-               
-       // need inflate syntax/reader for matrix
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-
-void SkImageView::onUriChange()
-{
-       if (this->freeData())
-               this->inval(NULL);
-       fUriIsValid = true;             // give ensureUriIsLoaded() a shot at the new uri
-}
-
-bool SkImageView::freeData()
-{
-       if (fData.fAnim)        // test is valid for all union values
-       {
-               if (fDataIsAnim)
-                       delete fData.fAnim;
-               else
-                       delete fData.fBitmap;
-
-               fData.fAnim = NULL;     // valid for all union values
-               return true;
-       }
-       return false;
-}
-
-bool SkImageView::getDataBounds(SkRect* bounds)
-{
-       SkASSERT(bounds);
-
-       if (this->ensureUriIsLoaded())
-       {
-               SkScalar width, height;
-
-               if (fDataIsAnim)
-               {                       
-                       if (SkScalarIsNaN(width = fData.fAnim->getScalar("dimensions", "x")) ||
-                               SkScalarIsNaN(height = fData.fAnim->getScalar("dimensions", "y")))
-                       {
-                               // cons up fake bounds
-                               width = this->width();
-                               height = this->height();
-                       }
-               }
-               else
-               {
-                       width = SkIntToScalar(fData.fBitmap->width());
-                       height = SkIntToScalar(fData.fBitmap->height());
-               }
-               bounds->set(0, 0, width, height);
-               return true;
-       }
-       return false;
-}
-
-bool SkImageView::ensureUriIsLoaded()
-{
-       if (fData.fAnim)        // test is valid for all union values
-       {
-               SkASSERT(fUriIsValid);
-               return true;
-       }
-       if (!fUriIsValid)
-               return false;
-
-       // try to load the url
-       if (fUri.endsWith(".xml"))      // assume it is screenplay
-       {
-               SkAnimator* anim = new SkAnimator;
-               
-               if (!anim->decodeURI(fUri.c_str()))
-               {
-                       delete anim;
-                       fUriIsValid = false;
-                       return false;
-               }
-               anim->setHostEventSink(this);
-
-               fData.fAnim = anim;
-               fDataIsAnim = true;
-       }
-       else    // assume it is an image format
-       {
-    #if 0
-               SkBitmap* bitmap = new SkBitmap;
-
-               if (!SkImageDecoder::DecodeURL(fUri.c_str(), bitmap))
-               {
-                       delete bitmap;
-                       fUriIsValid = false;
-                       return false;
-               }
-               fData.fBitmap = bitmap;
-               fDataIsAnim = false;
-    #else
-        return false;
-    #endif
-       }
-       return true;
-}
-
diff --git a/src/views/SkListWidget.cpp b/src/views/SkListWidget.cpp
deleted file mode 100644 (file)
index 4d95e0f..0000000
+++ /dev/null
@@ -1,630 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkWidgetViews.h"
-
-#include "SkAnimator.h"
-#include "SkScrollBarView.h"
-
-extern void init_skin_anim(const char name[], SkAnimator*);
-
-struct SkListView::BindingRec {
-       SkString        fSlotName;
-       int                     fFieldIndex;
-};
-
-SkListView::SkListView()
-{
-       fSource = NULL;                         // our list-source
-       fScrollBar = NULL;
-       fAnims = NULL;                          // array of animators[fVisibleRowCount]
-       fBindings = NULL;                       // our fields->slot array
-       fBindingCount = 0;                      // number of entries in fSlots array
-       fScrollIndex = 0;                       // number of cells to skip before first visible cell
-       fCurrIndex = -1;                        // index of "selected" cell
-       fVisibleRowCount = 0;           // number of cells that can fit in our bounds
-       fAnimContentDirty = true;       // true if fAnims[] have their correct content
-       fAnimFocusDirty = true;
-
-       fHeights[kNormal_Height] = SkIntToScalar(16);
-       fHeights[kSelected_Height] = SkIntToScalar(16);
-       
-       this->setFlags(this->getFlags() | kFocusable_Mask);
-}
-
-SkListView::~SkListView()
-{
-       SkSafeUnref(fScrollBar);
-       SkSafeUnref(fSource);
-       delete[] fAnims;
-       delete[] fBindings;
-}
-
-void SkListView::setHasScrollBar(bool hasSB)
-{
-       if (hasSB != this->hasScrollBar())
-       {
-               if (hasSB)
-               {
-                       SkASSERT(fScrollBar == NULL);
-                       fScrollBar = (SkScrollBarView*)SkWidgetFactory(kScroll_WidgetEnum);
-                       fScrollBar->setVisibleP(true);
-                       this->attachChildToFront(fScrollBar);
-                       fScrollBar->setHeight(this->height());  // assume it auto-sets its width
-               //      fScrollBar->setLoc(this->getContentWidth(), 0);
-                       fScrollBar->setLoc(this->width()-SkIntToScalar(10), 0);
-               }
-               else
-               {
-                       SkASSERT(fScrollBar);
-                       fScrollBar->detachFromParent();
-                       fScrollBar->unref();
-                       fScrollBar = NULL;
-               }
-               this->dirtyCache(kAnimContent_DirtyFlag);
-       }
-}
-
-void SkListView::setSelection(int index)
-{
-       if (fCurrIndex != index)
-       {
-               fAnimFocusDirty = true;
-               this->inval(NULL);
-
-               this->invalSelection();
-               fCurrIndex = index;
-               this->invalSelection();
-               this->ensureSelectionIsVisible();
-       }
-}
-
-bool SkListView::moveSelectionUp()
-{
-       if (fSource)
-       {
-               int     index = fCurrIndex;
-               if (index < 0)  // no selection
-                       index = fSource->countRecords() - 1;
-               else
-                       index = SkMax32(index - 1, 0);
-               
-               if (fCurrIndex != index)
-               {
-                       this->setSelection(index);
-                       return true;
-               }
-       }
-       return false;
-}
-
-bool SkListView::moveSelectionDown()
-{
-       if (fSource)
-       {
-               int     index = fCurrIndex;
-               if (index < 0)  // no selection
-                       index = 0;
-               else
-                       index = SkMin32(index + 1, fSource->countRecords() - 1);
-               
-               if (fCurrIndex != index)
-               {
-                       this->setSelection(index);
-                       return true;
-               }
-       }
-       return false;
-}
-
-void SkListView::invalSelection()
-{
-       SkRect  r;
-       if (this->getRowRect(fCurrIndex, &r))
-               this->inval(&r);
-}
-
-void SkListView::ensureSelectionIsVisible()
-{
-       if (fSource && (unsigned)fCurrIndex < (unsigned)fSource->countRecords())
-       {
-               int index = this->logicalToVisualIndex(fCurrIndex);
-
-               if ((unsigned)index >= (unsigned)fVisibleRowCount)      // need to scroll
-               {
-                       int newIndex;
-                       
-                       if (index < 0)  // too high
-                               newIndex = fCurrIndex;
-                       else
-                               newIndex = fCurrIndex - fVisibleRowCount + 1;
-                       SkASSERT((unsigned)newIndex < (unsigned)fSource->countRecords());
-                       this->inval(NULL);
-                       
-                       if (fScrollIndex != newIndex)
-                       {
-                               fScrollIndex = newIndex;
-                               if (fScrollBar)
-                                       fScrollBar->setStart(newIndex);
-                               this->dirtyCache(kAnimContent_DirtyFlag);
-                       }
-               }
-       }
-}
-
-SkScalar SkListView::getContentWidth() const
-{
-       SkScalar width = this->width();
-       
-       if (fScrollBar)
-       {
-               width -= fScrollBar->width();
-               if (width < 0)
-                       width = 0;
-       }
-       return width;
-}
-
-bool SkListView::getRowRect(int index, SkRect* r) const
-{
-       SkASSERT(r);
-
-       index = this->logicalToVisualIndex(index);
-       if (index >= 0)
-       {
-               int     selection = this->logicalToVisualIndex(fCurrIndex);
-               
-               SkScalar height = fHeights[index == selection ? kSelected_Height : kNormal_Height];
-               SkScalar top = index * fHeights[kNormal_Height];
-
-               if (index > selection && selection >= 0)
-                       top += fHeights[kSelected_Height] - fHeights[kNormal_Height];   
-
-               if (top < this->height())
-               {
-                       if (r)
-                               r->set(0, top, this->getContentWidth(), top + height);
-                       return true;
-               }
-       }
-       return false;
-}
-
-SkListSource* SkListView::setListSource(SkListSource* src)
-{
-       if (fSource != src)
-       {
-               SkRefCnt_SafeAssign(fSource, src);
-               this->ensureSelectionIsVisible();
-               this->inval(NULL);
-               
-               if (fScrollBar)
-                       fScrollBar->setTotal(fSource->countRecords());
-       }
-       return src;
-}
-
-void SkListView::dirtyCache(unsigned dirtyFlags)
-{
-       if (dirtyFlags & kAnimCount_DirtyFlag)
-       {
-               delete fAnims;
-               fAnims = NULL;
-               fAnimContentDirty = true;
-               fAnimFocusDirty = true;
-       }
-       if (dirtyFlags & kAnimContent_DirtyFlag)
-       {
-               if (!fAnimContentDirty)
-               {
-                       this->inval(NULL);
-                       fAnimContentDirty = true;
-               }
-               fAnimFocusDirty = true;
-       }
-}
-
-bool SkListView::ensureCache()
-{
-       if (fSkinName.size() == 0)
-               return false;
-
-       if (fAnims == NULL)
-       {
-               int n = SkMax32(1, fVisibleRowCount);
-
-               SkASSERT(fAnimContentDirty);
-               fAnims = new SkAnimator[n];
-               for (int i = 0; i < n; i++)
-               {
-                       fAnims[i].setHostEventSink(this);
-                       init_skin_anim(fSkinName.c_str(), &fAnims[i]);
-               }
-               
-               fHeights[kNormal_Height] = fAnims[0].getScalar("idleHeight", "value");
-               fHeights[kSelected_Height] = fAnims[0].getScalar("focusedHeight", "value");
-
-               fAnimFocusDirty = true;
-       }
-
-       if (fAnimContentDirty && fSource)
-       {
-               fAnimContentDirty = false;
-
-               SkString        str;
-               SkEvent         evt("user");
-               evt.setString("id", "setFields");
-               evt.setS32("rowCount", fVisibleRowCount);
-               
-               SkEvent dimEvt("user");
-               dimEvt.setString("id", "setDim");
-               dimEvt.setScalar("dimX", this->getContentWidth());
-               dimEvt.setScalar("dimY", this->height());
-
-               for (int i = fScrollIndex; i < fScrollIndex + fVisibleRowCount; i++)
-               {
-                       evt.setS32("relativeIndex", i - fScrollIndex);
-                       for (int j = 0; j < fBindingCount; j++)
-                       {
-                               fSource->getRecord(i, fBindings[j].fFieldIndex, &str);
-//SkDEBUGF(("getRecord(%d,%d,%s) slot(%s)\n", i, fBindings[j].fFieldIndex, str.c_str(), fBindings[j].fSlotName.c_str()));
-                               evt.setString(fBindings[j].fSlotName.c_str(), str.c_str());
-                       }
-                       (void)fAnims[i % fVisibleRowCount].doUserEvent(evt);
-                       (void)fAnims[i % fVisibleRowCount].doUserEvent(dimEvt);
-               }
-               fAnimFocusDirty = true;
-       }
-
-       if (fAnimFocusDirty)
-       {
-//SkDEBUGF(("service fAnimFocusDirty\n"));
-               fAnimFocusDirty = false;
-
-               SkEvent         focusEvt("user");
-               focusEvt.setString("id", "setFocus");
-
-               for (int i = fScrollIndex; i < fScrollIndex + fVisibleRowCount; i++)
-               {
-                       focusEvt.setS32("FOCUS", i == fCurrIndex);
-                       (void)fAnims[i % fVisibleRowCount].doUserEvent(focusEvt);
-               }
-       }
-
-       return true;
-}
-
-void SkListView::ensureVisibleRowCount()
-{
-       SkScalar        height = this->height();
-       int                     n = 0;
-       
-       if (height > 0)
-       {
-               n = 1;
-               height -= fHeights[kSelected_Height];
-               if (height > 0)
-               {
-                       SkScalar count = SkScalarDiv(height, fHeights[kNormal_Height]);
-                       n += SkScalarFloor(count);
-                       if (count - SkIntToScalar(n) > SK_Scalar1*3/4)
-                               n += 1;
-                               
-               //      SkDebugf("count %g, n %d\n", count/65536., n);
-               }
-       }
-
-       if (fVisibleRowCount != n)
-       {
-               if (fScrollBar)
-                       fScrollBar->setShown(n);
-
-               fVisibleRowCount = n;
-               this->ensureSelectionIsVisible();
-               this->dirtyCache(kAnimCount_DirtyFlag | kAnimContent_DirtyFlag);
-       }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "SkSystemEventTypes.h"
-#include "SkTime.h"
-
-void SkListView::onSizeChange()
-{
-       this->INHERITED::onSizeChange();
-
-       if (fScrollBar)
-               fScrollBar->setLoc(this->width()-SkIntToScalar(10), 0);
-
-       this->ensureVisibleRowCount();
-}
-
-void SkListView::onDraw(SkCanvas* canvas)
-{
-       this->INHERITED::onDraw(canvas);
-
-       this->ensureVisibleRowCount();
-
-       int     visibleCount = SkMin32(fVisibleRowCount, fSource->countRecords() - fScrollIndex);
-       if (visibleCount == 0 || !this->ensureCache())
-               return;
-
-//SkDebugf("visibleCount %d scrollIndex %d currIndex %d\n", visibleCount, fScrollIndex, fCurrIndex);
-
-       SkAutoCanvasRestore     ar(canvas, true);
-       SkMSec                          now = SkTime::GetMSecs();
-       SkRect                          bounds;
-
-       bounds.fLeft    = 0;
-       bounds.fRight   = this->getContentWidth();
-       bounds.fBottom  = 0;
-       // assign bounds.fTop inside the loop
-
-       // hack to reveal our bounds for debugging
-       if (this->hasFocus())
-               canvas->drawARGB(0x11, 0, 0, 0xFF);
-       else
-               canvas->drawARGB(0x11, 0x88, 0x88, 0x88);
-
-       for (int i = fScrollIndex; i < fScrollIndex + visibleCount; i++)
-       {
-               SkPaint  paint;
-               SkScalar height = fHeights[i == fCurrIndex ? kSelected_Height : kNormal_Height];
-
-               bounds.fTop = bounds.fBottom;
-               bounds.fBottom += height;
-               
-               canvas->save();
-               if (fAnims[i % fVisibleRowCount].draw(canvas, &paint, now) != SkAnimator::kNotDifferent)
-                       this->inval(&bounds);
-               canvas->restore();
-
-               canvas->translate(0, height);
-       }
-}
-
-bool SkListView::onEvent(const SkEvent& evt)
-{
-       if (evt.isType(SK_EventType_Key))
-       {
-               switch (evt.getFast32()) {
-               case kUp_SkKey:
-                       return this->moveSelectionUp();
-               case kDown_SkKey:
-                       return this->moveSelectionDown();
-               case kRight_SkKey:
-               case kOK_SkKey:
-                       this->postWidgetEvent();
-                       return true;
-               default:
-                       break;
-               }
-       }
-       return this->INHERITED::onEvent(evt);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-static const char gListViewEventSlot[] = "sk-listview-slot-name";
-
-/*virtual*/ bool SkListView::onPrepareWidgetEvent(SkEvent* evt)
-{
-       if (fSource && fCurrIndex >= 0 && this->INHERITED::onPrepareWidgetEvent(evt) &&
-               fSource->prepareWidgetEvent(evt, fCurrIndex))
-       {
-               evt->setS32(gListViewEventSlot, fCurrIndex);
-               return true;
-       }
-       return false;
-}
-
-int SkListView::GetWidgetEventListIndex(const SkEvent& evt)
-{
-       int32_t index;
-
-       return evt.findS32(gListViewEventSlot, &index) ? index : -1;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-void SkListView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-       this->INHERITED::onInflate(dom, node);
-       
-       {
-               bool hasScrollBar;
-               if (dom.findBool(node, "scrollBar", &hasScrollBar))
-                       this->setHasScrollBar(hasScrollBar);
-       }
-
-       const SkDOM::Node*      child;
-
-       if ((child = dom.getFirstChild(node, "bindings")) != NULL)
-       {
-               delete[] fBindings;
-               fBindings = NULL;
-               fBindingCount = 0;
-
-               SkListSource* listSrc = SkListSource::Factory(dom.findAttr(child, "data-fields"));
-               SkASSERT(listSrc);
-               fSkinName.set(dom.findAttr(child, "skin-slots"));
-               SkASSERT(fSkinName.size());
-
-               this->setListSource(listSrc)->unref();
-                       
-               int count = dom.countChildren(child, "bind");
-               if (count > 0)
-               {
-                       fBindings = new BindingRec[count];
-                       count = 0;      // reuse this to count up to the number of valid bindings
-
-                       child = dom.getFirstChild(child, "bind");
-                       SkASSERT(child);
-                       do {
-                               const char* fieldName = dom.findAttr(child, "field");
-                               const char* slotName = dom.findAttr(child, "slot");
-                               if (fieldName && slotName)
-                               {
-                                       fBindings[count].fFieldIndex = listSrc->findFieldIndex(fieldName);
-                                       if (fBindings[count].fFieldIndex >= 0)
-                                               fBindings[count++].fSlotName.set(slotName);
-                               }
-                       } while ((child = dom.getNextSibling(child, "bind")) != NULL);
-
-                       fBindingCount = SkToU16(count);
-                       if (count == 0)
-                       {
-                               SkDEBUGF(("SkListView::onInflate: no valid <bind> elements in <listsource>\n"));
-                               delete[] fBindings;
-                       }
-               }
-               this->dirtyCache(kAnimCount_DirtyFlag);
-               this->setSelection(0);
-       }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-class SkXMLListSource : public SkListSource {
-public:
-       SkXMLListSource(const char doc[], size_t len);
-       virtual ~SkXMLListSource()
-       {
-               delete[] fFields;
-               delete[] fRecords;
-       }
-
-       virtual int countFields() { return fFieldCount; }
-       virtual void getFieldName(int index, SkString* field)
-       {
-               SkASSERT((unsigned)index < (unsigned)fFieldCount);
-               if (field)
-                       *field = fFields[index];
-       }
-       virtual int findFieldIndex(const char field[])
-       {
-               for (int i = 0; i < fFieldCount; i++)
-                       if (fFields[i].equals(field))
-                               return i;
-               return -1;
-       }
-
-       virtual int     countRecords() { return fRecordCount; }
-       virtual void getRecord(int rowIndex, int fieldIndex, SkString* data)
-       {
-               SkASSERT((unsigned)rowIndex < (unsigned)fRecordCount);
-               SkASSERT((unsigned)fieldIndex < (unsigned)fFieldCount);
-               if (data)
-                       *data = fRecords[rowIndex * fFieldCount + fieldIndex];
-       }
-
-       virtual bool prepareWidgetEvent(SkEvent* evt, int rowIndex)
-       {
-               // hack, for testing right now. Need the xml to tell us what to jam in and where
-               SkString        data;
-               
-               this->getRecord(rowIndex, 0, &data);
-               evt->setString("xml-listsource", data.c_str());
-               return true;
-       }
-       
-private:
-       SkString*       fFields;        // [fFieldCount]
-       SkString*       fRecords;       // [fRecordCount][fFieldCount]
-       int                     fFieldCount, fRecordCount;
-};
-
-#include "SkDOM.h"
-
-SkXMLListSource::SkXMLListSource(const char doc[], size_t len)
-{
-       fFieldCount = fRecordCount = 0;
-       fFields = fRecords = NULL;
-
-       SkDOM   dom;
-
-       const SkDOM::Node* node = dom.build(doc, len);
-       SkASSERT(node);
-       const SkDOM::Node*      child;  
-
-       child = dom.getFirstChild(node, "fields");
-       if (child)
-       {
-               fFieldCount = dom.countChildren(child, "field");
-               fFields = new SkString[fFieldCount];
-
-               int n = 0;
-               child = dom.getFirstChild(child, "field");
-               while (child)
-               {
-                       fFields[n].set(dom.findAttr(child, "name"));
-                       child = dom.getNextSibling(child, "field");
-                       n += 1;
-               }
-               SkASSERT(n == fFieldCount);
-       }
-       
-       child = dom.getFirstChild(node, "records");
-       if (child)
-       {
-               fRecordCount = dom.countChildren(child, "record");
-               fRecords = new SkString[fRecordCount * fFieldCount];
-
-               int n = 0;
-               child = dom.getFirstChild(child, "record");
-               while (child)
-               {
-                       for (int i = 0; i < fFieldCount; i++)
-                               fRecords[n * fFieldCount + i].set(dom.findAttr(child, fFields[i].c_str()));
-                       child = dom.getNextSibling(child, "record");
-                       n += 1;
-               }
-               SkASSERT(n == fRecordCount);
-       }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-SkListSource* SkListSource::Factory(const char name[])
-{
-       static const char gDoc[] =
-               "<db name='contacts.db'>"
-                       "<fields>"
-                               "<field name='name'/>"
-                               "<field name='work-num'/>"
-                               "<field name='home-num'/>"
-                               "<field name='type'/>"
-                       "</fields>"
-                       "<records>"
-                               "<record name='Andy McFadden' work-num='919 357-1234' home-num='919 123-4567' type='0'/>"
-                               "<record name='Brian Swetland' work-num='919 123-1234' home-num='929 123-4567' type='1' />"
-                               "<record name='Chris Desalvo' work-num='919 345-1234' home-num='949 123-4567' type='1' />"
-                               "<record name='Chris White' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
-                               "<record name='Dan Bornstein' work-num='919 357-1234' home-num='919 123-4567' type='0' />"
-                               "<record name='Don Cung' work-num='919 123-1234' home-num='929 123-4567' type='2' />"
-                               "<record name='Eric Fischer' work-num='919 345-1234' home-num='949 123-4567' type='2' />"
-                               "<record name='Ficus Kirkpatric' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
-                               "<record name='Jack Veenstra' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
-                               "<record name='Jeff Yaksick' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
-                               "<record name='Joe Onorato' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
-                               "<record name='Mathias Agopian' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
-                               "<record name='Mike Fleming' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
-                               "<record name='Nick Sears' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
-                               "<record name='Rich Miner' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
-                               "<record name='Tracey Cole' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
-                               "<record name='Wei Huang' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
-                       "</records>"
-               "</db>";
-               
-//SkDebugf("doc size %d\n", sizeof(gDoc)-1);
-       return new SkXMLListSource(gDoc, sizeof(gDoc) - 1);
-}
-
-
-
diff --git a/src/views/SkProgressBarView.cpp b/src/views/SkProgressBarView.cpp
deleted file mode 100644 (file)
index ce26ac4..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkProgressBarView.h"
-#include "SkAnimator.h"
-#include "SkWidgetViews.h"
-#include "SkTime.h"
-#include "SkSystemEventTypes.h"
-
-SkProgressBarView::SkProgressBarView()
-{
-       init_skin_anim(kProgress_SkinEnum, &fAnim);
-       fAnim.setHostEventSink(this);
-       fProgress = 0;
-       fMax = 100;
-       
-}
-
-void SkProgressBarView::changeProgress(int diff)
-{
-       int newProg = fProgress + diff;
-       if (newProg > 0 && newProg < fMax)
-               this->setProgress(newProg);
-       //otherwise i'll just leave it as it is
-       //this implies that if a new max and progress are set, max must be set first
-}
-
-/*virtual*/ void SkProgressBarView::onDraw(SkCanvas* canvas)
-{
-       SkPaint                                         paint;          
-       SkAnimator::DifferenceType      diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
-       
-       if (diff == SkAnimator::kDifferent)
-               this->inval(NULL);
-       else if (diff == SkAnimator::kPartiallyDifferent)
-       {
-               SkRect  bounds;
-               fAnim.getInvalBounds(&bounds);
-               this->inval(&bounds);
-       }
-}
-       
-/*virtual*/ bool SkProgressBarView::onEvent(const SkEvent& evt)
-{
-       if (evt.isType(SK_EventType_Inval))
-       {
-               this->inval(NULL);
-               return true;
-       }
-       if (evt.isType("recommendDim"))
-       {
-               SkScalar        height;
-               
-               if (evt.findScalar("y", &height))
-                       this->setHeight(height);
-               return true;
-       }
-       return this->INHERITED::onEvent(evt);
-}
-
-/*virtual*/ void SkProgressBarView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-       this->INHERITED::onInflate(dom, node);
-       int32_t temp;
-       if (dom.findS32(node, "max", &temp))
-               this->setMax(temp);
-       if (dom.findS32(node, "progress", &temp))
-               this->setProgress(temp);
-}
-
-/*virtual*/ void SkProgressBarView::onSizeChange()
-{
-       this->INHERITED::onSizeChange();
-       SkEvent evt("user");
-       evt.setString("id", "setDim");
-       evt.setScalar("dimX", this->width());
-       evt.setScalar("dimY", this->height());
-       fAnim.doUserEvent(evt);
-}
-
-void SkProgressBarView::reset()
-{
-       fProgress = 0;
-       SkEvent e("user");
-       e.setString("id", "reset");
-       fAnim.doUserEvent(e);
-}
-
-void SkProgressBarView::setMax(int max)
-{
-       fMax = max;
-       SkEvent e("user");
-       e.setString("id", "setMax");
-       e.setS32("newMax", max);
-       fAnim.doUserEvent(e);
-}
-
-void SkProgressBarView::setProgress(int progress)
-{
-       fProgress = progress;
-       SkEvent e("user");
-       e.setString("id", "setProgress");
-       e.setS32("newProgress", progress);
-       fAnim.doUserEvent(e);
-}
diff --git a/src/views/SkScrollBarView.cpp b/src/views/SkScrollBarView.cpp
deleted file mode 100644 (file)
index 98288f5..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkScrollBarView.h"
-#include "SkAnimator.h"
-#include "SkWidgetViews.h"
-#include "SkSystemEventTypes.h"
-#include "SkTime.h"
-
-//see SkProgressBarView.cpp
-//#include "SkWidgetViews.cpp"
-
-SkScrollBarView::SkScrollBarView()
-{
-       fAnim.setHostEventSink(this);
-       init_skin_anim(kScroll_SkinEnum, &fAnim);
-
-       fTotalLength = 0;
-       fStartPoint = 0;
-       fShownLength = 0;
-
-       this->adjust();
-}
-
-void SkScrollBarView::setStart(unsigned start)
-{
-       if ((int)start < 0)
-               start = 0;
-       
-       if (fStartPoint != start)
-       {
-               fStartPoint = start;
-               this->adjust();
-       }
-}
-
-void SkScrollBarView::setShown(unsigned shown)
-{
-       if ((int)shown < 0)
-               shown = 0;
-
-       if (fShownLength != shown)
-       {
-               fShownLength = shown;
-               this->adjust();
-       }
-}
-
-void SkScrollBarView::setTotal(unsigned total)
-{
-       if ((int)total < 0)
-               total = 0;
-
-       if (fTotalLength != total)
-       {
-               fTotalLength = total;
-               this->adjust();
-       }
-}
-
-/* virtual */ void SkScrollBarView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-       this->INHERITED::onInflate(dom, node);
-       
-       int32_t value;
-       if (dom.findS32(node, "total", &value))
-               this->setTotal(value);
-       if (dom.findS32(node, "shown", &value))
-               this->setShown(value);
-}
-
-/*virtual*/ void SkScrollBarView::onSizeChange()
-{
-       this->INHERITED::onSizeChange();
-       SkEvent evt("user");
-       evt.setString("id", "setDim");
-       evt.setScalar("dimX", this->width());
-       evt.setScalar("dimY", this->height());
-       fAnim.doUserEvent(evt);
-}
-
-/*virtual*/ void SkScrollBarView::onDraw(SkCanvas* canvas)
-{
-       SkPaint                                         paint;          
-       SkAnimator::DifferenceType      diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
-       
-       if (diff == SkAnimator::kDifferent)
-               this->inval(NULL);
-       else if (diff == SkAnimator::kPartiallyDifferent)
-       {
-               SkRect  bounds;
-               fAnim.getInvalBounds(&bounds);
-               this->inval(&bounds);
-       }
-}
-
-/*virtual*/ bool SkScrollBarView::onEvent(const SkEvent& evt)
-{
-       if (evt.isType(SK_EventType_Inval))
-       {
-               this->inval(NULL);
-               return true;
-       }
-       if (evt.isType("recommendDim"))
-       {
-               SkScalar        width;
-               
-               if (evt.findScalar("x", &width))
-                       this->setWidth(width);
-               return true;
-       }
-
-       return this->INHERITED::onEvent(evt);
-}
-
-void SkScrollBarView::adjust()
-{
-       int total = fTotalLength;
-       int start = fStartPoint;
-       int shown = fShownLength;
-       int hideBar = 0;
-       
-       if (total <= 0 || shown <= 0 || shown >= total) // no bar to show
-       {
-               total = 1;              // avoid divide-by-zero. should be done by skin/script
-               hideBar = 1;    // signal we don't want a thumb
-       }
-       else
-       {
-               if (start + shown > total)
-                       start = total - shown;
-       }
-       
-       SkEvent e("user");
-       e.setString("id", "adjustScrollBar");
-       e.setScalar("_totalLength", SkIntToScalar(total));
-       e.setScalar("_startPoint", SkIntToScalar(start));
-       e.setScalar("_shownLength", SkIntToScalar(shown));
-//     e.setS32("hideBar", hideBar);
-       fAnim.doUserEvent(e);
-}
-
diff --git a/src/views/SkStaticTextView.cpp b/src/views/SkStaticTextView.cpp
deleted file mode 100644 (file)
index 2fd04a7..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkWidgetViews.h"
-#include "SkTextBox.h"
-
-#ifdef SK_DEBUG
-static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
-{
-    const char* value = dom.findAttr(node, attr);
-    if (value)
-        SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
-}
-#else
-    #define assert_no_attr(dom, node, attr)
-#endif
-
-SkStaticTextView::SkStaticTextView()
-{
-       fMargin.set(0, 0);
-       fMode = kFixedSize_Mode;
-       fSpacingAlign = SkTextBox::kStart_SpacingAlign;
-       
-//     init_skin_paint(kStaticText_SkinEnum, &fPaint);
-}
-
-SkStaticTextView::~SkStaticTextView()
-{
-}
-
-void SkStaticTextView::computeSize()
-{
-       if (fMode == kAutoWidth_Mode)
-       {
-               SkScalar width = fPaint.measureText(fText.c_str(), fText.size());
-               this->setWidth(width + fMargin.fX * 2);
-       }
-       else if (fMode == kAutoHeight_Mode)
-       {
-               SkScalar width = this->width() - fMargin.fX * 2;
-               int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0;
-
-               this->setHeight(lines * fPaint.getFontSpacing() + fMargin.fY * 2);
-       }
-}
-
-void SkStaticTextView::setMode(Mode mode)
-{
-       SkASSERT((unsigned)mode < kModeCount);
-
-       if (fMode != mode)
-       {
-               fMode = SkToU8(mode);
-               this->computeSize();
-       }
-}
-
-void SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align)
-{
-       fSpacingAlign = SkToU8(align);
-       this->inval(NULL);
-}
-
-void SkStaticTextView::getMargin(SkPoint* margin) const
-{
-       if (margin)
-               *margin = fMargin;
-}
-
-void SkStaticTextView::setMargin(SkScalar dx, SkScalar dy)
-{
-       if (fMargin.fX != dx || fMargin.fY != dy)
-       {
-               fMargin.set(dx, dy);
-               this->computeSize();
-               this->inval(NULL);
-       }
-}
-
-size_t SkStaticTextView::getText(SkString* text) const
-{
-       if (text)
-               *text = fText;
-       return fText.size();
-}
-
-size_t SkStaticTextView::getText(char text[]) const
-{
-       if (text)
-               memcpy(text, fText.c_str(), fText.size());
-       return fText.size();
-}
-
-void SkStaticTextView::setText(const SkString& text)
-{
-       this->setText(text.c_str(), text.size());
-}
-
-void SkStaticTextView::setText(const char text[])
-{
-       if (text == NULL)
-               text = "";
-       this->setText(text, strlen(text));
-}
-
-void SkStaticTextView::setText(const char text[], size_t len)
-{
-       if (!fText.equals(text, len))
-       {
-               fText.set(text, len);
-               this->computeSize();
-               this->inval(NULL);
-       }
-}
-
-void SkStaticTextView::getPaint(SkPaint* paint) const
-{
-       if (paint)
-               *paint = fPaint;
-}
-
-void SkStaticTextView::setPaint(const SkPaint& paint)
-{
-       if (fPaint != paint)
-       {
-               fPaint = paint;
-               this->computeSize();
-               this->inval(NULL);
-       }
-}
-
-void SkStaticTextView::onDraw(SkCanvas* canvas)
-{
-       this->INHERITED::onDraw(canvas);
-
-       if (fText.isEmpty())
-               return;
-
-       SkTextBox       box;
-
-       box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode);
-       box.setSpacingAlign(this->getSpacingAlign());
-       box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY);
-       box.draw(canvas, fText.c_str(), fText.size(), fPaint);
-}
-
-void SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-#if 0
-       this->INHERITED::onInflate(dom, node);
-
-       int     index;
-       if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0)
-               this->setMode((Mode)index);
-       else
-               assert_no_attr(dom, node, "mode");
-
-       if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0)
-               this->setSpacingAlign((SkTextBox::SpacingAlign)index);
-       else
-               assert_no_attr(dom, node, "spacing-align");
-
-       SkScalar s[2];
-       if (dom.findScalars(node, "margin", s, 2))
-               this->setMargin(s[0], s[1]);
-       else
-               assert_no_attr(dom, node, "margin");
-
-       const char* text = dom.findAttr(node, "text");
-       if (text)
-               this->setText(text);
-
-       if ((node = dom.getFirstChild(node, "paint")) != NULL &&
-               (node = dom.getFirstChild(node, "screenplay")) != NULL)
-       {
-               inflate_paint(dom, node, &fPaint);
-       }
-#endif
-}
-
diff --git a/src/views/SkWidgetViews.cpp b/src/views/SkWidgetViews.cpp
deleted file mode 100644 (file)
index 2803d93..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SkWidgetViews.h"
-#include "SkAnimator.h"
-#include "SkCanvas.h"
-#include "SkPaint.h"
-#include "SkStream.h"
-#include "SkSystemEventTypes.h"
-
-#ifdef SK_DEBUG
-       static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
-       {
-               const char* value = dom.findAttr(node, attr);
-               if (value)
-                       SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
-       }
-#else
-       #define assert_no_attr(dom, node, attr)
-#endif
-/*
-I have moved this to SkWidgetViews.h
-enum SkinEnum {
-       kButton_SkinEnum,
-       kProgress_SkinEnum,
-       kScroll_SkinEnum,
-       kStaticText_SkinEnum,
-       
-       kSkinEnumCount
-};
-*/
-
-const char* get_skin_enum_path(SkinEnum se)
-{
-       SkASSERT((unsigned)se < kSkinEnumCount);
-
-       static const char* gSkinPaths[] = {
-            "common/default/default/skins/border3.xml",
-            "common/default/default/skins/button.xml",
-            "common/default/default/skins/progressBar.xml",
-            "common/default/default/skins/scrollBar.xml",
-            "common/default/default/skins/statictextpaint.xml"
-       };
-
-       return gSkinPaths[se];
-}
-
-void init_skin_anim(const char path[], SkAnimator* anim)
-{
-       SkASSERT(path && anim);
-
-       SkFILEStream    stream(path);
-
-       if (!stream.isValid())
-       {
-               SkDEBUGF(("init_skin_anim: loading skin failed <%s>\n", path));
-               sk_throw();
-       }
-
-       if (!anim->decodeStream(&stream))
-       {
-               SkDEBUGF(("init_skin_anim: decoding skin failed <%s>\n", path));
-               sk_throw();
-       }
-}
-
-void init_skin_anim(SkinEnum se, SkAnimator* anim)
-{
-       init_skin_anim(get_skin_enum_path(se), anim);
-}
-
-void init_skin_paint(SkinEnum se, SkPaint* paint)
-{
-       SkASSERT(paint);
-
-       SkAnimator      anim;
-       SkCanvas        canvas;
-       
-       init_skin_anim(se, &anim);
-       anim.draw(&canvas, paint, 0);
-}
-
-void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint)
-{
-       SkASSERT(paint);
-
-       SkAnimator      anim;
-       SkCanvas        canvas;
-       
-       if (!anim.decodeDOM(dom, node))
-       {
-               SkDEBUGF(("inflate_paint: decoding dom failed\n"));
-               SkDEBUGCODE(dom.dump(node);)
-               sk_throw();
-       }       
-       anim.draw(&canvas, paint, 0);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-
-SkWidgetView::SkWidgetView() : SkView(SkView::kFocusable_Mask | SkView::kEnabled_Mask)
-{
-}
-
-const char* SkWidgetView::getLabel() const
-{
-       return fLabel.c_str();
-}
-       
-void SkWidgetView::getLabel(SkString* label) const
-{
-       if (label)
-               *label = fLabel;
-}
-
-void SkWidgetView::setLabel(const char label[])
-{
-       this->setLabel(label, label ? strlen(label) : 0);
-}
-
-void SkWidgetView::setLabel(const char label[], size_t len)
-{
-       if ((label == NULL && fLabel.size() != 0) || !fLabel.equals(label, len))
-       {
-               SkString        tmp(label, len);
-
-               this->onLabelChange(fLabel.c_str(), tmp.c_str());
-               fLabel.swap(tmp);
-       }
-}
-
-void SkWidgetView::setLabel(const SkString& label)
-{
-       if (fLabel != label)
-       {
-               this->onLabelChange(fLabel.c_str(), label.c_str());
-               fLabel = label;
-       }
-}
-
-bool SkWidgetView::postWidgetEvent()
-{
-       if (!fEvent.isType(""))
-       {
-               SkEvent evt(fEvent);    // make a copy since onPrepareWidgetEvent may edit the event
-
-               if (this->onPrepareWidgetEvent(&evt))
-               {
-                       SkDEBUGCODE(evt.dump("SkWidgetView::postWidgetEvent");)
-
-                       this->postToListeners(evt);     // wonder if this should return true if there are > 0 listeners...
-                       return true;
-               }
-       }
-       return false;
-}
-
-/*virtual*/ void SkWidgetView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-       this->INHERITED::onInflate(dom, node);
-
-       const char* label = dom.findAttr(node, "label");
-       if (label)
-               this->setLabel(label);
-               
-       if ((node = dom.getFirstChild(node, "event")) != NULL)
-               fEvent.inflate(dom, node);
-}
-
-/*virtual*/ void SkWidgetView::onLabelChange(const char oldLabel[], const char newLabel[])
-{
-       this->inval(NULL);
-}
-
-static const char gWidgetEventSinkIDSlotName[] = "sk-widget-sinkid-slot";
-
-/*virtual*/ bool SkWidgetView::onPrepareWidgetEvent(SkEvent* evt)
-{
-       evt->setS32(gWidgetEventSinkIDSlotName, this->getSinkID());
-       return true;
-}
-
-SkEventSinkID SkWidgetView::GetWidgetEventSinkID(const SkEvent& evt)
-{
-       int32_t sinkID;
-       
-       return evt.findS32(gWidgetEventSinkIDSlotName, &sinkID) ? (SkEventSinkID)sinkID : 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*virtual*/ bool SkButtonView::onEvent(const SkEvent& evt)
-{
-       if (evt.isType(SK_EventType_Key) && evt.getFast32() == kOK_SkKey)
-       {
-               this->postWidgetEvent();
-               return true;
-       }
-       return this->INHERITED::onEvent(evt);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-SkCheckButtonView::SkCheckButtonView() : fCheckState(kOff_CheckState)
-{
-}
-
-void SkCheckButtonView::setCheckState(CheckState state)
-{
-       SkASSERT((unsigned)state <= kUnknown_CheckState);
-       
-       if (fCheckState != state)
-       {
-               this->onCheckStateChange(this->getCheckState(), state);
-               fCheckState = SkToU8(state);
-       }
-}
-       
-/*virtual*/ void SkCheckButtonView::onCheckStateChange(CheckState oldState, CheckState newState)
-{
-       this->inval(NULL);
-}
-
-/*virtual*/ void SkCheckButtonView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
-{
-       this->INHERITED::onInflate(dom, node);
-       
-       int index = dom.findList(node, "check-state", "off,on,unknown");
-       if (index >= 0)
-               this->setCheckState((CheckState)index);
-}
-
-static const char gCheckStateSlotName[] = "sk-checkbutton-check-slot";
-
-/*virtual*/ bool SkCheckButtonView::onPrepareWidgetEvent(SkEvent* evt)
-{
-       // could check if we're "disabled", and return false...
-
-       evt->setS32(gCheckStateSlotName, this->getCheckState());
-       return true;
-}
-
-bool SkCheckButtonView::GetWidgetEventCheckState(const SkEvent& evt, CheckState* state)
-{
-       int32_t state32;
-       
-       if (evt.findS32(gCheckStateSlotName, &state32))
-       {
-               if (state)
-                       *state = (CheckState)state32;
-               return true;
-       }
-       return false;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "SkTime.h"
-#include <stdio.h>
-
-class SkAnimButtonView : public SkButtonView {
-public:
-       SkAnimButtonView()
-       {
-               fAnim.setHostEventSink(this);
-               init_skin_anim(kButton_SkinEnum, &fAnim);
-       }
-
-protected:
-       virtual void onLabelChange(const char oldLabel[], const char newLabel[])
-       {
-               this->INHERITED::onLabelChange(oldLabel, newLabel);
-
-               SkEvent evt("user");
-               evt.setString("id", "setLabel");
-               evt.setString("LABEL", newLabel);
-               fAnim.doUserEvent(evt);
-       }
-       
-       virtual void onFocusChange(bool gainFocus)
-       {
-               this->INHERITED::onFocusChange(gainFocus);
-
-               SkEvent evt("user");
-               evt.setString("id", "setFocus");
-               evt.setS32("FOCUS", gainFocus);
-               fAnim.doUserEvent(evt);
-       }
-
-       virtual void onSizeChange()
-       {
-               this->INHERITED::onSizeChange();
-
-               SkEvent evt("user");
-               evt.setString("id", "setDim");
-               evt.setScalar("dimX", this->width());
-               evt.setScalar("dimY", this->height());
-               fAnim.doUserEvent(evt);
-       }
-
-       virtual void onDraw(SkCanvas* canvas)
-       {
-               SkPaint                                         paint;          
-               SkAnimator::DifferenceType      diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
-               
-               if (diff == SkAnimator::kDifferent)
-                       this->inval(NULL);
-               else if (diff == SkAnimator::kPartiallyDifferent)
-               {
-                       SkRect  bounds;
-                       fAnim.getInvalBounds(&bounds);
-                       this->inval(&bounds);
-               }
-       }
-       
-       virtual bool onEvent(const SkEvent& evt)
-       {
-               if (evt.isType(SK_EventType_Inval))
-               {
-                       this->inval(NULL);
-                       return true;
-               }
-               if (evt.isType("recommendDim"))
-               {
-                       SkScalar        height;
-                       
-                       if (evt.findScalar("y", &height))
-                               this->setHeight(height);
-                       return true;
-               }
-               return this->INHERITED::onEvent(evt);
-       }
-       
-       virtual bool onPrepareWidgetEvent(SkEvent* evt)
-       {
-               if (this->INHERITED::onPrepareWidgetEvent(evt))
-               {
-                       SkEvent e("user");
-                       e.setString("id", "handlePress");
-                       (void)fAnim.doUserEvent(e);
-                       return true;
-               }
-               return false;
-       }
-
-private:
-       SkAnimator      fAnim;
-       
-       typedef SkButtonView INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////////
-
-SkView* SkWidgetFactory(const char name[])
-{
-       if (name == NULL)
-               return NULL;
-       
-       // must be in the same order as the SkSkinWidgetEnum is declared
-       static const char* gNames[] = {
-               "sk-border",
-               "sk-button",
-               "sk-image",
-               "sk-list",
-               "sk-progress",
-               "sk-scroll",
-               "sk-text"
-               
-       };
-
-       for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); i++)
-               if (!strcmp(gNames[i], name))
-                       return SkWidgetFactory((SkWidgetEnum)i);
-
-       return NULL;
-}
-
-#include "SkImageView.h"
-#include "SkProgressBarView.h"
-#include "SkScrollBarView.h"
-#include "SkBorderView.h"
-
-SkView* SkWidgetFactory(SkWidgetEnum sw)
-{
-       switch (sw) {
-       case kBorder_WidgetEnum:
-               return new SkBorderView;
-       case kButton_WidgetEnum:
-               return new SkAnimButtonView;
-       case kImage_WidgetEnum:
-               return new SkImageView;
-       case kList_WidgetEnum:
-               return new SkListView;
-       case kProgress_WidgetEnum:
-               return new SkProgressBarView;
-       case kScroll_WidgetEnum:
-               return new SkScrollBarView;
-       case kText_WidgetEnum:
-               return new SkStaticTextView;
-       default:
-               SkDEBUGFAIL("unknown enum passed to SkWidgetFactory");
-               break;
-       }
-       return NULL;
-}
diff --git a/src/views/animated/SkBorderView.cpp b/src/views/animated/SkBorderView.cpp
new file mode 100644 (file)
index 0000000..cc1c08b
--- /dev/null
@@ -0,0 +1,96 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkBorderView.h"
+#include "SkAnimator.h"
+#include "SkWidgetViews.h"
+#include "SkSystemEventTypes.h"
+#include "SkTime.h"
+#include "SkStackViewLayout.h"
+
+SkBorderView::SkBorderView() : fLeft(SkIntToScalar(0)),
+                               fRight(SkIntToScalar(0)),
+                               fTop(SkIntToScalar(0)),
+                               fBottom(SkIntToScalar(0))
+{
+       fAnim.setHostEventSink(this);
+       init_skin_anim(kBorder_SkinEnum, &fAnim);
+}
+
+SkBorderView::~SkBorderView()
+{
+       
+}
+
+void SkBorderView::setSkin(const char skin[])
+{
+       init_skin_anim(skin, &fAnim);
+}
+
+/* virtual */ void SkBorderView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
+{
+       this->INHERITED::onInflate(dom, node);
+}
+
+/*virtual*/ void SkBorderView::onSizeChange()
+{
+       this->INHERITED::onSizeChange();
+       SkEvent evt("user");
+       evt.setString("id", "setDim");
+       evt.setScalar("dimX", this->width());
+       evt.setScalar("dimY", this->height());
+       fAnim.doUserEvent(evt);
+}
+
+/*virtual*/ void SkBorderView::onDraw(SkCanvas* canvas)
+{
+       SkPaint                                         paint;          
+       SkAnimator::DifferenceType      diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
+       
+       if (diff == SkAnimator::kDifferent)
+               this->inval(NULL);
+       else if (diff == SkAnimator::kPartiallyDifferent)
+       {
+               SkRect  bounds;
+               fAnim.getInvalBounds(&bounds);
+               this->inval(&bounds);
+       }
+}
+
+/*virtual*/ bool SkBorderView::onEvent(const SkEvent& evt)
+{
+       if (evt.isType(SK_EventType_Inval))
+       {
+               this->inval(NULL);
+               return true;
+       }
+       if (evt.isType("recommendDim"))
+       {
+               evt.findScalar("leftMargin", &fLeft);
+               evt.findScalar("rightMargin", &fRight);
+               evt.findScalar("topMargin", &fTop);
+               evt.findScalar("bottomMargin", &fBottom);
+       
+               //setup_views.cpp uses SkView::Layout instead of SkStackViewLayout
+               //but that gives me an error
+               SkStackViewLayout* layout;
+               fMargin.set(fLeft, fTop, fRight, fBottom);
+               if (this->getLayout())
+               {
+                       layout = (SkStackViewLayout*)this->getLayout();
+                       layout->setMargin(fMargin);
+               }
+               else
+               {
+                       layout = new SkStackViewLayout;
+                       layout->setMargin(fMargin);
+                       this->setLayout(layout)->unref();
+               }
+               this->invokeLayout();
+       }
+       return this->INHERITED::onEvent(evt);
+}
diff --git a/src/views/animated/SkImageView.cpp b/src/views/animated/SkImageView.cpp
new file mode 100644 (file)
index 0000000..8924dd3
--- /dev/null
@@ -0,0 +1,303 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkImageView.h"
+#include "SkAnimator.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkImageDecoder.h"
+#include "SkMatrix.h"
+#include "SkSystemEventTypes.h"
+#include "SkTime.h"
+
+SkImageView::SkImageView()
+{
+       fMatrix         = NULL;
+       fScaleType      = kMatrix_ScaleType;
+
+       fData.fAnim     = NULL;         // handles initializing the other union values
+       fDataIsAnim     = true;
+       
+       fUriIsValid     = false;        // an empty string is not valid
+}
+
+SkImageView::~SkImageView()
+{
+       if (fMatrix)
+               sk_free(fMatrix);
+               
+       this->freeData();
+}
+
+void SkImageView::getUri(SkString* uri) const
+{
+       if (uri)
+               *uri = fUri;
+}
+
+void SkImageView::setUri(const char uri[])
+{
+       if (!fUri.equals(uri))
+       {
+               fUri.set(uri);
+               this->onUriChange();
+       }
+}
+
+void SkImageView::setUri(const SkString& uri)
+{
+       if (fUri != uri)
+       {
+               fUri = uri;
+               this->onUriChange();
+       }
+}
+
+void SkImageView::setScaleType(ScaleType st)
+{
+       SkASSERT((unsigned)st <= kFitEnd_ScaleType);
+
+       if ((ScaleType)fScaleType != st)
+       {
+               fScaleType = SkToU8(st);
+               if (fUriIsValid)
+                       this->inval(NULL);
+       }
+}
+
+bool SkImageView::getImageMatrix(SkMatrix* matrix) const
+{
+       if (fMatrix)
+       {
+               SkASSERT(!fMatrix->isIdentity());
+               if (matrix)
+                       *matrix = *fMatrix;
+               return true;
+       }
+       else
+       {
+               if (matrix)
+                       matrix->reset();
+               return false;
+       }
+}
+
+void SkImageView::setImageMatrix(const SkMatrix* matrix)
+{
+       bool changed = false;
+
+       if (matrix && !matrix->isIdentity())
+       {
+               if (fMatrix == NULL)
+                       fMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
+               *fMatrix = *matrix;
+               changed = true;
+       }
+       else    // set us to identity
+       {
+               if (fMatrix)
+               {
+                       SkASSERT(!fMatrix->isIdentity());
+                       sk_free(fMatrix);
+                       fMatrix = NULL;
+                       changed = true;
+               }
+       }
+
+       // only redraw if we changed our matrix and we're not in scaleToFit mode
+       if (changed && this->getScaleType() == kMatrix_ScaleType && fUriIsValid)
+               this->inval(NULL);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SkImageView::onEvent(const SkEvent& evt)
+{
+       if (evt.isType(SK_EventType_Inval))
+       {
+               if (fUriIsValid)
+                       this->inval(NULL);
+               return true;
+       }
+       return this->INHERITED::onEvent(evt);
+}
+
+static inline SkMatrix::ScaleToFit scaleTypeToScaleToFit(SkImageView::ScaleType st)
+{
+       SkASSERT(st != SkImageView::kMatrix_ScaleType);
+       SkASSERT((unsigned)st <= SkImageView::kFitEnd_ScaleType);
+
+       SkASSERT(SkImageView::kFitXY_ScaleType - 1 == SkMatrix::kFill_ScaleToFit);
+       SkASSERT(SkImageView::kFitStart_ScaleType - 1 == SkMatrix::kStart_ScaleToFit);
+       SkASSERT(SkImageView::kFitCenter_ScaleType - 1 == SkMatrix::kCenter_ScaleToFit);
+       SkASSERT(SkImageView::kFitEnd_ScaleType - 1 == SkMatrix::kEnd_ScaleToFit);
+       
+       return (SkMatrix::ScaleToFit)(st - 1);
+}
+
+void SkImageView::onDraw(SkCanvas* canvas)
+{
+       SkRect  src;
+       if (!this->getDataBounds(&src))
+       {
+               SkDEBUGCODE(canvas->drawColor(SK_ColorRED);)
+               return;         // nothing to draw
+       }
+               
+       SkAutoCanvasRestore     restore(canvas, true);
+       SkMatrix                        matrix;
+       
+       if (this->getScaleType() == kMatrix_ScaleType)
+               (void)this->getImageMatrix(&matrix);
+       else
+       {
+               SkRect  dst;            
+               dst.set(0, 0, this->width(), this->height());
+               matrix.setRectToRect(src, dst, scaleTypeToScaleToFit(this->getScaleType()));
+       }
+       canvas->concat(matrix);
+
+       SkPaint paint;
+       
+       paint.setAntiAlias(true);
+
+       if (fDataIsAnim)
+       {
+               SkMSec  now = SkTime::GetMSecs();
+               
+               SkAnimator::DifferenceType diff = fData.fAnim->draw(canvas, &paint, now);
+               
+SkDEBUGF(("SkImageView : now = %X[%12.3f], diff = %d\n", now, now/1000., diff));
+
+               if (diff == SkAnimator::kDifferent)
+                       this->inval(NULL);
+               else if (diff == SkAnimator::kPartiallyDifferent)
+               {
+                       SkRect  bounds;
+                       fData.fAnim->getInvalBounds(&bounds);
+                       matrix.mapRect(&bounds);        // get the bounds into view coordinates
+                       this->inval(&bounds);
+               }
+       }
+       else
+               canvas->drawBitmap(*fData.fBitmap, 0, 0, &paint);
+}
+
+void SkImageView::onInflate(const SkDOM& dom, const SkDOMNode* node)
+{
+       this->INHERITED::onInflate(dom, node);
+       
+       const char* src = dom.findAttr(node, "src");
+       if (src)
+               this->setUri(src);
+
+       int     index = dom.findList(node, "scaleType", "matrix,fitXY,fitStart,fitCenter,fitEnd");
+       if (index >= 0)
+               this->setScaleType((ScaleType)index);
+               
+       // need inflate syntax/reader for matrix
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+void SkImageView::onUriChange()
+{
+       if (this->freeData())
+               this->inval(NULL);
+       fUriIsValid = true;             // give ensureUriIsLoaded() a shot at the new uri
+}
+
+bool SkImageView::freeData()
+{
+       if (fData.fAnim)        // test is valid for all union values
+       {
+               if (fDataIsAnim)
+                       delete fData.fAnim;
+               else
+                       delete fData.fBitmap;
+
+               fData.fAnim = NULL;     // valid for all union values
+               return true;
+       }
+       return false;
+}
+
+bool SkImageView::getDataBounds(SkRect* bounds)
+{
+       SkASSERT(bounds);
+
+       if (this->ensureUriIsLoaded())
+       {
+               SkScalar width, height;
+
+               if (fDataIsAnim)
+               {                       
+                       if (SkScalarIsNaN(width = fData.fAnim->getScalar("dimensions", "x")) ||
+                               SkScalarIsNaN(height = fData.fAnim->getScalar("dimensions", "y")))
+                       {
+                               // cons up fake bounds
+                               width = this->width();
+                               height = this->height();
+                       }
+               }
+               else
+               {
+                       width = SkIntToScalar(fData.fBitmap->width());
+                       height = SkIntToScalar(fData.fBitmap->height());
+               }
+               bounds->set(0, 0, width, height);
+               return true;
+       }
+       return false;
+}
+
+bool SkImageView::ensureUriIsLoaded()
+{
+       if (fData.fAnim)        // test is valid for all union values
+       {
+               SkASSERT(fUriIsValid);
+               return true;
+       }
+       if (!fUriIsValid)
+               return false;
+
+       // try to load the url
+       if (fUri.endsWith(".xml"))      // assume it is screenplay
+       {
+               SkAnimator* anim = new SkAnimator;
+               
+               if (!anim->decodeURI(fUri.c_str()))
+               {
+                       delete anim;
+                       fUriIsValid = false;
+                       return false;
+               }
+               anim->setHostEventSink(this);
+
+               fData.fAnim = anim;
+               fDataIsAnim = true;
+       }
+       else    // assume it is an image format
+       {
+    #if 0
+               SkBitmap* bitmap = new SkBitmap;
+
+               if (!SkImageDecoder::DecodeURL(fUri.c_str(), bitmap))
+               {
+                       delete bitmap;
+                       fUriIsValid = false;
+                       return false;
+               }
+               fData.fBitmap = bitmap;
+               fDataIsAnim = false;
+    #else
+        return false;
+    #endif
+       }
+       return true;
+}
+
diff --git a/src/views/animated/SkListWidget.cpp b/src/views/animated/SkListWidget.cpp
new file mode 100644 (file)
index 0000000..4d95e0f
--- /dev/null
@@ -0,0 +1,630 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkWidgetViews.h"
+
+#include "SkAnimator.h"
+#include "SkScrollBarView.h"
+
+extern void init_skin_anim(const char name[], SkAnimator*);
+
+struct SkListView::BindingRec {
+       SkString        fSlotName;
+       int                     fFieldIndex;
+};
+
+SkListView::SkListView()
+{
+       fSource = NULL;                         // our list-source
+       fScrollBar = NULL;
+       fAnims = NULL;                          // array of animators[fVisibleRowCount]
+       fBindings = NULL;                       // our fields->slot array
+       fBindingCount = 0;                      // number of entries in fSlots array
+       fScrollIndex = 0;                       // number of cells to skip before first visible cell
+       fCurrIndex = -1;                        // index of "selected" cell
+       fVisibleRowCount = 0;           // number of cells that can fit in our bounds
+       fAnimContentDirty = true;       // true if fAnims[] have their correct content
+       fAnimFocusDirty = true;
+
+       fHeights[kNormal_Height] = SkIntToScalar(16);
+       fHeights[kSelected_Height] = SkIntToScalar(16);
+       
+       this->setFlags(this->getFlags() | kFocusable_Mask);
+}
+
+SkListView::~SkListView()
+{
+       SkSafeUnref(fScrollBar);
+       SkSafeUnref(fSource);
+       delete[] fAnims;
+       delete[] fBindings;
+}
+
+void SkListView::setHasScrollBar(bool hasSB)
+{
+       if (hasSB != this->hasScrollBar())
+       {
+               if (hasSB)
+               {
+                       SkASSERT(fScrollBar == NULL);
+                       fScrollBar = (SkScrollBarView*)SkWidgetFactory(kScroll_WidgetEnum);
+                       fScrollBar->setVisibleP(true);
+                       this->attachChildToFront(fScrollBar);
+                       fScrollBar->setHeight(this->height());  // assume it auto-sets its width
+               //      fScrollBar->setLoc(this->getContentWidth(), 0);
+                       fScrollBar->setLoc(this->width()-SkIntToScalar(10), 0);
+               }
+               else
+               {
+                       SkASSERT(fScrollBar);
+                       fScrollBar->detachFromParent();
+                       fScrollBar->unref();
+                       fScrollBar = NULL;
+               }
+               this->dirtyCache(kAnimContent_DirtyFlag);
+       }
+}
+
+void SkListView::setSelection(int index)
+{
+       if (fCurrIndex != index)
+       {
+               fAnimFocusDirty = true;
+               this->inval(NULL);
+
+               this->invalSelection();
+               fCurrIndex = index;
+               this->invalSelection();
+               this->ensureSelectionIsVisible();
+       }
+}
+
+bool SkListView::moveSelectionUp()
+{
+       if (fSource)
+       {
+               int     index = fCurrIndex;
+               if (index < 0)  // no selection
+                       index = fSource->countRecords() - 1;
+               else
+                       index = SkMax32(index - 1, 0);
+               
+               if (fCurrIndex != index)
+               {
+                       this->setSelection(index);
+                       return true;
+               }
+       }
+       return false;
+}
+
+bool SkListView::moveSelectionDown()
+{
+       if (fSource)
+       {
+               int     index = fCurrIndex;
+               if (index < 0)  // no selection
+                       index = 0;
+               else
+                       index = SkMin32(index + 1, fSource->countRecords() - 1);
+               
+               if (fCurrIndex != index)
+               {
+                       this->setSelection(index);
+                       return true;
+               }
+       }
+       return false;
+}
+
+void SkListView::invalSelection()
+{
+       SkRect  r;
+       if (this->getRowRect(fCurrIndex, &r))
+               this->inval(&r);
+}
+
+void SkListView::ensureSelectionIsVisible()
+{
+       if (fSource && (unsigned)fCurrIndex < (unsigned)fSource->countRecords())
+       {
+               int index = this->logicalToVisualIndex(fCurrIndex);
+
+               if ((unsigned)index >= (unsigned)fVisibleRowCount)      // need to scroll
+               {
+                       int newIndex;
+                       
+                       if (index < 0)  // too high
+                               newIndex = fCurrIndex;
+                       else
+                               newIndex = fCurrIndex - fVisibleRowCount + 1;
+                       SkASSERT((unsigned)newIndex < (unsigned)fSource->countRecords());
+                       this->inval(NULL);
+                       
+                       if (fScrollIndex != newIndex)
+                       {
+                               fScrollIndex = newIndex;
+                               if (fScrollBar)
+                                       fScrollBar->setStart(newIndex);
+                               this->dirtyCache(kAnimContent_DirtyFlag);
+                       }
+               }
+       }
+}
+
+SkScalar SkListView::getContentWidth() const
+{
+       SkScalar width = this->width();
+       
+       if (fScrollBar)
+       {
+               width -= fScrollBar->width();
+               if (width < 0)
+                       width = 0;
+       }
+       return width;
+}
+
+bool SkListView::getRowRect(int index, SkRect* r) const
+{
+       SkASSERT(r);
+
+       index = this->logicalToVisualIndex(index);
+       if (index >= 0)
+       {
+               int     selection = this->logicalToVisualIndex(fCurrIndex);
+               
+               SkScalar height = fHeights[index == selection ? kSelected_Height : kNormal_Height];
+               SkScalar top = index * fHeights[kNormal_Height];
+
+               if (index > selection && selection >= 0)
+                       top += fHeights[kSelected_Height] - fHeights[kNormal_Height];   
+
+               if (top < this->height())
+               {
+                       if (r)
+                               r->set(0, top, this->getContentWidth(), top + height);
+                       return true;
+               }
+       }
+       return false;
+}
+
+SkListSource* SkListView::setListSource(SkListSource* src)
+{
+       if (fSource != src)
+       {
+               SkRefCnt_SafeAssign(fSource, src);
+               this->ensureSelectionIsVisible();
+               this->inval(NULL);
+               
+               if (fScrollBar)
+                       fScrollBar->setTotal(fSource->countRecords());
+       }
+       return src;
+}
+
+void SkListView::dirtyCache(unsigned dirtyFlags)
+{
+       if (dirtyFlags & kAnimCount_DirtyFlag)
+       {
+               delete fAnims;
+               fAnims = NULL;
+               fAnimContentDirty = true;
+               fAnimFocusDirty = true;
+       }
+       if (dirtyFlags & kAnimContent_DirtyFlag)
+       {
+               if (!fAnimContentDirty)
+               {
+                       this->inval(NULL);
+                       fAnimContentDirty = true;
+               }
+               fAnimFocusDirty = true;
+       }
+}
+
+bool SkListView::ensureCache()
+{
+       if (fSkinName.size() == 0)
+               return false;
+
+       if (fAnims == NULL)
+       {
+               int n = SkMax32(1, fVisibleRowCount);
+
+               SkASSERT(fAnimContentDirty);
+               fAnims = new SkAnimator[n];
+               for (int i = 0; i < n; i++)
+               {
+                       fAnims[i].setHostEventSink(this);
+                       init_skin_anim(fSkinName.c_str(), &fAnims[i]);
+               }
+               
+               fHeights[kNormal_Height] = fAnims[0].getScalar("idleHeight", "value");
+               fHeights[kSelected_Height] = fAnims[0].getScalar("focusedHeight", "value");
+
+               fAnimFocusDirty = true;
+       }
+
+       if (fAnimContentDirty && fSource)
+       {
+               fAnimContentDirty = false;
+
+               SkString        str;
+               SkEvent         evt("user");
+               evt.setString("id", "setFields");
+               evt.setS32("rowCount", fVisibleRowCount);
+               
+               SkEvent dimEvt("user");
+               dimEvt.setString("id", "setDim");
+               dimEvt.setScalar("dimX", this->getContentWidth());
+               dimEvt.setScalar("dimY", this->height());
+
+               for (int i = fScrollIndex; i < fScrollIndex + fVisibleRowCount; i++)
+               {
+                       evt.setS32("relativeIndex", i - fScrollIndex);
+                       for (int j = 0; j < fBindingCount; j++)
+                       {
+                               fSource->getRecord(i, fBindings[j].fFieldIndex, &str);
+//SkDEBUGF(("getRecord(%d,%d,%s) slot(%s)\n", i, fBindings[j].fFieldIndex, str.c_str(), fBindings[j].fSlotName.c_str()));
+                               evt.setString(fBindings[j].fSlotName.c_str(), str.c_str());
+                       }
+                       (void)fAnims[i % fVisibleRowCount].doUserEvent(evt);
+                       (void)fAnims[i % fVisibleRowCount].doUserEvent(dimEvt);
+               }
+               fAnimFocusDirty = true;
+       }
+
+       if (fAnimFocusDirty)
+       {
+//SkDEBUGF(("service fAnimFocusDirty\n"));
+               fAnimFocusDirty = false;
+
+               SkEvent         focusEvt("user");
+               focusEvt.setString("id", "setFocus");
+
+               for (int i = fScrollIndex; i < fScrollIndex + fVisibleRowCount; i++)
+               {
+                       focusEvt.setS32("FOCUS", i == fCurrIndex);
+                       (void)fAnims[i % fVisibleRowCount].doUserEvent(focusEvt);
+               }
+       }
+
+       return true;
+}
+
+void SkListView::ensureVisibleRowCount()
+{
+       SkScalar        height = this->height();
+       int                     n = 0;
+       
+       if (height > 0)
+       {
+               n = 1;
+               height -= fHeights[kSelected_Height];
+               if (height > 0)
+               {
+                       SkScalar count = SkScalarDiv(height, fHeights[kNormal_Height]);
+                       n += SkScalarFloor(count);
+                       if (count - SkIntToScalar(n) > SK_Scalar1*3/4)
+                               n += 1;
+                               
+               //      SkDebugf("count %g, n %d\n", count/65536., n);
+               }
+       }
+
+       if (fVisibleRowCount != n)
+       {
+               if (fScrollBar)
+                       fScrollBar->setShown(n);
+
+               fVisibleRowCount = n;
+               this->ensureSelectionIsVisible();
+               this->dirtyCache(kAnimCount_DirtyFlag | kAnimContent_DirtyFlag);
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkSystemEventTypes.h"
+#include "SkTime.h"
+
+void SkListView::onSizeChange()
+{
+       this->INHERITED::onSizeChange();
+
+       if (fScrollBar)
+               fScrollBar->setLoc(this->width()-SkIntToScalar(10), 0);
+
+       this->ensureVisibleRowCount();
+}
+
+void SkListView::onDraw(SkCanvas* canvas)
+{
+       this->INHERITED::onDraw(canvas);
+
+       this->ensureVisibleRowCount();
+
+       int     visibleCount = SkMin32(fVisibleRowCount, fSource->countRecords() - fScrollIndex);
+       if (visibleCount == 0 || !this->ensureCache())
+               return;
+
+//SkDebugf("visibleCount %d scrollIndex %d currIndex %d\n", visibleCount, fScrollIndex, fCurrIndex);
+
+       SkAutoCanvasRestore     ar(canvas, true);
+       SkMSec                          now = SkTime::GetMSecs();
+       SkRect                          bounds;
+
+       bounds.fLeft    = 0;
+       bounds.fRight   = this->getContentWidth();
+       bounds.fBottom  = 0;
+       // assign bounds.fTop inside the loop
+
+       // hack to reveal our bounds for debugging
+       if (this->hasFocus())
+               canvas->drawARGB(0x11, 0, 0, 0xFF);
+       else
+               canvas->drawARGB(0x11, 0x88, 0x88, 0x88);
+
+       for (int i = fScrollIndex; i < fScrollIndex + visibleCount; i++)
+       {
+               SkPaint  paint;
+               SkScalar height = fHeights[i == fCurrIndex ? kSelected_Height : kNormal_Height];
+
+               bounds.fTop = bounds.fBottom;
+               bounds.fBottom += height;
+               
+               canvas->save();
+               if (fAnims[i % fVisibleRowCount].draw(canvas, &paint, now) != SkAnimator::kNotDifferent)
+                       this->inval(&bounds);
+               canvas->restore();
+
+               canvas->translate(0, height);
+       }
+}
+
+bool SkListView::onEvent(const SkEvent& evt)
+{
+       if (evt.isType(SK_EventType_Key))
+       {
+               switch (evt.getFast32()) {
+               case kUp_SkKey:
+                       return this->moveSelectionUp();
+               case kDown_SkKey:
+                       return this->moveSelectionDown();
+               case kRight_SkKey:
+               case kOK_SkKey:
+                       this->postWidgetEvent();
+                       return true;
+               default:
+                       break;
+               }
+       }
+       return this->INHERITED::onEvent(evt);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+static const char gListViewEventSlot[] = "sk-listview-slot-name";
+
+/*virtual*/ bool SkListView::onPrepareWidgetEvent(SkEvent* evt)
+{
+       if (fSource && fCurrIndex >= 0 && this->INHERITED::onPrepareWidgetEvent(evt) &&
+               fSource->prepareWidgetEvent(evt, fCurrIndex))
+       {
+               evt->setS32(gListViewEventSlot, fCurrIndex);
+               return true;
+       }
+       return false;
+}
+
+int SkListView::GetWidgetEventListIndex(const SkEvent& evt)
+{
+       int32_t index;
+
+       return evt.findS32(gListViewEventSlot, &index) ? index : -1;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+void SkListView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
+{
+       this->INHERITED::onInflate(dom, node);
+       
+       {
+               bool hasScrollBar;
+               if (dom.findBool(node, "scrollBar", &hasScrollBar))
+                       this->setHasScrollBar(hasScrollBar);
+       }
+
+       const SkDOM::Node*      child;
+
+       if ((child = dom.getFirstChild(node, "bindings")) != NULL)
+       {
+               delete[] fBindings;
+               fBindings = NULL;
+               fBindingCount = 0;
+
+               SkListSource* listSrc = SkListSource::Factory(dom.findAttr(child, "data-fields"));
+               SkASSERT(listSrc);
+               fSkinName.set(dom.findAttr(child, "skin-slots"));
+               SkASSERT(fSkinName.size());
+
+               this->setListSource(listSrc)->unref();
+                       
+               int count = dom.countChildren(child, "bind");
+               if (count > 0)
+               {
+                       fBindings = new BindingRec[count];
+                       count = 0;      // reuse this to count up to the number of valid bindings
+
+                       child = dom.getFirstChild(child, "bind");
+                       SkASSERT(child);
+                       do {
+                               const char* fieldName = dom.findAttr(child, "field");
+                               const char* slotName = dom.findAttr(child, "slot");
+                               if (fieldName && slotName)
+                               {
+                                       fBindings[count].fFieldIndex = listSrc->findFieldIndex(fieldName);
+                                       if (fBindings[count].fFieldIndex >= 0)
+                                               fBindings[count++].fSlotName.set(slotName);
+                               }
+                       } while ((child = dom.getNextSibling(child, "bind")) != NULL);
+
+                       fBindingCount = SkToU16(count);
+                       if (count == 0)
+                       {
+                               SkDEBUGF(("SkListView::onInflate: no valid <bind> elements in <listsource>\n"));
+                               delete[] fBindings;
+                       }
+               }
+               this->dirtyCache(kAnimCount_DirtyFlag);
+               this->setSelection(0);
+       }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkXMLListSource : public SkListSource {
+public:
+       SkXMLListSource(const char doc[], size_t len);
+       virtual ~SkXMLListSource()
+       {
+               delete[] fFields;
+               delete[] fRecords;
+       }
+
+       virtual int countFields() { return fFieldCount; }
+       virtual void getFieldName(int index, SkString* field)
+       {
+               SkASSERT((unsigned)index < (unsigned)fFieldCount);
+               if (field)
+                       *field = fFields[index];
+       }
+       virtual int findFieldIndex(const char field[])
+       {
+               for (int i = 0; i < fFieldCount; i++)
+                       if (fFields[i].equals(field))
+                               return i;
+               return -1;
+       }
+
+       virtual int     countRecords() { return fRecordCount; }
+       virtual void getRecord(int rowIndex, int fieldIndex, SkString* data)
+       {
+               SkASSERT((unsigned)rowIndex < (unsigned)fRecordCount);
+               SkASSERT((unsigned)fieldIndex < (unsigned)fFieldCount);
+               if (data)
+                       *data = fRecords[rowIndex * fFieldCount + fieldIndex];
+       }
+
+       virtual bool prepareWidgetEvent(SkEvent* evt, int rowIndex)
+       {
+               // hack, for testing right now. Need the xml to tell us what to jam in and where
+               SkString        data;
+               
+               this->getRecord(rowIndex, 0, &data);
+               evt->setString("xml-listsource", data.c_str());
+               return true;
+       }
+       
+private:
+       SkString*       fFields;        // [fFieldCount]
+       SkString*       fRecords;       // [fRecordCount][fFieldCount]
+       int                     fFieldCount, fRecordCount;
+};
+
+#include "SkDOM.h"
+
+SkXMLListSource::SkXMLListSource(const char doc[], size_t len)
+{
+       fFieldCount = fRecordCount = 0;
+       fFields = fRecords = NULL;
+
+       SkDOM   dom;
+
+       const SkDOM::Node* node = dom.build(doc, len);
+       SkASSERT(node);
+       const SkDOM::Node*      child;  
+
+       child = dom.getFirstChild(node, "fields");
+       if (child)
+       {
+               fFieldCount = dom.countChildren(child, "field");
+               fFields = new SkString[fFieldCount];
+
+               int n = 0;
+               child = dom.getFirstChild(child, "field");
+               while (child)
+               {
+                       fFields[n].set(dom.findAttr(child, "name"));
+                       child = dom.getNextSibling(child, "field");
+                       n += 1;
+               }
+               SkASSERT(n == fFieldCount);
+       }
+       
+       child = dom.getFirstChild(node, "records");
+       if (child)
+       {
+               fRecordCount = dom.countChildren(child, "record");
+               fRecords = new SkString[fRecordCount * fFieldCount];
+
+               int n = 0;
+               child = dom.getFirstChild(child, "record");
+               while (child)
+               {
+                       for (int i = 0; i < fFieldCount; i++)
+                               fRecords[n * fFieldCount + i].set(dom.findAttr(child, fFields[i].c_str()));
+                       child = dom.getNextSibling(child, "record");
+                       n += 1;
+               }
+               SkASSERT(n == fRecordCount);
+       }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+SkListSource* SkListSource::Factory(const char name[])
+{
+       static const char gDoc[] =
+               "<db name='contacts.db'>"
+                       "<fields>"
+                               "<field name='name'/>"
+                               "<field name='work-num'/>"
+                               "<field name='home-num'/>"
+                               "<field name='type'/>"
+                       "</fields>"
+                       "<records>"
+                               "<record name='Andy McFadden' work-num='919 357-1234' home-num='919 123-4567' type='0'/>"
+                               "<record name='Brian Swetland' work-num='919 123-1234' home-num='929 123-4567' type='1' />"
+                               "<record name='Chris Desalvo' work-num='919 345-1234' home-num='949 123-4567' type='1' />"
+                               "<record name='Chris White' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
+                               "<record name='Dan Bornstein' work-num='919 357-1234' home-num='919 123-4567' type='0' />"
+                               "<record name='Don Cung' work-num='919 123-1234' home-num='929 123-4567' type='2' />"
+                               "<record name='Eric Fischer' work-num='919 345-1234' home-num='949 123-4567' type='2' />"
+                               "<record name='Ficus Kirkpatric' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
+                               "<record name='Jack Veenstra' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
+                               "<record name='Jeff Yaksick' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
+                               "<record name='Joe Onorato' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
+                               "<record name='Mathias Agopian' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
+                               "<record name='Mike Fleming' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
+                               "<record name='Nick Sears' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
+                               "<record name='Rich Miner' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
+                               "<record name='Tracey Cole' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
+                               "<record name='Wei Huang' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
+                       "</records>"
+               "</db>";
+               
+//SkDebugf("doc size %d\n", sizeof(gDoc)-1);
+       return new SkXMLListSource(gDoc, sizeof(gDoc) - 1);
+}
+
+
+
diff --git a/src/views/animated/SkProgressBarView.cpp b/src/views/animated/SkProgressBarView.cpp
new file mode 100644 (file)
index 0000000..ce26ac4
--- /dev/null
@@ -0,0 +1,109 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkProgressBarView.h"
+#include "SkAnimator.h"
+#include "SkWidgetViews.h"
+#include "SkTime.h"
+#include "SkSystemEventTypes.h"
+
+SkProgressBarView::SkProgressBarView()
+{
+       init_skin_anim(kProgress_SkinEnum, &fAnim);
+       fAnim.setHostEventSink(this);
+       fProgress = 0;
+       fMax = 100;
+       
+}
+
+void SkProgressBarView::changeProgress(int diff)
+{
+       int newProg = fProgress + diff;
+       if (newProg > 0 && newProg < fMax)
+               this->setProgress(newProg);
+       //otherwise i'll just leave it as it is
+       //this implies that if a new max and progress are set, max must be set first
+}
+
+/*virtual*/ void SkProgressBarView::onDraw(SkCanvas* canvas)
+{
+       SkPaint                                         paint;          
+       SkAnimator::DifferenceType      diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
+       
+       if (diff == SkAnimator::kDifferent)
+               this->inval(NULL);
+       else if (diff == SkAnimator::kPartiallyDifferent)
+       {
+               SkRect  bounds;
+               fAnim.getInvalBounds(&bounds);
+               this->inval(&bounds);
+       }
+}
+       
+/*virtual*/ bool SkProgressBarView::onEvent(const SkEvent& evt)
+{
+       if (evt.isType(SK_EventType_Inval))
+       {
+               this->inval(NULL);
+               return true;
+       }
+       if (evt.isType("recommendDim"))
+       {
+               SkScalar        height;
+               
+               if (evt.findScalar("y", &height))
+                       this->setHeight(height);
+               return true;
+       }
+       return this->INHERITED::onEvent(evt);
+}
+
+/*virtual*/ void SkProgressBarView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
+{
+       this->INHERITED::onInflate(dom, node);
+       int32_t temp;
+       if (dom.findS32(node, "max", &temp))
+               this->setMax(temp);
+       if (dom.findS32(node, "progress", &temp))
+               this->setProgress(temp);
+}
+
+/*virtual*/ void SkProgressBarView::onSizeChange()
+{
+       this->INHERITED::onSizeChange();
+       SkEvent evt("user");
+       evt.setString("id", "setDim");
+       evt.setScalar("dimX", this->width());
+       evt.setScalar("dimY", this->height());
+       fAnim.doUserEvent(evt);
+}
+
+void SkProgressBarView::reset()
+{
+       fProgress = 0;
+       SkEvent e("user");
+       e.setString("id", "reset");
+       fAnim.doUserEvent(e);
+}
+
+void SkProgressBarView::setMax(int max)
+{
+       fMax = max;
+       SkEvent e("user");
+       e.setString("id", "setMax");
+       e.setS32("newMax", max);
+       fAnim.doUserEvent(e);
+}
+
+void SkProgressBarView::setProgress(int progress)
+{
+       fProgress = progress;
+       SkEvent e("user");
+       e.setString("id", "setProgress");
+       e.setS32("newProgress", progress);
+       fAnim.doUserEvent(e);
+}
diff --git a/src/views/animated/SkScrollBarView.cpp b/src/views/animated/SkScrollBarView.cpp
new file mode 100644 (file)
index 0000000..98288f5
--- /dev/null
@@ -0,0 +1,146 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkScrollBarView.h"
+#include "SkAnimator.h"
+#include "SkWidgetViews.h"
+#include "SkSystemEventTypes.h"
+#include "SkTime.h"
+
+//see SkProgressBarView.cpp
+//#include "SkWidgetViews.cpp"
+
+SkScrollBarView::SkScrollBarView()
+{
+       fAnim.setHostEventSink(this);
+       init_skin_anim(kScroll_SkinEnum, &fAnim);
+
+       fTotalLength = 0;
+       fStartPoint = 0;
+       fShownLength = 0;
+
+       this->adjust();
+}
+
+void SkScrollBarView::setStart(unsigned start)
+{
+       if ((int)start < 0)
+               start = 0;
+       
+       if (fStartPoint != start)
+       {
+               fStartPoint = start;
+               this->adjust();
+       }
+}
+
+void SkScrollBarView::setShown(unsigned shown)
+{
+       if ((int)shown < 0)
+               shown = 0;
+
+       if (fShownLength != shown)
+       {
+               fShownLength = shown;
+               this->adjust();
+       }
+}
+
+void SkScrollBarView::setTotal(unsigned total)
+{
+       if ((int)total < 0)
+               total = 0;
+
+       if (fTotalLength != total)
+       {
+               fTotalLength = total;
+               this->adjust();
+       }
+}
+
+/* virtual */ void SkScrollBarView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
+{
+       this->INHERITED::onInflate(dom, node);
+       
+       int32_t value;
+       if (dom.findS32(node, "total", &value))
+               this->setTotal(value);
+       if (dom.findS32(node, "shown", &value))
+               this->setShown(value);
+}
+
+/*virtual*/ void SkScrollBarView::onSizeChange()
+{
+       this->INHERITED::onSizeChange();
+       SkEvent evt("user");
+       evt.setString("id", "setDim");
+       evt.setScalar("dimX", this->width());
+       evt.setScalar("dimY", this->height());
+       fAnim.doUserEvent(evt);
+}
+
+/*virtual*/ void SkScrollBarView::onDraw(SkCanvas* canvas)
+{
+       SkPaint                                         paint;          
+       SkAnimator::DifferenceType      diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
+       
+       if (diff == SkAnimator::kDifferent)
+               this->inval(NULL);
+       else if (diff == SkAnimator::kPartiallyDifferent)
+       {
+               SkRect  bounds;
+               fAnim.getInvalBounds(&bounds);
+               this->inval(&bounds);
+       }
+}
+
+/*virtual*/ bool SkScrollBarView::onEvent(const SkEvent& evt)
+{
+       if (evt.isType(SK_EventType_Inval))
+       {
+               this->inval(NULL);
+               return true;
+       }
+       if (evt.isType("recommendDim"))
+       {
+               SkScalar        width;
+               
+               if (evt.findScalar("x", &width))
+                       this->setWidth(width);
+               return true;
+       }
+
+       return this->INHERITED::onEvent(evt);
+}
+
+void SkScrollBarView::adjust()
+{
+       int total = fTotalLength;
+       int start = fStartPoint;
+       int shown = fShownLength;
+       int hideBar = 0;
+       
+       if (total <= 0 || shown <= 0 || shown >= total) // no bar to show
+       {
+               total = 1;              // avoid divide-by-zero. should be done by skin/script
+               hideBar = 1;    // signal we don't want a thumb
+       }
+       else
+       {
+               if (start + shown > total)
+                       start = total - shown;
+       }
+       
+       SkEvent e("user");
+       e.setString("id", "adjustScrollBar");
+       e.setScalar("_totalLength", SkIntToScalar(total));
+       e.setScalar("_startPoint", SkIntToScalar(start));
+       e.setScalar("_shownLength", SkIntToScalar(shown));
+//     e.setS32("hideBar", hideBar);
+       fAnim.doUserEvent(e);
+}
+
diff --git a/src/views/animated/SkStaticTextView.cpp b/src/views/animated/SkStaticTextView.cpp
new file mode 100644 (file)
index 0000000..2fd04a7
--- /dev/null
@@ -0,0 +1,184 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkWidgetViews.h"
+#include "SkTextBox.h"
+
+#ifdef SK_DEBUG
+static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
+{
+    const char* value = dom.findAttr(node, attr);
+    if (value)
+        SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
+}
+#else
+    #define assert_no_attr(dom, node, attr)
+#endif
+
+SkStaticTextView::SkStaticTextView()
+{
+       fMargin.set(0, 0);
+       fMode = kFixedSize_Mode;
+       fSpacingAlign = SkTextBox::kStart_SpacingAlign;
+       
+//     init_skin_paint(kStaticText_SkinEnum, &fPaint);
+}
+
+SkStaticTextView::~SkStaticTextView()
+{
+}
+
+void SkStaticTextView::computeSize()
+{
+       if (fMode == kAutoWidth_Mode)
+       {
+               SkScalar width = fPaint.measureText(fText.c_str(), fText.size());
+               this->setWidth(width + fMargin.fX * 2);
+       }
+       else if (fMode == kAutoHeight_Mode)
+       {
+               SkScalar width = this->width() - fMargin.fX * 2;
+               int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0;
+
+               this->setHeight(lines * fPaint.getFontSpacing() + fMargin.fY * 2);
+       }
+}
+
+void SkStaticTextView::setMode(Mode mode)
+{
+       SkASSERT((unsigned)mode < kModeCount);
+
+       if (fMode != mode)
+       {
+               fMode = SkToU8(mode);
+               this->computeSize();
+       }
+}
+
+void SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align)
+{
+       fSpacingAlign = SkToU8(align);
+       this->inval(NULL);
+}
+
+void SkStaticTextView::getMargin(SkPoint* margin) const
+{
+       if (margin)
+               *margin = fMargin;
+}
+
+void SkStaticTextView::setMargin(SkScalar dx, SkScalar dy)
+{
+       if (fMargin.fX != dx || fMargin.fY != dy)
+       {
+               fMargin.set(dx, dy);
+               this->computeSize();
+               this->inval(NULL);
+       }
+}
+
+size_t SkStaticTextView::getText(SkString* text) const
+{
+       if (text)
+               *text = fText;
+       return fText.size();
+}
+
+size_t SkStaticTextView::getText(char text[]) const
+{
+       if (text)
+               memcpy(text, fText.c_str(), fText.size());
+       return fText.size();
+}
+
+void SkStaticTextView::setText(const SkString& text)
+{
+       this->setText(text.c_str(), text.size());
+}
+
+void SkStaticTextView::setText(const char text[])
+{
+       if (text == NULL)
+               text = "";
+       this->setText(text, strlen(text));
+}
+
+void SkStaticTextView::setText(const char text[], size_t len)
+{
+       if (!fText.equals(text, len))
+       {
+               fText.set(text, len);
+               this->computeSize();
+               this->inval(NULL);
+       }
+}
+
+void SkStaticTextView::getPaint(SkPaint* paint) const
+{
+       if (paint)
+               *paint = fPaint;
+}
+
+void SkStaticTextView::setPaint(const SkPaint& paint)
+{
+       if (fPaint != paint)
+       {
+               fPaint = paint;
+               this->computeSize();
+               this->inval(NULL);
+       }
+}
+
+void SkStaticTextView::onDraw(SkCanvas* canvas)
+{
+       this->INHERITED::onDraw(canvas);
+
+       if (fText.isEmpty())
+               return;
+
+       SkTextBox       box;
+
+       box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode);
+       box.setSpacingAlign(this->getSpacingAlign());
+       box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY);
+       box.draw(canvas, fText.c_str(), fText.size(), fPaint);
+}
+
+void SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
+{
+#if 0
+       this->INHERITED::onInflate(dom, node);
+
+       int     index;
+       if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0)
+               this->setMode((Mode)index);
+       else
+               assert_no_attr(dom, node, "mode");
+
+       if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0)
+               this->setSpacingAlign((SkTextBox::SpacingAlign)index);
+       else
+               assert_no_attr(dom, node, "spacing-align");
+
+       SkScalar s[2];
+       if (dom.findScalars(node, "margin", s, 2))
+               this->setMargin(s[0], s[1]);
+       else
+               assert_no_attr(dom, node, "margin");
+
+       const char* text = dom.findAttr(node, "text");
+       if (text)
+               this->setText(text);
+
+       if ((node = dom.getFirstChild(node, "paint")) != NULL &&
+               (node = dom.getFirstChild(node, "screenplay")) != NULL)
+       {
+               inflate_paint(dom, node, &fPaint);
+       }
+#endif
+}
+
diff --git a/src/views/animated/SkWidgetViews.cpp b/src/views/animated/SkWidgetViews.cpp
new file mode 100644 (file)
index 0000000..2803d93
--- /dev/null
@@ -0,0 +1,412 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkWidgetViews.h"
+#include "SkAnimator.h"
+#include "SkCanvas.h"
+#include "SkPaint.h"
+#include "SkStream.h"
+#include "SkSystemEventTypes.h"
+
+#ifdef SK_DEBUG
+       static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
+       {
+               const char* value = dom.findAttr(node, attr);
+               if (value)
+                       SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
+       }
+#else
+       #define assert_no_attr(dom, node, attr)
+#endif
+/*
+I have moved this to SkWidgetViews.h
+enum SkinEnum {
+       kButton_SkinEnum,
+       kProgress_SkinEnum,
+       kScroll_SkinEnum,
+       kStaticText_SkinEnum,
+       
+       kSkinEnumCount
+};
+*/
+
+const char* get_skin_enum_path(SkinEnum se)
+{
+       SkASSERT((unsigned)se < kSkinEnumCount);
+
+       static const char* gSkinPaths[] = {
+            "common/default/default/skins/border3.xml",
+            "common/default/default/skins/button.xml",
+            "common/default/default/skins/progressBar.xml",
+            "common/default/default/skins/scrollBar.xml",
+            "common/default/default/skins/statictextpaint.xml"
+       };
+
+       return gSkinPaths[se];
+}
+
+void init_skin_anim(const char path[], SkAnimator* anim)
+{
+       SkASSERT(path && anim);
+
+       SkFILEStream    stream(path);
+
+       if (!stream.isValid())
+       {
+               SkDEBUGF(("init_skin_anim: loading skin failed <%s>\n", path));
+               sk_throw();
+       }
+
+       if (!anim->decodeStream(&stream))
+       {
+               SkDEBUGF(("init_skin_anim: decoding skin failed <%s>\n", path));
+               sk_throw();
+       }
+}
+
+void init_skin_anim(SkinEnum se, SkAnimator* anim)
+{
+       init_skin_anim(get_skin_enum_path(se), anim);
+}
+
+void init_skin_paint(SkinEnum se, SkPaint* paint)
+{
+       SkASSERT(paint);
+
+       SkAnimator      anim;
+       SkCanvas        canvas;
+       
+       init_skin_anim(se, &anim);
+       anim.draw(&canvas, paint, 0);
+}
+
+void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint)
+{
+       SkASSERT(paint);
+
+       SkAnimator      anim;
+       SkCanvas        canvas;
+       
+       if (!anim.decodeDOM(dom, node))
+       {
+               SkDEBUGF(("inflate_paint: decoding dom failed\n"));
+               SkDEBUGCODE(dom.dump(node);)
+               sk_throw();
+       }       
+       anim.draw(&canvas, paint, 0);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+SkWidgetView::SkWidgetView() : SkView(SkView::kFocusable_Mask | SkView::kEnabled_Mask)
+{
+}
+
+const char* SkWidgetView::getLabel() const
+{
+       return fLabel.c_str();
+}
+       
+void SkWidgetView::getLabel(SkString* label) const
+{
+       if (label)
+               *label = fLabel;
+}
+
+void SkWidgetView::setLabel(const char label[])
+{
+       this->setLabel(label, label ? strlen(label) : 0);
+}
+
+void SkWidgetView::setLabel(const char label[], size_t len)
+{
+       if ((label == NULL && fLabel.size() != 0) || !fLabel.equals(label, len))
+       {
+               SkString        tmp(label, len);
+
+               this->onLabelChange(fLabel.c_str(), tmp.c_str());
+               fLabel.swap(tmp);
+       }
+}
+
+void SkWidgetView::setLabel(const SkString& label)
+{
+       if (fLabel != label)
+       {
+               this->onLabelChange(fLabel.c_str(), label.c_str());
+               fLabel = label;
+       }
+}
+
+bool SkWidgetView::postWidgetEvent()
+{
+       if (!fEvent.isType(""))
+       {
+               SkEvent evt(fEvent);    // make a copy since onPrepareWidgetEvent may edit the event
+
+               if (this->onPrepareWidgetEvent(&evt))
+               {
+                       SkDEBUGCODE(evt.dump("SkWidgetView::postWidgetEvent");)
+
+                       this->postToListeners(evt);     // wonder if this should return true if there are > 0 listeners...
+                       return true;
+               }
+       }
+       return false;
+}
+
+/*virtual*/ void SkWidgetView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
+{
+       this->INHERITED::onInflate(dom, node);
+
+       const char* label = dom.findAttr(node, "label");
+       if (label)
+               this->setLabel(label);
+               
+       if ((node = dom.getFirstChild(node, "event")) != NULL)
+               fEvent.inflate(dom, node);
+}
+
+/*virtual*/ void SkWidgetView::onLabelChange(const char oldLabel[], const char newLabel[])
+{
+       this->inval(NULL);
+}
+
+static const char gWidgetEventSinkIDSlotName[] = "sk-widget-sinkid-slot";
+
+/*virtual*/ bool SkWidgetView::onPrepareWidgetEvent(SkEvent* evt)
+{
+       evt->setS32(gWidgetEventSinkIDSlotName, this->getSinkID());
+       return true;
+}
+
+SkEventSinkID SkWidgetView::GetWidgetEventSinkID(const SkEvent& evt)
+{
+       int32_t sinkID;
+       
+       return evt.findS32(gWidgetEventSinkIDSlotName, &sinkID) ? (SkEventSinkID)sinkID : 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*virtual*/ bool SkButtonView::onEvent(const SkEvent& evt)
+{
+       if (evt.isType(SK_EventType_Key) && evt.getFast32() == kOK_SkKey)
+       {
+               this->postWidgetEvent();
+               return true;
+       }
+       return this->INHERITED::onEvent(evt);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+SkCheckButtonView::SkCheckButtonView() : fCheckState(kOff_CheckState)
+{
+}
+
+void SkCheckButtonView::setCheckState(CheckState state)
+{
+       SkASSERT((unsigned)state <= kUnknown_CheckState);
+       
+       if (fCheckState != state)
+       {
+               this->onCheckStateChange(this->getCheckState(), state);
+               fCheckState = SkToU8(state);
+       }
+}
+       
+/*virtual*/ void SkCheckButtonView::onCheckStateChange(CheckState oldState, CheckState newState)
+{
+       this->inval(NULL);
+}
+
+/*virtual*/ void SkCheckButtonView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
+{
+       this->INHERITED::onInflate(dom, node);
+       
+       int index = dom.findList(node, "check-state", "off,on,unknown");
+       if (index >= 0)
+               this->setCheckState((CheckState)index);
+}
+
+static const char gCheckStateSlotName[] = "sk-checkbutton-check-slot";
+
+/*virtual*/ bool SkCheckButtonView::onPrepareWidgetEvent(SkEvent* evt)
+{
+       // could check if we're "disabled", and return false...
+
+       evt->setS32(gCheckStateSlotName, this->getCheckState());
+       return true;
+}
+
+bool SkCheckButtonView::GetWidgetEventCheckState(const SkEvent& evt, CheckState* state)
+{
+       int32_t state32;
+       
+       if (evt.findS32(gCheckStateSlotName, &state32))
+       {
+               if (state)
+                       *state = (CheckState)state32;
+               return true;
+       }
+       return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkTime.h"
+#include <stdio.h>
+
+class SkAnimButtonView : public SkButtonView {
+public:
+       SkAnimButtonView()
+       {
+               fAnim.setHostEventSink(this);
+               init_skin_anim(kButton_SkinEnum, &fAnim);
+       }
+
+protected:
+       virtual void onLabelChange(const char oldLabel[], const char newLabel[])
+       {
+               this->INHERITED::onLabelChange(oldLabel, newLabel);
+
+               SkEvent evt("user");
+               evt.setString("id", "setLabel");
+               evt.setString("LABEL", newLabel);
+               fAnim.doUserEvent(evt);
+       }
+       
+       virtual void onFocusChange(bool gainFocus)
+       {
+               this->INHERITED::onFocusChange(gainFocus);
+
+               SkEvent evt("user");
+               evt.setString("id", "setFocus");
+               evt.setS32("FOCUS", gainFocus);
+               fAnim.doUserEvent(evt);
+       }
+
+       virtual void onSizeChange()
+       {
+               this->INHERITED::onSizeChange();
+
+               SkEvent evt("user");
+               evt.setString("id", "setDim");
+               evt.setScalar("dimX", this->width());
+               evt.setScalar("dimY", this->height());
+               fAnim.doUserEvent(evt);
+       }
+
+       virtual void onDraw(SkCanvas* canvas)
+       {
+               SkPaint                                         paint;          
+               SkAnimator::DifferenceType      diff = fAnim.draw(canvas, &paint, SkTime::GetMSecs());
+               
+               if (diff == SkAnimator::kDifferent)
+                       this->inval(NULL);
+               else if (diff == SkAnimator::kPartiallyDifferent)
+               {
+                       SkRect  bounds;
+                       fAnim.getInvalBounds(&bounds);
+                       this->inval(&bounds);
+               }
+       }
+       
+       virtual bool onEvent(const SkEvent& evt)
+       {
+               if (evt.isType(SK_EventType_Inval))
+               {
+                       this->inval(NULL);
+                       return true;
+               }
+               if (evt.isType("recommendDim"))
+               {
+                       SkScalar        height;
+                       
+                       if (evt.findScalar("y", &height))
+                               this->setHeight(height);
+                       return true;
+               }
+               return this->INHERITED::onEvent(evt);
+       }
+       
+       virtual bool onPrepareWidgetEvent(SkEvent* evt)
+       {
+               if (this->INHERITED::onPrepareWidgetEvent(evt))
+               {
+                       SkEvent e("user");
+                       e.setString("id", "handlePress");
+                       (void)fAnim.doUserEvent(e);
+                       return true;
+               }
+               return false;
+       }
+
+private:
+       SkAnimator      fAnim;
+       
+       typedef SkButtonView INHERITED;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////
+
+SkView* SkWidgetFactory(const char name[])
+{
+       if (name == NULL)
+               return NULL;
+       
+       // must be in the same order as the SkSkinWidgetEnum is declared
+       static const char* gNames[] = {
+               "sk-border",
+               "sk-button",
+               "sk-image",
+               "sk-list",
+               "sk-progress",
+               "sk-scroll",
+               "sk-text"
+               
+       };
+
+       for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); i++)
+               if (!strcmp(gNames[i], name))
+                       return SkWidgetFactory((SkWidgetEnum)i);
+
+       return NULL;
+}
+
+#include "SkImageView.h"
+#include "SkProgressBarView.h"
+#include "SkScrollBarView.h"
+#include "SkBorderView.h"
+
+SkView* SkWidgetFactory(SkWidgetEnum sw)
+{
+       switch (sw) {
+       case kBorder_WidgetEnum:
+               return new SkBorderView;
+       case kButton_WidgetEnum:
+               return new SkAnimButtonView;
+       case kImage_WidgetEnum:
+               return new SkImageView;
+       case kList_WidgetEnum:
+               return new SkListView;
+       case kProgress_WidgetEnum:
+               return new SkProgressBarView;
+       case kScroll_WidgetEnum:
+               return new SkScrollBarView;
+       case kText_WidgetEnum:
+               return new SkStaticTextView;
+       default:
+               SkDEBUGFAIL("unknown enum passed to SkWidgetFactory");
+               break;
+       }
+       return NULL;
+}