aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/views/SkWidgetViews.h
blob: 4dd88669f80b2fccde5223532b763ca147d252f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#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&);
};

////////////////////////////////////////////////////////////////////////////////////////////////

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