Home | History | Annotate | Download | only in views
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkOSMenu_DEFINED
     11 #define SkOSMenu_DEFINED
     12 
     13 #include "SkEvent.h"
     14 #include "SkTDArray.h"
     15 
     16 class SkOSMenu {
     17 public:
     18     explicit SkOSMenu(const char title[] = "");
     19     ~SkOSMenu();
     20 
     21     /**
     22      * Each of these (except action) has an associated value, which is stored in
     23      * the event payload for the item.
     24      * Each type has a specific type for its value...
     25      *     Action : none
     26      *     List : int (selected index)
     27      *     Segmented : int (selected index)
     28      *     Slider : float
     29      *     Switch : bool
     30      *     TextField : string
     31      *     TriState : TriState
     32      *     Custom : custom object/value
     33      */
     34     enum Type {
     35         kAction_Type,
     36         kList_Type,
     37         kSlider_Type,
     38         kSwitch_Type,
     39         kTriState_Type,
     40         kTextField_Type,
     41         kCustom_Type
     42     };
     43 
     44     enum TriState {
     45         kMixedState = -1,
     46         kOffState = 0,
     47         kOnState = 1
     48     };
     49 
     50     class Item {
     51     public:
     52         /**
     53          * Auto increments a global to generate an unique ID for each new item
     54          * Note: Thread safe
     55          */
     56         Item(const char label[], SkOSMenu::Type type, const char slotName[],
     57              SkEvent* evt);
     58         ~Item() { delete fEvent; }
     59 
     60         SkEvent*    getEvent() const { return fEvent; }
     61         int         getID() const { return fID; }
     62         const char* getLabel() const { return fLabel.c_str(); }
     63         const char* getSlotName() const { return fSlotName.c_str(); }
     64         Type        getType() const { return fType; }
     65         void        setKeyEquivalent(SkUnichar key) { fKey = key; }
     66         SkUnichar   getKeyEquivalent() const { return fKey; }
     67 
     68         /**
     69          * Helper functions for predefined types
     70          */
     71         void setBool(bool value) const;             //For Switch
     72         void setScalar(SkScalar value) const;       //For Slider
     73         void setInt(int value) const;               //For List
     74         void setTriState(TriState value) const;     //For Tristate
     75         void setString(const char value[]) const;   //For TextField
     76 
     77         /**
     78          * Post event associated with the menu item to target, any changes to
     79          * the associated event must be made prior to calling this method
     80          */
     81         void postEvent() const { (new SkEvent(*(fEvent)))->post(); }
     82 
     83     private:
     84         int             fID;
     85         SkEvent*        fEvent;
     86         SkString        fLabel;
     87         SkString        fSlotName;
     88         Type            fType;
     89         SkUnichar       fKey;
     90     };
     91 
     92     void        reset();
     93     const char* getTitle() const { return fTitle.c_str(); }
     94     void        setTitle (const char title[]) { fTitle.set(title); }
     95     int         getCount() const { return fItems.count(); }
     96     const Item* getItemByID(int itemID) const;
     97     void        getItems(const Item* items[]) const;
     98 
     99     /**
    100      * Assign key to the menu item with itemID, will do nothing if there's no
    101      * item with the id given
    102      */
    103     void        assignKeyEquivalentToItem(int itemID, SkUnichar key);
    104     /**
    105      * Call this in a SkView's onHandleChar to trigger any menu items with the
    106      * given key equivalent. If such an item is found, the method will return
    107      * true and its corresponding event will be triggered (default behavior
    108      * defined for switches(toggling), tristates(cycle), and lists(cycle),
    109      * for anything else, the event attached is posted without state changes)
    110      * If no menu item can be matched with the key, false will be returned
    111      */
    112     bool        handleKeyEquivalent(SkUnichar key);
    113 
    114     /**
    115      * The following functions append new items to the menu and returns their
    116      * associated unique id, which can be used to by the client to refer to
    117      * the menu item created and change its state. slotName specifies the string
    118      * identifier of any state/value to be returned in the item's SkEvent object
    119      * NOTE: evt must be dynamically allocated
    120      */
    121     int appendItem(const char label[], Type type, const char slotName[],
    122                    SkEvent* evt);
    123 
    124     /**
    125      * Create predefined items with the given parameters. To be used with the
    126      * other helper functions below to retrive/update state information.
    127      * Note: the helper functions below assume that slotName is UNIQUE for all
    128      * menu items of the same type since it's used to identify the event
    129      */
    130     int appendAction(const char label[], SkEventSinkID target);
    131     int appendList(const char label[], const char slotName[],
    132                    SkEventSinkID target, int defaultIndex, const char[] ...);
    133     int appendSlider(const char label[], const char slotName[],
    134                      SkEventSinkID target, SkScalar min, SkScalar max,
    135                      SkScalar defaultValue);
    136     int appendSwitch(const char label[], const char slotName[],
    137                      SkEventSinkID target, bool defaultState = false);
    138     int appendTriState(const char label[], const char slotName[],
    139                        SkEventSinkID target, TriState defaultState = kOffState);
    140     int appendTextField(const char label[], const char slotName[],
    141                         SkEventSinkID target, const char placeholder[] = "");
    142 
    143 
    144     /**
    145      * Helper functions to retrieve information other than the stored value for
    146      * some predefined types
    147      */
    148     static bool FindListItemCount(const SkEvent& evt, int* count);
    149     /**
    150      * Ensure that the items array can store n SkStrings where n is the count
    151      * extracted using FindListItemCount
    152      */
    153     static bool FindListItems(const SkEvent& evt, SkString items[]);
    154     static bool FindSliderMin(const SkEvent& evt, SkScalar* min);
    155     static bool FindSliderMax(const SkEvent& evt, SkScalar* max);
    156 
    157     /**
    158      * Returns true if an action with the given label is found, false otherwise
    159      */
    160     static bool FindAction(const SkEvent& evt, const char label[]);
    161     /**
    162      * The following helper functions will return true if evt is generated from
    163      * a predefined item type and retrieve the corresponding state information.
    164      * They will return false and leave value unchanged if there's a type
    165      * mismatch or slotName is incorrect
    166      */
    167     static bool FindListIndex(const SkEvent& evt, const char slotName[], int* value);
    168     static bool FindSliderValue(const SkEvent& evt, const char slotName[], SkScalar* value);
    169     static bool FindSwitchState(const SkEvent& evt, const char slotName[], bool* value);
    170     static bool FindTriState(const SkEvent& evt, const char slotName[], TriState* value);
    171     static bool FindText(const SkEvent& evt, const char slotName[], SkString* value);
    172 
    173 private:
    174     SkString fTitle;
    175     SkTDArray<Item*> fItems;
    176 
    177     // illegal
    178     SkOSMenu(const SkOSMenu&);
    179     SkOSMenu& operator=(const SkOSMenu&);
    180 };
    181 
    182 #endif
    183