2 * Copyright 2011 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
11 static int gOSMenuCmd = 7000;
13 SkOSMenu::SkOSMenu(const char title[]) {
17 SkOSMenu::~SkOSMenu() {
21 void SkOSMenu::reset() {
26 const SkOSMenu::Item* SkOSMenu::getItemByID(int itemID) const {
27 for (int i = 0; i < fItems.count(); ++i) {
28 if (itemID == fItems[i]->getID())
34 void SkOSMenu::getItems(const SkOSMenu::Item* items[]) const {
36 for (int i = 0; i < fItems.count(); ++i) {
42 void SkOSMenu::assignKeyEquivalentToItem(int itemID, SkUnichar key) {
43 for (int i = 0; i < fItems.count(); ++i) {
44 if (itemID == fItems[i]->getID())
45 fItems[i]->setKeyEquivalent(key);
49 bool SkOSMenu::handleKeyEquivalent(SkUnichar key) {
50 int value = 0, size = 0;
52 SkOSMenu::TriState tristate;
53 for (int i = 0; i < fItems.count(); ++i) {
54 Item* item = fItems[i];
55 if (item->getKeyEquivalent()== key) {
57 switch (item->getType()) {
59 SkOSMenu::FindListItemCount(*item->getEvent(), &size);
60 SkOSMenu::FindListIndex(*item->getEvent(), item->getSlotName(), &value);
61 value = (value + 1) % size;
65 SkOSMenu::FindSwitchState(*item->getEvent(), item->getSlotName(), &state);
66 item->setBool(!state);
69 SkOSMenu::FindTriState(*item->getEvent(), item->getSlotName(), &tristate);
70 if (kOnState == tristate)
71 tristate = kMixedState;
73 tristate = (SkOSMenu::TriState)((int)tristate + 1);
74 item->setTriState(tristate);
90 ////////////////////////////////////////////////////////////////////////////////
92 SkOSMenu::Item::Item(const char label[], SkOSMenu::Type type,
93 const char slotName[], SkEvent* evt) {
95 fSlotName.set(slotName);
99 fID = sk_atomic_inc(&gOSMenuCmd);
102 void SkOSMenu::Item::setBool(bool value) const {
103 SkASSERT(SkOSMenu::kSwitch_Type == fType);
104 fEvent->setBool(fSlotName.c_str(), value);
107 void SkOSMenu::Item::setScalar(SkScalar value) const {
108 SkASSERT(SkOSMenu::kSlider_Type == fType);
109 fEvent->setScalar(fSlotName.c_str(), value);
112 void SkOSMenu::Item::setInt(int value) const {
113 SkASSERT(SkOSMenu::kList_Type == fType);
114 fEvent->setS32(fSlotName.c_str(), value);
117 void SkOSMenu::Item::setTriState(TriState value) const {
118 SkASSERT(SkOSMenu::kTriState_Type == fType);
119 fEvent->setS32(fSlotName.c_str(), value);
122 void SkOSMenu::Item::setString(const char value[]) const {
123 SkASSERT(SkOSMenu::kTextField_Type == fType);
124 fEvent->setString(fSlotName.c_str(), value);
127 ////////////////////////////////////////////////////////////////////////////////
129 static const char* gMenuEventType = "SkOSMenuEventType";
130 static const char* gSlider_Min_Scalar = "SkOSMenuSlider_Min";
131 static const char* gSlider_Max_Scalar = "SkOSMenuSlider_Max";
132 static const char* gDelimiter = "|";
133 static const char* gList_Items_Str = "SkOSMenuList_Items";
134 static const char* gList_ItemCount_S32 = "SkOSMenuList_ItemCount";
136 int SkOSMenu::appendItem(const char label[], Type type, const char slotName[],
138 SkOSMenu::Item* item = new Item(label, type, slotName, evt);
139 fItems.append(1, &item);
140 return item->getID();
143 int SkOSMenu::appendAction(const char label[], SkEventSinkID target) {
144 SkEvent* evt = new SkEvent(gMenuEventType, target);
145 //Store label in event so it can be used to identify the action later
146 evt->setString(label, label);
147 return appendItem(label, SkOSMenu::kAction_Type, "", evt);
150 int SkOSMenu::appendList(const char label[], const char slotName[],
151 SkEventSinkID target, int index, const char option[], ...) {
152 SkEvent* evt = new SkEvent(gMenuEventType, target);
155 SkString str(option);
156 va_start(args, option);
158 for (const char* arg = va_arg(args, const char*); arg != NULL; arg = va_arg(args, const char*)) {
164 evt->setString(gList_Items_Str, str);
165 evt->setS32(gList_ItemCount_S32, count);
166 evt->setS32(slotName, index);
168 return appendItem(label, SkOSMenu::kList_Type, slotName, evt);
171 int SkOSMenu::appendSlider(const char label[], const char slotName[],
172 SkEventSinkID target, SkScalar min, SkScalar max,
173 SkScalar defaultValue) {
174 SkEvent* evt = new SkEvent(gMenuEventType, target);
175 evt->setScalar(gSlider_Min_Scalar, min);
176 evt->setScalar(gSlider_Max_Scalar, max);
177 evt->setScalar(slotName, defaultValue);
178 return appendItem(label, SkOSMenu::kSlider_Type, slotName, evt);
181 int SkOSMenu::appendSwitch(const char label[], const char slotName[],
182 SkEventSinkID target, bool defaultState) {
183 SkEvent* evt = new SkEvent(gMenuEventType, target);
184 evt->setBool(slotName, defaultState);
185 return appendItem(label, SkOSMenu::kSwitch_Type, slotName, evt);
188 int SkOSMenu::appendTriState(const char label[], const char slotName[],
189 SkEventSinkID target, SkOSMenu::TriState defaultState) {
190 SkEvent* evt = new SkEvent(gMenuEventType, target);
191 evt->setS32(slotName, defaultState);
192 return appendItem(label, SkOSMenu::kTriState_Type, slotName, evt);
195 int SkOSMenu::appendTextField(const char label[], const char slotName[],
196 SkEventSinkID target, const char placeholder[]) {
197 SkEvent* evt = new SkEvent(gMenuEventType, target);
198 evt->setString(slotName, placeholder);
199 return appendItem(label, SkOSMenu::kTextField_Type, slotName, evt);
202 bool SkOSMenu::FindListItemCount(const SkEvent& evt, int* count) {
203 return evt.isType(gMenuEventType) && evt.findS32(gList_ItemCount_S32, count);
206 bool SkOSMenu::FindListItems(const SkEvent& evt, SkString items[]) {
207 if (evt.isType(gMenuEventType) && items) {
208 const char* text = evt.findString(gList_Items_Str);
211 char* token = strtok((char*)temp.c_str(), gDelimiter);
213 while (token != NULL) {
214 items[index].set(token, strlen(token));
215 token = strtok (NULL, gDelimiter);
224 bool SkOSMenu::FindSliderMin(const SkEvent& evt, SkScalar* min) {
225 return evt.isType(gMenuEventType) && evt.findScalar(gSlider_Min_Scalar, min);
228 bool SkOSMenu::FindSliderMax(const SkEvent& evt, SkScalar* max) {
229 return evt.isType(gMenuEventType) && evt.findScalar(gSlider_Max_Scalar, max);
232 bool SkOSMenu::FindAction(const SkEvent& evt, const char label[]) {
233 return evt.isType(gMenuEventType) && evt.findString(label);
236 bool SkOSMenu::FindListIndex(const SkEvent& evt, const char slotName[], int* value) {
237 return evt.isType(gMenuEventType) && evt.findS32(slotName, value);
240 bool SkOSMenu::FindSliderValue(const SkEvent& evt, const char slotName[], SkScalar* value) {
241 return evt.isType(gMenuEventType) && evt.findScalar(slotName, value);
244 bool SkOSMenu::FindSwitchState(const SkEvent& evt, const char slotName[], bool* value) {
245 return evt.isType(gMenuEventType) && evt.findBool(slotName, value);
248 bool SkOSMenu::FindTriState(const SkEvent& evt, const char slotName[], SkOSMenu::TriState* value) {
249 return evt.isType(gMenuEventType) && evt.findS32(slotName, (int*)value);
252 bool SkOSMenu::FindText(const SkEvent& evt, const char slotName[], SkString* value) {
253 if (evt.isType(gMenuEventType)) {
254 const char* text = evt.findString(slotName);