1 
2 /*
3  * Copyright 2006 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 #ifndef SkWidgetViews_DEFINED
11 #define SkWidgetViews_DEFINED
12 
13 #include "SkView.h"
14 
15 
16 enum SkWidgetEnum {
17     kBorder_WidgetEnum,         //!< <sk-border>
18     kButton_WidgetEnum,         //!< <sk-button>
19     kImage_WidgetEnum,          //!< <sk-image>
20     kList_WidgetEnum,           //!< <sk-list>
21     kProgress_WidgetEnum,       //!< <sk-progress>
22     kScroll_WidgetEnum,         //!< <sk-scroll>
23     kText_WidgetEnum,           //!< <sk-text>
24 
25     kWidgetEnumCount
26 };
27 
28 //determines which skin to use
29 enum SkinEnum {
30     kBorder_SkinEnum,
31     kButton_SkinEnum,
32     kProgress_SkinEnum,
33     kScroll_SkinEnum,
34     kStaticText_SkinEnum,
35 
36     kSkinEnumCount
37 };
38 
39 #include "SkAnimator.h"
40 //used for inflates
41 const char* get_skin_enum_path(SkinEnum se);
42 void init_skin_anim(const char path[], SkAnimator* anim);
43 void init_skin_anim(SkinEnum se, SkAnimator* anim);
44 void init_skin_paint(SkinEnum se, SkPaint* paint);
45 void inflate_paint(const SkDOM& dom, const SkDOM::Node* node, SkPaint* paint);
46 
47 /** Given an enum value, return an instance of the specified widget.
48     If the enum is out of range, returns null
49 */
50 SkView* SkWidgetFactory(SkWidgetEnum);
51 /** Given the inflate/element name of a widget, return an instance of
52     the specified widget, or null if name does not match any known
53     widget type.
54 */
55 SkView* SkWidgetFactory(const char name[]);
56 
57 ////////////////////////////////////////////////////////////////////////////////////////////////
58 
59 class SkWidgetView : public SkView {
60 public:
61     SkWidgetView();
62 
63     const char* getLabel() const;
64     void        getLabel(SkString* label) const;
65 
66     void        setLabel(const char[]);
67     void        setLabel(const char[], size_t len);
68     void        setLabel(const SkString&);
69 
event()70     SkEvent&        event() { return fEvent; }
event()71     const SkEvent&  event() const { return fEvent; }
72 
73     /** Returns true if the widget can post its event to its listeners.
74     */
75     bool    postWidgetEvent();
76 
77     /** Returns the sinkID of the widgetview that posted the event, or 0
78     */
79     static SkEventSinkID GetWidgetEventSinkID(const SkEvent&);
80 
81 protected:
82     /** called when the label changes. override in subclasses. default action invals the view's bounds.
83         called with the old and new labels, before the label has actually changed.
84     */
85     virtual void onLabelChange(const char oldLabel[], const char newLabel[]);
86     /** called before posting the event to our listeners. Override to add slots to the event
87         before posting. Return true to proceed with posting, or false to not post the event to any
88         listener. Note: the event passed in may not be the same as calling this->event().
89         Be sure to call your INHERITED method as well, so that all classes in the hierarchy get a shot
90         at modifying the event (and possibly returning false to abort).
91     */
92     virtual bool onPrepareWidgetEvent(SkEvent* evt);
93 
94     // overrides
95     virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
96 
97 private:
98     SkString    fLabel;
99     SkEvent     fEvent;
100 
101     typedef SkView INHERITED;
102 };
103 
104 ////////////////////////////////////////////////////////////////////////////////////////////////
105 
106 class SkButtonView : public SkWidgetView {
107 public:
108     // inflate: "sk-button"
109 
110 protected:
111     // overrides
112     virtual bool onEvent(const SkEvent&);
113 private:
114     typedef SkWidgetView INHERITED;
115 };
116 
117 ////////////////////////////////////////////////////////////////////////////////////////////////
118 
119 class SkCheckButtonView : public SkWidgetView {
120 public:
121     SkCheckButtonView();
122 
123     // inflate: "sk-checkbutton"
124 
125     enum CheckState {
126         kOff_CheckState,        //!< inflate: check-state="off"
127         kOn_CheckState,         //!< inflate: check-state="on"
128         kUnknown_CheckState     //!< inflate: check-state="unknown"
129     };
getCheckState()130     CheckState  getCheckState() const { return (CheckState)fCheckState; }
131     void        setCheckState(CheckState);
132 
133     /** use this to extract the CheckState from an event (i.e. one that as posted
134         by a SkCheckButtonView). Returns true if the proper slot was present in the event,
135         and sets state to that value. If no proper slot is found, returns false and does not
136         modify state.
137     */
138     static bool GetWidgetEventCheckState(const SkEvent&, CheckState* state);
139 
140 protected:
141     // called when the check-state is about to change, but before it actually has
142     virtual void onCheckStateChange(CheckState oldState, CheckState newState);
143 
144     // overrides
145     virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
146     virtual bool onPrepareWidgetEvent(SkEvent* evt);
147 
148 private:
149     uint8_t  fCheckState;
150 
151     typedef SkWidgetView INHERITED;
152 };
153 
154 ////////////////////////////////////////////////////////////////////////////////////////////////
155 #include "SkTextBox.h"
156 
157 class SkStaticTextView : public SkView {
158 public:
159             SkStaticTextView();
160     virtual ~SkStaticTextView();
161 
162     enum Mode {
163         kFixedSize_Mode,
164         kAutoWidth_Mode,
165         kAutoHeight_Mode,
166 
167         kModeCount
168     };
getMode()169     Mode    getMode() const { return (Mode)fMode; }
170     void    setMode(Mode);
171 
getSpacingAlign()172     SkTextBox::SpacingAlign getSpacingAlign() const { return (SkTextBox::SpacingAlign)fSpacingAlign; }
173     void    setSpacingAlign(SkTextBox::SpacingAlign);
174 
175     void    getMargin(SkPoint* margin) const;
176     void    setMargin(SkScalar dx, SkScalar dy);
177 
178     size_t  getText(SkString* text = NULL) const;
179     size_t  getText(char text[] = NULL) const;
180     void    setText(const SkString&);
181     void    setText(const char text[]);
182     void    setText(const char text[], size_t len);
183 
184     void    getPaint(SkPaint*) const;
185     void    setPaint(const SkPaint&);
186 
187 protected:
188     // overrides
189     virtual void onDraw(SkCanvas*);
190     virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
191 
192 private:
193     SkPoint     fMargin;
194     SkString    fText;
195     SkPaint     fPaint;
196     uint8_t     fMode;
197     uint8_t     fSpacingAlign;
198 
199     void computeSize();
200 
201     typedef SkView INHERITED;
202 };
203 
204 ////////////////////////////////////////////////////////////////////////////////////////////////
205 
206 class SkAnimator;
207 class SkListSource;
208 class SkScrollBarView;
209 
210 class SkListView : public SkWidgetView {
211 public:
212             SkListView();
213     virtual ~SkListView();
214 
hasScrollBar()215     bool    hasScrollBar() const { return fScrollBar != NULL; }
216     void    setHasScrollBar(bool);
217 
218     /** Return the number of visible rows
219     */
getVisibleRowCount()220     int     getVisibleRowCount() const { return fVisibleRowCount; }
221     /** Return the index of the selected row, or -1 if none
222     */
getSelection()223     int     getSelection() const { return fCurrIndex; }
224     /** Set the index of the selected row, or -1 for none
225     */
226     void    setSelection(int);
227     /** If possible, move the selection up and return true,
228         else do nothing and return false
229         If nothing is selected, select the last item (unless there are no items).
230     */
231     bool    moveSelectionUp();
232     /** If possible, move the selection down and return true,
233         else do nothing and return false.
234         If nothing is selected, select the first item (unless there are no items).
235     */
236     bool    moveSelectionDown();
237 
getListSource()238     SkListSource*   getListSource() const { return fSource; }
239     SkListSource*   setListSource(SkListSource*);
240 
241     /** Call this in your event handler. If the specified event is from a SkListView,
242         then it returns the index of the selected item in this list, otherwise it
243         returns -1
244     */
245     static int GetWidgetEventListIndex(const SkEvent&);
246 
247 protected:
248     // overrides
249     virtual void onDraw(SkCanvas*);
250     virtual void onSizeChange();
251     virtual bool onEvent(const SkEvent&);
252     virtual void onInflate(const SkDOM& dom, const SkDOM::Node* node);
253     virtual bool onPrepareWidgetEvent(SkEvent*);
254 
255 private:
256     enum DirtyFlags {
257         kAnimCount_DirtyFlag    = 0x01,
258         kAnimContent_DirtyFlag  = 0x02
259     };
260     void    dirtyCache(unsigned dirtyFlags);
261     bool    ensureCache();
262 
logicalToVisualIndex(int index)263     int     logicalToVisualIndex(int index) const { return index - fScrollIndex; }
264     void    invalSelection();
265     SkScalar getContentWidth() const;
266     bool    getRowRect(int index, SkRect*) const;
267     void    ensureSelectionIsVisible();
268     void    ensureVisibleRowCount();
269 
270     struct BindingRec;
271 
272     enum Heights {
273         kNormal_Height,
274         kSelected_Height
275     };
276     SkListSource*   fSource;
277     SkScrollBarView*    fScrollBar;
278     SkAnimator*     fAnims;
279     BindingRec*     fBindings;
280     SkString        fSkinName;
281     SkScalar        fHeights[2];
282     int16_t         fScrollIndex, fCurrIndex;
283     uint16_t        fVisibleRowCount, fBindingCount;
284     SkBool8         fAnimContentDirty;
285     SkBool8         fAnimFocusDirty;
286 
287     typedef SkWidgetView INHERITED;
288 };
289 
290 class SkListSource : public SkRefCnt {
291 public:
292     SK_DECLARE_INST_COUNT(SkListSource)
293 
294     virtual int countFields();
295     virtual void getFieldName(int index, SkString* field);
296     /** Return the index of the named field, or -1 if not found */
297     virtual int findFieldIndex(const char field[]);
298 
299     virtual int countRecords();
300     virtual void getRecord(int rowIndex, int fieldIndex, SkString* data);
301 
302     virtual bool prepareWidgetEvent(SkEvent*, int rowIndex);
303 
304     static SkListSource* Factory(const char name[]);
305 private:
306     typedef SkRefCnt INHERITED;
307 };
308 
309 #endif
310