blob: a8856cccd719cff80c50b46310e3e2756ccfc499 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
yangsu@google.com654d72f2011-08-01 17:27:33 +00007#include <stdarg.h>
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SkOSMenu.h"
yangsu@google.com654d72f2011-08-01 17:27:33 +00009#include "SkThread.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000010
11static int gOSMenuCmd = 7000;
12
yangsu@google.com654d72f2011-08-01 17:27:33 +000013SkOSMenu::SkOSMenu(const char title[]) {
14 fTitle.set(title);
reed@android.com8a1c16f2008-12-17 15:59:43 +000015}
16
yangsu@google.com654d72f2011-08-01 17:27:33 +000017SkOSMenu::~SkOSMenu() {
18 this->reset();
reed@android.com8a1c16f2008-12-17 15:59:43 +000019}
20
yangsu@google.com654d72f2011-08-01 17:27:33 +000021void SkOSMenu::reset() {
22 fItems.deleteAll();
23 fTitle.reset();
24}
25
26int SkOSMenu::countItems() const {
reed@android.com8a1c16f2008-12-17 15:59:43 +000027 return fItems.count();
28}
29
yangsu@google.com654d72f2011-08-01 17:27:33 +000030const SkOSMenu::Item* SkOSMenu::getItem(int index) const{
31 return fItems[index];
reed@android.com8a1c16f2008-12-17 15:59:43 +000032}
33
yangsu@google.com654d72f2011-08-01 17:27:33 +000034////////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +000035
yangsu@google.com654d72f2011-08-01 17:27:33 +000036SkOSMenu::Item::Item(const char label[], SkOSMenu::Type type,
37 const char slotName[], SkEvent* evt, SkEventSinkID target) {
38 fLabel.set(label);
39 fSlotName.set(slotName);
40 fType = type;
41 fTarget = target;
42 fEvent = evt;
43 fID = sk_atomic_inc(&gOSMenuCmd);
reed@android.com8a1c16f2008-12-17 15:59:43 +000044}
45
yangsu@google.com654d72f2011-08-01 17:27:33 +000046void SkOSMenu::Item::postEventWithBool(bool value) const {
47 SkASSERT(SkOSMenu::kSwitch_Type == fType);
48 fEvent->setBool(fSlotName.c_str(), value);
49 this->postEvent();
reed@android.com8a1c16f2008-12-17 15:59:43 +000050}
51
yangsu@google.com654d72f2011-08-01 17:27:33 +000052void SkOSMenu::Item::postEventWithScalar(SkScalar value) const {
53 SkASSERT(SkOSMenu::kSlider_Type == fType);
54 fEvent->setScalar(fSlotName.c_str(), value);
55 this->postEvent();
56}
57
58void SkOSMenu::Item::postEventWithInt(int value) const {
59 SkASSERT(SkOSMenu::kList_Type == fType || SkOSMenu::kTriState_Type == fType);
60 fEvent->setS32(fSlotName.c_str(), value);
61 this->postEvent();
62}
63
64void SkOSMenu::Item::postEventWithString(const char value[]) const {
65 SkASSERT(SkOSMenu::kTextField_Type == fType);
66 fEvent->setString(fSlotName.c_str(), value);
67 this->postEvent();
68}
69
70////////////////////////////////////////////////////////////////////////////////
71
72const char* SkOSMenu::EventType = "SkOSMenuEventType";
73const char* SkOSMenu::Delimiter = "|";
74const char* SkOSMenu::Slider_Min_Scalar = "SkOSMenuSlider_Min";
75const char* SkOSMenu::Slider_Max_Scalar = "SkOSMenuSlider_Max";
76const char* SkOSMenu::List_Items_Str = "SkOSMenuList_Items";
77
78int SkOSMenu::appendItem(const char label[], Type type, const char slotName[],
79 SkEvent* evt, SkEventSinkID target) {
80 SkOSMenu::Item* item = new Item(label, type, slotName, evt, target);
81 fItems.append(1, &item);
82 return item->getID();
83}
84
85int SkOSMenu::appendAction(const char label[], SkEventSinkID target) {
86 SkEvent* evt = new SkEvent(SkOSMenu::EventType);
87 SkOSMenu::Item* item = new Item(label, SkOSMenu::kAction_Type, "", evt, target);
88 //Store label in event so it can be used to identify the action later
89 evt->setString(label, "");
90 fItems.append(1, &item);
91 return item->getID();
92}
93
94int SkOSMenu::appendList(const char label[], const char slotName[],
95 SkEventSinkID target, int index, const char option[], ...) {
96 SkEvent* evt = new SkEvent(SkOSMenu::EventType);
97 va_list args;
98 if (option) {
99 SkString str(option);
100 va_start(args, option);
101 for (const char* arg = va_arg(args, const char*); arg != NULL; arg = va_arg(args, const char*)) {
102 str += SkOSMenu::Delimiter;
103 str += arg;
104 }
105 va_end(args);
106 evt->setString(SkOSMenu::List_Items_Str, str);
107 evt->setS32(slotName, index);
108 }
109 SkOSMenu::Item* item = new Item(label, SkOSMenu::kList_Type, slotName, evt, target);
110 fItems.append(1, &item);
111 return item->getID();
112}
113
114int SkOSMenu::appendSlider(const char label[], const char slotName[],
115 SkEventSinkID target, SkScalar min, SkScalar max,
116 SkScalar defaultValue) {
117 SkEvent* evt = new SkEvent(SkOSMenu::EventType);
118 evt->setScalar(SkOSMenu::Slider_Min_Scalar, min);
119 evt->setScalar(SkOSMenu::Slider_Max_Scalar, max);
120 evt->setScalar(slotName, defaultValue);
121 SkOSMenu::Item* item = new Item(label, SkOSMenu::kSlider_Type, slotName, evt, target);
122 fItems.append(1, &item);
123 return item->getID();
124}
125
126int SkOSMenu::appendSwitch(const char label[], const char slotName[],
127 SkEventSinkID target, bool defaultState) {
128 SkEvent* evt = new SkEvent(SkOSMenu::EventType);
129 evt->setBool(slotName, defaultState);
130 SkOSMenu::Item* item = new Item(label, SkOSMenu::kSwitch_Type, slotName, evt, target);
131 fItems.append(1, &item);
132 return item->getID();
133}
134
135int SkOSMenu::appendTriState(const char label[], const char slotName[],
136 SkEventSinkID target, SkOSMenu::TriState defaultState) {
137 SkEvent* evt = new SkEvent(SkOSMenu::EventType);
138 evt->setS32(slotName, defaultState);
139 SkOSMenu::Item* item = new Item(label, SkOSMenu::kTriState_Type, slotName, evt, target);
140 fItems.append(1, &item);
141 return item->getID();
142}
143
144int SkOSMenu::appendTextField(const char label[], const char slotName[],
145 SkEventSinkID target, const char placeholder[]) {
146 SkEvent* evt = new SkEvent(SkOSMenu::EventType);
147 evt->setString(slotName, placeholder);
148 SkOSMenu::Item* item = new Item(label, SkOSMenu::kTextField_Type, slotName, evt, target);
149 fItems.append(1, &item);
150 return item->getID();
151}
152
153
154bool SkOSMenu::FindAction(const SkEvent* evt, const char label[]) {
155 return evt->isType(SkOSMenu::EventType) && evt->findString(label);
156}
157
158bool SkOSMenu::FindListIndex(const SkEvent* evt, const char slotName[], int* selected) {
159 return evt->isType(SkOSMenu::EventType) && evt->findS32(slotName, selected);
160}
161
162bool SkOSMenu::FindSliderValue(const SkEvent* evt, const char slotName[], SkScalar* value) {
163 return evt->isType(SkOSMenu::EventType) && evt->findScalar(slotName, value);
164}
165
166bool SkOSMenu::FindSwitchState(const SkEvent* evt, const char slotName[], bool* value) {
167 return evt->isType(SkOSMenu::EventType) && evt->findBool(slotName, value);
168}
169
170bool SkOSMenu::FindTriState(const SkEvent* evt, const char slotName[], SkOSMenu::TriState* state) {
171 return evt->isType(SkOSMenu::EventType) && evt->findS32(slotName, (int*)state);
172}
173
174bool SkOSMenu::FindText(const SkEvent* evt, const char slotName[], SkString* value) {
175 if (evt->isType(SkOSMenu::EventType)) {
176 const char* text = evt->findString(slotName);
177 if (!text || !*text)
178 return false;
179 else {
180 value->set(text);
181 return true;
182 }
183 }
184 return false;
185}