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
16enum 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
29enum 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
41const char* get_skin_enum_path(SkinEnum se);
42void init_skin_anim(const char path[], SkAnimator* anim);
43void init_skin_anim(SkinEnum se, SkAnimator* anim);
44void init_skin_paint(SkinEnum se, SkPaint* paint);
45void 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*/
50SkView* 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*/
55SkView* SkWidgetFactory(const char name[]);
56
57////////////////////////////////////////////////////////////////////////////////////////////////
58
59class SkWidgetView : public SkView {
60public:
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
70    SkEvent&        event() { return fEvent; }
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
81protected:
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
97private:
98    SkString    fLabel;
99    SkEvent     fEvent;
100
101    typedef SkView INHERITED;
102};
103
104////////////////////////////////////////////////////////////////////////////////////////////////
105
106class SkButtonView : public SkWidgetView {
107public:
108    // inflate: "sk-button"
109
110protected:
111    // overrides
112    virtual bool onEvent(const SkEvent&);
113private:
114    typedef SkWidgetView INHERITED;
115};
116
117////////////////////////////////////////////////////////////////////////////////////////////////
118
119class SkCheckButtonView : public SkWidgetView {
120public:
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    };
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
140protected:
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
148private:
149    uint8_t  fCheckState;
150
151    typedef SkWidgetView INHERITED;
152};
153
154////////////////////////////////////////////////////////////////////////////////////////////////
155#include "SkTextBox.h"
156
157class SkStaticTextView : public SkView {
158public:
159            SkStaticTextView();
160    virtual ~SkStaticTextView();
161
162    enum Mode {
163        kFixedSize_Mode,
164        kAutoWidth_Mode,
165        kAutoHeight_Mode,
166
167        kModeCount
168    };
169    Mode    getMode() const { return (Mode)fMode; }
170    void    setMode(Mode);
171
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
187protected:
188    // overrides
189    virtual void onDraw(SkCanvas*);
190    virtual void onInflate(const SkDOM& dom, const SkDOM::Node*);
191
192private:
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
206class SkAnimator;
207class SkListSource;
208class SkScrollBarView;
209
210class SkListView : public SkWidgetView {
211public:
212            SkListView();
213    virtual ~SkListView();
214
215    bool    hasScrollBar() const { return fScrollBar != NULL; }
216    void    setHasScrollBar(bool);
217
218    /** Return the number of visible rows
219    */
220    int     getVisibleRowCount() const { return fVisibleRowCount; }
221    /** Return the index of the selected row, or -1 if none
222    */
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
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
247protected:
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
255private:
256    enum DirtyFlags {
257        kAnimCount_DirtyFlag    = 0x01,
258        kAnimContent_DirtyFlag  = 0x02
259    };
260    void    dirtyCache(unsigned dirtyFlags);
261    bool    ensureCache();
262
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
290class SkListSource : public SkRefCnt {
291public:
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[]);
305private:
306    typedef SkRefCnt INHERITED;
307};
308
309#endif
310