1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/views/SkOSMenu.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,263 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 +#include <stdarg.h> 1.11 +#include "SkOSMenu.h" 1.12 +#include "SkThread.h" 1.13 + 1.14 +static int gOSMenuCmd = 7000; 1.15 + 1.16 +SkOSMenu::SkOSMenu(const char title[]) { 1.17 + fTitle.set(title); 1.18 +} 1.19 + 1.20 +SkOSMenu::~SkOSMenu() { 1.21 + this->reset(); 1.22 +} 1.23 + 1.24 +void SkOSMenu::reset() { 1.25 + fItems.deleteAll(); 1.26 + fTitle.reset(); 1.27 +} 1.28 + 1.29 +const SkOSMenu::Item* SkOSMenu::getItemByID(int itemID) const { 1.30 + for (int i = 0; i < fItems.count(); ++i) { 1.31 + if (itemID == fItems[i]->getID()) 1.32 + return fItems[i]; 1.33 + } 1.34 + return NULL; 1.35 +} 1.36 + 1.37 +void SkOSMenu::getItems(const SkOSMenu::Item* items[]) const { 1.38 + if (NULL != items) { 1.39 + for (int i = 0; i < fItems.count(); ++i) { 1.40 + items[i] = fItems[i]; 1.41 + } 1.42 + } 1.43 +} 1.44 + 1.45 +void SkOSMenu::assignKeyEquivalentToItem(int itemID, SkUnichar key) { 1.46 + for (int i = 0; i < fItems.count(); ++i) { 1.47 + if (itemID == fItems[i]->getID()) 1.48 + fItems[i]->setKeyEquivalent(key); 1.49 + } 1.50 +} 1.51 + 1.52 +bool SkOSMenu::handleKeyEquivalent(SkUnichar key) { 1.53 + int value = 0, size = 0; 1.54 + bool state; 1.55 + SkOSMenu::TriState tristate; 1.56 + for (int i = 0; i < fItems.count(); ++i) { 1.57 + Item* item = fItems[i]; 1.58 + if (item->getKeyEquivalent()== key) { 1.59 + SkString list; 1.60 + switch (item->getType()) { 1.61 + case kList_Type: 1.62 + SkOSMenu::FindListItemCount(*item->getEvent(), &size); 1.63 + SkOSMenu::FindListIndex(*item->getEvent(), item->getSlotName(), &value); 1.64 + value = (value + 1) % size; 1.65 + item->setInt(value); 1.66 + break; 1.67 + case kSwitch_Type: 1.68 + SkOSMenu::FindSwitchState(*item->getEvent(), item->getSlotName(), &state); 1.69 + item->setBool(!state); 1.70 + break; 1.71 + case kTriState_Type: 1.72 + SkOSMenu::FindTriState(*item->getEvent(), item->getSlotName(), &tristate); 1.73 + if (kOnState == tristate) 1.74 + tristate = kMixedState; 1.75 + else 1.76 + tristate = (SkOSMenu::TriState)((int)tristate + 1); 1.77 + item->setTriState(tristate); 1.78 + break; 1.79 + case kAction_Type: 1.80 + case kCustom_Type: 1.81 + case kSlider_Type: 1.82 + case kTextField_Type: 1.83 + default: 1.84 + break; 1.85 + } 1.86 + item->postEvent(); 1.87 + return true; 1.88 + } 1.89 + } 1.90 + return false; 1.91 +} 1.92 + 1.93 +//////////////////////////////////////////////////////////////////////////////// 1.94 + 1.95 +SkOSMenu::Item::Item(const char label[], SkOSMenu::Type type, 1.96 + const char slotName[], SkEvent* evt) { 1.97 + fLabel.set(label); 1.98 + fSlotName.set(slotName); 1.99 + fType = type; 1.100 + fEvent = evt; 1.101 + fKey = 0; 1.102 + fID = sk_atomic_inc(&gOSMenuCmd); 1.103 +} 1.104 + 1.105 +void SkOSMenu::Item::setBool(bool value) const { 1.106 + SkASSERT(SkOSMenu::kSwitch_Type == fType); 1.107 + fEvent->setBool(fSlotName.c_str(), value); 1.108 +} 1.109 + 1.110 +void SkOSMenu::Item::setScalar(SkScalar value) const { 1.111 + SkASSERT(SkOSMenu::kSlider_Type == fType); 1.112 + fEvent->setScalar(fSlotName.c_str(), value); 1.113 +} 1.114 + 1.115 +void SkOSMenu::Item::setInt(int value) const { 1.116 + SkASSERT(SkOSMenu::kList_Type == fType); 1.117 + fEvent->setS32(fSlotName.c_str(), value); 1.118 +} 1.119 + 1.120 +void SkOSMenu::Item::setTriState(TriState value) const { 1.121 + SkASSERT(SkOSMenu::kTriState_Type == fType); 1.122 + fEvent->setS32(fSlotName.c_str(), value); 1.123 +} 1.124 + 1.125 +void SkOSMenu::Item::setString(const char value[]) const { 1.126 + SkASSERT(SkOSMenu::kTextField_Type == fType); 1.127 + fEvent->setString(fSlotName.c_str(), value); 1.128 +} 1.129 + 1.130 +//////////////////////////////////////////////////////////////////////////////// 1.131 + 1.132 +static const char* gMenuEventType = "SkOSMenuEventType"; 1.133 +static const char* gSlider_Min_Scalar = "SkOSMenuSlider_Min"; 1.134 +static const char* gSlider_Max_Scalar = "SkOSMenuSlider_Max"; 1.135 +static const char* gDelimiter = "|"; 1.136 +static const char* gList_Items_Str = "SkOSMenuList_Items"; 1.137 +static const char* gList_ItemCount_S32 = "SkOSMenuList_ItemCount"; 1.138 + 1.139 +int SkOSMenu::appendItem(const char label[], Type type, const char slotName[], 1.140 + SkEvent* evt) { 1.141 + SkOSMenu::Item* item = new Item(label, type, slotName, evt); 1.142 + fItems.append(1, &item); 1.143 + return item->getID(); 1.144 +} 1.145 + 1.146 +int SkOSMenu::appendAction(const char label[], SkEventSinkID target) { 1.147 + SkEvent* evt = new SkEvent(gMenuEventType, target); 1.148 + //Store label in event so it can be used to identify the action later 1.149 + evt->setString(label, label); 1.150 + return appendItem(label, SkOSMenu::kAction_Type, "", evt); 1.151 +} 1.152 + 1.153 +int SkOSMenu::appendList(const char label[], const char slotName[], 1.154 + SkEventSinkID target, int index, const char option[], ...) { 1.155 + SkEvent* evt = new SkEvent(gMenuEventType, target); 1.156 + va_list args; 1.157 + if (option) { 1.158 + SkString str(option); 1.159 + va_start(args, option); 1.160 + int count = 1; 1.161 + for (const char* arg = va_arg(args, const char*); arg != NULL; arg = va_arg(args, const char*)) { 1.162 + str += gDelimiter; 1.163 + str += arg; 1.164 + ++count; 1.165 + } 1.166 + va_end(args); 1.167 + evt->setString(gList_Items_Str, str); 1.168 + evt->setS32(gList_ItemCount_S32, count); 1.169 + evt->setS32(slotName, index); 1.170 + } 1.171 + return appendItem(label, SkOSMenu::kList_Type, slotName, evt); 1.172 +} 1.173 + 1.174 +int SkOSMenu::appendSlider(const char label[], const char slotName[], 1.175 + SkEventSinkID target, SkScalar min, SkScalar max, 1.176 + SkScalar defaultValue) { 1.177 + SkEvent* evt = new SkEvent(gMenuEventType, target); 1.178 + evt->setScalar(gSlider_Min_Scalar, min); 1.179 + evt->setScalar(gSlider_Max_Scalar, max); 1.180 + evt->setScalar(slotName, defaultValue); 1.181 + return appendItem(label, SkOSMenu::kSlider_Type, slotName, evt); 1.182 +} 1.183 + 1.184 +int SkOSMenu::appendSwitch(const char label[], const char slotName[], 1.185 + SkEventSinkID target, bool defaultState) { 1.186 + SkEvent* evt = new SkEvent(gMenuEventType, target); 1.187 + evt->setBool(slotName, defaultState); 1.188 + return appendItem(label, SkOSMenu::kSwitch_Type, slotName, evt); 1.189 +} 1.190 + 1.191 +int SkOSMenu::appendTriState(const char label[], const char slotName[], 1.192 + SkEventSinkID target, SkOSMenu::TriState defaultState) { 1.193 + SkEvent* evt = new SkEvent(gMenuEventType, target); 1.194 + evt->setS32(slotName, defaultState); 1.195 + return appendItem(label, SkOSMenu::kTriState_Type, slotName, evt); 1.196 +} 1.197 + 1.198 +int SkOSMenu::appendTextField(const char label[], const char slotName[], 1.199 + SkEventSinkID target, const char placeholder[]) { 1.200 + SkEvent* evt = new SkEvent(gMenuEventType, target); 1.201 + evt->setString(slotName, placeholder); 1.202 + return appendItem(label, SkOSMenu::kTextField_Type, slotName, evt); 1.203 +} 1.204 + 1.205 +bool SkOSMenu::FindListItemCount(const SkEvent& evt, int* count) { 1.206 + return evt.isType(gMenuEventType) && evt.findS32(gList_ItemCount_S32, count); 1.207 +} 1.208 + 1.209 +bool SkOSMenu::FindListItems(const SkEvent& evt, SkString items[]) { 1.210 + if (evt.isType(gMenuEventType) && NULL != items) { 1.211 + const char* text = evt.findString(gList_Items_Str); 1.212 + if (text != NULL) { 1.213 + SkString temp(text); 1.214 + char* token = strtok((char*)temp.c_str(), gDelimiter); 1.215 + int index = 0; 1.216 + while (token != NULL) { 1.217 + items[index].set(token, strlen(token)); 1.218 + token = strtok (NULL, gDelimiter); 1.219 + ++index; 1.220 + } 1.221 + } 1.222 + return true; 1.223 + } 1.224 + return false; 1.225 +} 1.226 + 1.227 +bool SkOSMenu::FindSliderMin(const SkEvent& evt, SkScalar* min) { 1.228 + return evt.isType(gMenuEventType) && evt.findScalar(gSlider_Min_Scalar, min); 1.229 +} 1.230 + 1.231 +bool SkOSMenu::FindSliderMax(const SkEvent& evt, SkScalar* max) { 1.232 + return evt.isType(gMenuEventType) && evt.findScalar(gSlider_Max_Scalar, max); 1.233 +} 1.234 + 1.235 +bool SkOSMenu::FindAction(const SkEvent& evt, const char label[]) { 1.236 + return evt.isType(gMenuEventType) && evt.findString(label); 1.237 +} 1.238 + 1.239 +bool SkOSMenu::FindListIndex(const SkEvent& evt, const char slotName[], int* value) { 1.240 + return evt.isType(gMenuEventType) && evt.findS32(slotName, value); 1.241 +} 1.242 + 1.243 +bool SkOSMenu::FindSliderValue(const SkEvent& evt, const char slotName[], SkScalar* value) { 1.244 + return evt.isType(gMenuEventType) && evt.findScalar(slotName, value); 1.245 +} 1.246 + 1.247 +bool SkOSMenu::FindSwitchState(const SkEvent& evt, const char slotName[], bool* value) { 1.248 + return evt.isType(gMenuEventType) && evt.findBool(slotName, value); 1.249 +} 1.250 + 1.251 +bool SkOSMenu::FindTriState(const SkEvent& evt, const char slotName[], SkOSMenu::TriState* value) { 1.252 + return evt.isType(gMenuEventType) && evt.findS32(slotName, (int*)value); 1.253 +} 1.254 + 1.255 +bool SkOSMenu::FindText(const SkEvent& evt, const char slotName[], SkString* value) { 1.256 + if (evt.isType(gMenuEventType)) { 1.257 + const char* text = evt.findString(slotName); 1.258 + if (!text || !*text) 1.259 + return false; 1.260 + else { 1.261 + value->set(text); 1.262 + return true; 1.263 + } 1.264 + } 1.265 + return false; 1.266 +}