blob: 0c4a619efa3730afafe50b0a7005619c302713cf [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 /**
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000069 * Helper functions for predefined types
70 */
71 void setBool(bool value) const; //For Switch
72 void setScalar(SkScalar value) const; //For Slider
73 void setInt(int value) const; //For List
74 void setTriState(TriState value) const; //For Tristate
75 void setString(const char value[]) const; //For TextField
76
77 /**
yangsu@google.come55f5332011-08-05 22:11:41 +000078 * Post event associated with the menu item to target, any changes to
79 * the associated event must be made prior to calling this method
80 */
81 void postEvent() const { (new SkEvent(*(fEvent)))->post(); }
reed@android.com8a1c16f2008-12-17 15:59:43 +000082
yangsu@google.com654d72f2011-08-01 17:27:33 +000083 private:
84 int fID;
85 SkEvent* fEvent;
86 SkString fLabel;
87 SkString fSlotName;
yangsu@google.com654d72f2011-08-01 17:27:33 +000088 Type fType;
yangsu@google.come55f5332011-08-05 22:11:41 +000089 SkUnichar fKey;
yangsu@google.com654d72f2011-08-01 17:27:33 +000090 };
91
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000092 void reset();
yangsu@google.come55f5332011-08-05 22:11:41 +000093 const char* getTitle() const { return fTitle.c_str(); }
94 void setTitle (const char title[]) { fTitle.set(title); }
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000095 int getCount() const { return fItems.count(); }
96 const Item* getItemByID(int itemID) const;
97 void getItems(const Item* items[]) const;
yangsu@google.come55f5332011-08-05 22:11:41 +000098
99 /**
100 * Assign key to the menu item with itemID, will do nothing if there's no
101 * item with the id given
102 */
103 void assignKeyEquivalentToItem(int itemID, SkUnichar key);
104 /**
105 * Call this in a SkView's onHandleChar to trigger any menu items with the
106 * given key equivalent. If such an item is found, the method will return
107 * true and its corresponding event will be triggered (default behavior
108 * defined for switches(toggling), tristates(cycle), and lists(cycle),
109 * for anything else, the event attached is posted without state changes)
110 * If no menu item can be matched with the key, false will be returned
111 */
112 bool handleKeyEquivalent(SkUnichar key);
113
114 /**
115 * The following functions append new items to the menu and returns their
116 * associated unique id, which can be used to by the client to refer to
117 * the menu item created and change its state. slotName specifies the string
118 * identifier of any state/value to be returned in the item's SkEvent object
119 * NOTE: evt must be dynamically allocated
120 */
yangsu@google.com654d72f2011-08-01 17:27:33 +0000121 int appendItem(const char label[], Type type, const char slotName[],
yangsu@google.come55f5332011-08-05 22:11:41 +0000122 SkEvent* evt);
yangsu@google.com654d72f2011-08-01 17:27:33 +0000123
yangsu@google.come55f5332011-08-05 22:11:41 +0000124 /**
125 * Create predefined items with the given parameters. To be used with the
126 * other helper functions below to retrive/update state information.
127 * Note: the helper functions below assume that slotName is UNIQUE for all
128 * menu items of the same type since it's used to identify the event
129 */
yangsu@google.com654d72f2011-08-01 17:27:33 +0000130 int appendAction(const char label[], SkEventSinkID target);
131 int appendList(const char label[], const char slotName[],
132 SkEventSinkID target, int defaultIndex, const char[] ...);
133 int appendSlider(const char label[], const char slotName[],
134 SkEventSinkID target, SkScalar min, SkScalar max,
135 SkScalar defaultValue);
136 int appendSwitch(const char label[], const char slotName[],
137 SkEventSinkID target, bool defaultState = false);
138 int appendTriState(const char label[], const char slotName[],
yangsu@google.come55f5332011-08-05 22:11:41 +0000139 SkEventSinkID target, TriState defaultState = kOffState);
yangsu@google.com654d72f2011-08-01 17:27:33 +0000140 int appendTextField(const char label[], const char slotName[],
141 SkEventSinkID target, const char placeholder[] = "");
142
yangsu@google.come55f5332011-08-05 22:11:41 +0000143
144 /**
145 * Helper functions to retrieve information other than the stored value for
146 * some predefined types
147 */
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000148 static bool FindListItemCount(const SkEvent& evt, int* count);
yangsu@google.come55f5332011-08-05 22:11:41 +0000149 /**
150 * Ensure that the items array can store n SkStrings where n is the count
151 * extracted using FindListItemCount
152 */
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000153 static bool FindListItems(const SkEvent& evt, SkString items[]);
154 static bool FindSliderMin(const SkEvent& evt, SkScalar* min);
155 static bool FindSliderMax(const SkEvent& evt, SkScalar* max);
yangsu@google.come55f5332011-08-05 22:11:41 +0000156
157 /**
158 * Returns true if an action with the given label is found, false otherwise
159 */
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000160 static bool FindAction(const SkEvent& evt, const char label[]);
yangsu@google.come55f5332011-08-05 22:11:41 +0000161 /**
162 * The following helper functions will return true if evt is generated from
163 * a predefined item type and retrieve the corresponding state information.
164 * They will return false and leave value unchanged if there's a type
165 * mismatch or slotName is incorrect
166 */
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000167 static bool FindListIndex(const SkEvent& evt, const char slotName[], int* value);
168 static bool FindSliderValue(const SkEvent& evt, const char slotName[], SkScalar* value);
169 static bool FindSwitchState(const SkEvent& evt, const char slotName[], bool* value);
170 static bool FindTriState(const SkEvent& evt, const char slotName[], TriState* value);
171 static bool FindText(const SkEvent& evt, const char slotName[], SkString* value);
yangsu@google.com654d72f2011-08-01 17:27:33 +0000172
reed@android.com8a1c16f2008-12-17 15:59:43 +0000173private:
yangsu@google.com654d72f2011-08-01 17:27:33 +0000174 SkString fTitle;
175 SkTDArray<Item*> fItems;
176
reed@android.com8a1c16f2008-12-17 15:59:43 +0000177 // illegal
178 SkOSMenu(const SkOSMenu&);
179 SkOSMenu& operator=(const SkOSMenu&);
180};
181
182#endif
183