blob: 763499e07314611dfc1a07675857c5ea12a59522 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkOSMenu_DEFINED
11#define SkOSMenu_DEFINED
12
13#include "SkEvent.h"
14#include "SkTDArray.h"
15
16class SkOSMenu {
17public:
yangsu@google.com654d72f2011-08-01 17:27:33 +000018 explicit SkOSMenu(const char title[] = "");
reed@android.com8a1c16f2008-12-17 15:59:43 +000019 ~SkOSMenu();
yangsu@google.com654d72f2011-08-01 17:27:33 +000020
yangsu@google.com654d72f2011-08-01 17:27:33 +000021 /**
22 * Each of these (except action) has an associated value, which is stored in
23 * the event payload for the item.
24 * Each type has a specific type for its value...
25 * Action : none
26 * List : int (selected index)
27 * Segmented : int (selected index)
28 * Slider : float
29 * Switch : bool
30 * TextField : string
31 * TriState : TriState
32 * Custom : custom object/value
33 */
yangsu@google.com654d72f2011-08-01 17:27:33 +000034 enum Type {
35 kAction_Type,
36 kList_Type,
37 kSlider_Type,
38 kSwitch_Type,
39 kTriState_Type,
40 kTextField_Type,
41 kCustom_Type
42 };
43
yangsu@google.come55f5332011-08-05 22:11:41 +000044 enum TriState {
45 kMixedState = -1,
46 kOffState = 0,
47 kOnState = 1
48 };
49
yangsu@google.com654d72f2011-08-01 17:27:33 +000050 class Item {
51 public:
yangsu@google.come55f5332011-08-05 22:11:41 +000052 /**
53 * Auto increments a global to generate an unique ID for each new item
54 * Note: Thread safe
55 */
yangsu@google.com654d72f2011-08-01 17:27:33 +000056 Item(const char label[], SkOSMenu::Type type, const char slotName[],
yangsu@google.come55f5332011-08-05 22:11:41 +000057 SkEvent* evt);
yangsu@google.com654d72f2011-08-01 17:27:33 +000058 ~Item() { delete fEvent; }
59
yangsu@google.come55f5332011-08-05 22:11:41 +000060 SkEvent* getEvent() const { return fEvent; }
61 int getID() const { return fID; }
yangsu@google.com654d72f2011-08-01 17:27:33 +000062 const char* getLabel() const { return fLabel.c_str(); }
63 const char* getSlotName() const { return fSlotName.c_str(); }
yangsu@google.come55f5332011-08-05 22:11:41 +000064 Type getType() const { return fType; }
65 void setKeyEquivalent(SkUnichar key) { fKey = key; }
66 SkUnichar getKeyEquivalent() const { return fKey; }
yangsu@google.com654d72f2011-08-01 17:27:33 +000067
yangsu@google.come55f5332011-08-05 22:11:41 +000068 /**
69 * Post event associated with the menu item to target, any changes to
70 * the associated event must be made prior to calling this method
71 */
72 void postEvent() const { (new SkEvent(*(fEvent)))->post(); }
yangsu@google.com654d72f2011-08-01 17:27:33 +000073
yangsu@google.come55f5332011-08-05 22:11:41 +000074 /**
75 * Helper functions for predefined types
76 */
77 void postEventWithBool(bool value) const; //For Switch
78 void postEventWithScalar(SkScalar value) const; //For Slider
79 void postEventWithInt(int value) const; //For List, TriState
yangsu@google.com654d72f2011-08-01 17:27:33 +000080 void postEventWithString(const char value[]) const; //For TextField
reed@android.com8a1c16f2008-12-17 15:59:43 +000081
yangsu@google.com654d72f2011-08-01 17:27:33 +000082 private:
83 int fID;
84 SkEvent* fEvent;
85 SkString fLabel;
86 SkString fSlotName;
yangsu@google.com654d72f2011-08-01 17:27:33 +000087 Type fType;
yangsu@google.come55f5332011-08-05 22:11:41 +000088 SkUnichar fKey;
yangsu@google.com654d72f2011-08-01 17:27:33 +000089 };
90
yangsu@google.come55f5332011-08-05 22:11:41 +000091 void reset();
92 const char* getTitle() const { return fTitle.c_str(); }
93 void setTitle (const char title[]) { fTitle.set(title); }
94 int countItems() const { return fItems.count(); }
95 const Item* getItem(int index) const { return fItems[index]; }
96
97 /**
98 * Assign key to the menu item with itemID, will do nothing if there's no
99 * item with the id given
100 */
101 void assignKeyEquivalentToItem(int itemID, SkUnichar key);
102 /**
103 * Call this in a SkView's onHandleChar to trigger any menu items with the
104 * given key equivalent. If such an item is found, the method will return
105 * true and its corresponding event will be triggered (default behavior
106 * defined for switches(toggling), tristates(cycle), and lists(cycle),
107 * for anything else, the event attached is posted without state changes)
108 * If no menu item can be matched with the key, false will be returned
109 */
110 bool handleKeyEquivalent(SkUnichar key);
111
112 /**
113 * The following functions append new items to the menu and returns their
114 * associated unique id, which can be used to by the client to refer to
115 * the menu item created and change its state. slotName specifies the string
116 * identifier of any state/value to be returned in the item's SkEvent object
117 * NOTE: evt must be dynamically allocated
118 */
yangsu@google.com654d72f2011-08-01 17:27:33 +0000119 int appendItem(const char label[], Type type, const char slotName[],
yangsu@google.come55f5332011-08-05 22:11:41 +0000120 SkEvent* evt);
yangsu@google.com654d72f2011-08-01 17:27:33 +0000121
yangsu@google.come55f5332011-08-05 22:11:41 +0000122 /**
123 * Create predefined items with the given parameters. To be used with the
124 * other helper functions below to retrive/update state information.
125 * Note: the helper functions below assume that slotName is UNIQUE for all
126 * menu items of the same type since it's used to identify the event
127 */
yangsu@google.com654d72f2011-08-01 17:27:33 +0000128 int appendAction(const char label[], SkEventSinkID target);
129 int appendList(const char label[], const char slotName[],
130 SkEventSinkID target, int defaultIndex, const char[] ...);
131 int appendSlider(const char label[], const char slotName[],
132 SkEventSinkID target, SkScalar min, SkScalar max,
133 SkScalar defaultValue);
134 int appendSwitch(const char label[], const char slotName[],
135 SkEventSinkID target, bool defaultState = false);
136 int appendTriState(const char label[], const char slotName[],
yangsu@google.come55f5332011-08-05 22:11:41 +0000137 SkEventSinkID target, TriState defaultState = kOffState);
yangsu@google.com654d72f2011-08-01 17:27:33 +0000138 int appendTextField(const char label[], const char slotName[],
139 SkEventSinkID target, const char placeholder[] = "");
140
yangsu@google.come55f5332011-08-05 22:11:41 +0000141
142 /**
143 * Helper functions to retrieve information other than the stored value for
144 * some predefined types
145 */
146 static bool FindListItemCount(const SkEvent* evt, int* count);
147 /**
148 * Ensure that the items array can store n SkStrings where n is the count
149 * extracted using FindListItemCount
150 */
151 static bool FindListItems(const SkEvent* evt, SkString items[]);
152 static bool FindSliderMin(const SkEvent* evt, SkScalar* min);
153 static bool FindSliderMax(const SkEvent* evt, SkScalar* max);
154
155 /**
156 * Returns true if an action with the given label is found, false otherwise
157 */
yangsu@google.com654d72f2011-08-01 17:27:33 +0000158 static bool FindAction(const SkEvent* evt, const char label[]);
yangsu@google.come55f5332011-08-05 22:11:41 +0000159 /**
160 * The following helper functions will return true if evt is generated from
161 * a predefined item type and retrieve the corresponding state information.
162 * They will return false and leave value unchanged if there's a type
163 * mismatch or slotName is incorrect
164 */
165 static bool FindListIndex(const SkEvent* evt, const char slotName[], int* value);
yangsu@google.com654d72f2011-08-01 17:27:33 +0000166 static bool FindSliderValue(const SkEvent* evt, const char slotName[], SkScalar* value);
167 static bool FindSwitchState(const SkEvent* evt, const char slotName[], bool* value);
yangsu@google.come55f5332011-08-05 22:11:41 +0000168 static bool FindTriState(const SkEvent* evt, const char slotName[], TriState* value);
yangsu@google.com654d72f2011-08-01 17:27:33 +0000169 static bool FindText(const SkEvent* evt, const char slotName[], SkString* value);
170
reed@android.com8a1c16f2008-12-17 15:59:43 +0000171private:
yangsu@google.com654d72f2011-08-01 17:27:33 +0000172 SkString fTitle;
173 SkTDArray<Item*> fItems;
174
reed@android.com8a1c16f2008-12-17 15:59:43 +0000175 // illegal
176 SkOSMenu(const SkOSMenu&);
177 SkOSMenu& operator=(const SkOSMenu&);
178};
179
180#endif
181