/* * Copyright 2006 The Android Open Source Project * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkOSMenu_DEFINED #define SkOSMenu_DEFINED #include "SkEvent.h" #include "SkTDArray.h" class SkOSMenu { public: explicit SkOSMenu(const char title[] = ""); ~SkOSMenu(); /** * Each of these (except action) has an associated value, which is stored in * the event payload for the item. * Each type has a specific type for its value... * Action : none * List : int (selected index) * Segmented : int (selected index) * Slider : float * Switch : bool * TextField : string * TriState : TriState * Custom : custom object/value */ enum Type { kAction_Type, kList_Type, kSlider_Type, kSwitch_Type, kTriState_Type, kTextField_Type, kCustom_Type }; enum TriState { kMixedState = -1, kOffState = 0, kOnState = 1 }; class Item { public: /** * Auto increments a global to generate an unique ID for each new item * Note: Thread safe */ Item(const char label[], SkOSMenu::Type type, const char slotName[], SkEvent* evt); ~Item() { delete fEvent; } SkEvent* getEvent() const { return fEvent; } int getID() const { return fID; } const char* getLabel() const { return fLabel.c_str(); } const char* getSlotName() const { return fSlotName.c_str(); } Type getType() const { return fType; } void setKeyEquivalent(SkUnichar key) { fKey = key; } SkUnichar getKeyEquivalent() const { return fKey; } /** * Helper functions for predefined types */ void setBool(bool value) const; //For Switch void setScalar(SkScalar value) const; //For Slider void setInt(int value) const; //For List void setTriState(TriState value) const; //For Tristate void setString(const char value[]) const; //For TextField /** * Post event associated with the menu item to target, any changes to * the associated event must be made prior to calling this method */ void postEvent() const { (new SkEvent(*(fEvent)))->post(); } private: int fID; SkEvent* fEvent; SkString fLabel; SkString fSlotName; Type fType; SkUnichar fKey; }; void reset(); const char* getTitle() const { return fTitle.c_str(); } void setTitle (const char title[]) { fTitle.set(title); } int getCount() const { return fItems.count(); } const Item* getItemByID(int itemID) const; void getItems(const Item* items[]) const; /** * Assign key to the menu item with itemID, will do nothing if there's no * item with the id given */ void assignKeyEquivalentToItem(int itemID, SkUnichar key); /** * Call this in a SkView's onHandleChar to trigger any menu items with the * given key equivalent. If such an item is found, the method will return * true and its corresponding event will be triggered (default behavior * defined for switches(toggling), tristates(cycle), and lists(cycle), * for anything else, the event attached is posted without state changes) * If no menu item can be matched with the key, false will be returned */ bool handleKeyEquivalent(SkUnichar key); /** * The following functions append new items to the menu and returns their * associated unique id, which can be used to by the client to refer to * the menu item created and change its state. slotName specifies the string * identifier of any state/value to be returned in the item's SkEvent object * NOTE: evt must be dynamically allocated */ int appendItem(const char label[], Type type, const char slotName[], SkEvent* evt); /** * Create predefined items with the given parameters. To be used with the * other helper functions below to retrive/update state information. * Note: the helper functions below assume that slotName is UNIQUE for all * menu items of the same type since it's used to identify the event */ int appendAction(const char label[], SkEventSinkID target); int appendList(const char label[], const char slotName[], SkEventSinkID target, int defaultIndex, const char[] ...); int appendSlider(const char label[], const char slotName[], SkEventSinkID target, SkScalar min, SkScalar max, SkScalar defaultValue); int appendSwitch(const char label[], const char slotName[], SkEventSinkID target, bool defaultState = false); int appendTriState(const char label[], const char slotName[], SkEventSinkID target, TriState defaultState = kOffState); int appendTextField(const char label[], const char slotName[], SkEventSinkID target, const char placeholder[] = ""); /** * Helper functions to retrieve information other than the stored value for * some predefined types */ static bool FindListItemCount(const SkEvent& evt, int* count); /** * Ensure that the items array can store n SkStrings where n is the count * extracted using FindListItemCount */ static bool FindListItems(const SkEvent& evt, SkString items[]); static bool FindSliderMin(const SkEvent& evt, SkScalar* min); static bool FindSliderMax(const SkEvent& evt, SkScalar* max); /** * Returns true if an action with the given label is found, false otherwise */ static bool FindAction(const SkEvent& evt, const char label[]); /** * The following helper functions will return true if evt is generated from * a predefined item type and retrieve the corresponding state information. * They will return false and leave value unchanged if there's a type * mismatch or slotName is incorrect */ static bool FindListIndex(const SkEvent& evt, const char slotName[], int* value); static bool FindSliderValue(const SkEvent& evt, const char slotName[], SkScalar* value); static bool FindSwitchState(const SkEvent& evt, const char slotName[], bool* value); static bool FindTriState(const SkEvent& evt, const char slotName[], TriState* value); static bool FindText(const SkEvent& evt, const char slotName[], SkString* value); private: SkString fTitle; SkTDArray<Item*> fItems; // illegal SkOSMenu(const SkOSMenu&); SkOSMenu& operator=(const SkOSMenu&); }; #endif