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