1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkOSMenu_DEFINED
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkOSMenu_DEFINED
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkEvent.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTDArray.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkOSMenu {
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
18654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    explicit SkOSMenu(const char title[] = "");
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ~SkOSMenu();
20fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
21654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    /**
22fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * Each of these (except action) has an associated value, which is stored in
23654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     * the event payload for the item.
24654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     * Each type has a specific type for its value...
25654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     *     Action : none
26654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     *     List : int (selected index)
27654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     *     Segmented : int (selected index)
28654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     *     Slider : float
29654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     *     Switch : bool
30654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     *     TextField : string
31654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     *     TriState : TriState
32654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     *     Custom : custom object/value
33654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com     */
34654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    enum Type {
35654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        kAction_Type,
36654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        kList_Type,
37654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        kSlider_Type,
38654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        kSwitch_Type,
39654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        kTriState_Type,
40654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        kTextField_Type,
41654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        kCustom_Type
42654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    };
43fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
44e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    enum TriState {
45e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        kMixedState = -1,
46e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        kOffState = 0,
47e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        kOnState = 1
48e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    };
49fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
50654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    class Item {
51654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    public:
52e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        /**
53e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com         * Auto increments a global to generate an unique ID for each new item
54e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com         * Note: Thread safe
55e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com         */
56fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        Item(const char label[], SkOSMenu::Type type, const char slotName[],
57e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com             SkEvent* evt);
58654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        ~Item() { delete fEvent; }
59fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
60e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        SkEvent*    getEvent() const { return fEvent; }
61e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        int         getID() const { return fID; }
62654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        const char* getLabel() const { return fLabel.c_str(); }
63654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        const char* getSlotName() const { return fSlotName.c_str(); }
64e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        Type        getType() const { return fType; }
65e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        void        setKeyEquivalent(SkUnichar key) { fKey = key; }
66e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        SkUnichar   getKeyEquivalent() const { return fKey; }
67fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
68e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        /**
69ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com         * Helper functions for predefined types
70e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com         */
71ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        void setBool(bool value) const;             //For Switch
72fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        void setScalar(SkScalar value) const;       //For Slider
73ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        void setInt(int value) const;               //For List
74ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        void setTriState(TriState value) const;     //For Tristate
75ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        void setString(const char value[]) const;   //For TextField
76fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
77e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        /**
78fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com         * Post event associated with the menu item to target, any changes to
79ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com         * the associated event must be made prior to calling this method
80e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com         */
81ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        void postEvent() const { (new SkEvent(*(fEvent)))->post(); }
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
83654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    private:
84654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        int             fID;
85654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        SkEvent*        fEvent;
86654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        SkString        fLabel;
87654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        SkString        fSlotName;
88654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com        Type            fType;
89e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com        SkUnichar       fKey;
90654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    };
91fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
92ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    void        reset();
93e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    const char* getTitle() const { return fTitle.c_str(); }
94e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    void        setTitle (const char title[]) { fTitle.set(title); }
95ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    int         getCount() const { return fItems.count(); }
96ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    const Item* getItemByID(int itemID) const;
97ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    void        getItems(const Item* items[]) const;
98fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
99e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    /**
100fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * Assign key to the menu item with itemID, will do nothing if there's no
101e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * item with the id given
102e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     */
103e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    void        assignKeyEquivalentToItem(int itemID, SkUnichar key);
104e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    /**
105fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * Call this in a SkView's onHandleChar to trigger any menu items with the
106fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * given key equivalent. If such an item is found, the method will return
107fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * true and its corresponding event will be triggered (default behavior
108e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * defined for switches(toggling), tristates(cycle), and lists(cycle),
109fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * for anything else, the event attached is posted without state changes)
110e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * If no menu item can be matched with the key, false will be returned
111e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     */
112e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    bool        handleKeyEquivalent(SkUnichar key);
113fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
114e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    /**
115fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * The following functions append new items to the menu and returns their
116fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * associated unique id, which can be used to by the client to refer to
117e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * the menu item created and change its state. slotName specifies the string
118e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * identifier of any state/value to be returned in the item's SkEvent object
119e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * NOTE: evt must be dynamically allocated
120e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     */
121fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    int appendItem(const char label[], Type type, const char slotName[],
122fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com                   SkEvent* evt);
123fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
124e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    /**
125fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * Create predefined items with the given parameters. To be used with the
126e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * other helper functions below to retrive/update state information.
127fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * Note: the helper functions below assume that slotName is UNIQUE for all
128e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * menu items of the same type since it's used to identify the event
129e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     */
130654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    int appendAction(const char label[], SkEventSinkID target);
131fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    int appendList(const char label[], const char slotName[],
132a10742c69ce47d346e3cf23e7be909c9f29b401ecaryclark                   SkEventSinkID target, int defaultIndex, const char* ...);
133fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    int appendSlider(const char label[], const char slotName[],
134fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com                     SkEventSinkID target, SkScalar min, SkScalar max,
135654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com                     SkScalar defaultValue);
136fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    int appendSwitch(const char label[], const char slotName[],
137654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com                     SkEventSinkID target, bool defaultState = false);
138654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    int appendTriState(const char label[], const char slotName[],
139e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com                       SkEventSinkID target, TriState defaultState = kOffState);
140654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    int appendTextField(const char label[], const char slotName[],
141654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com                        SkEventSinkID target, const char placeholder[] = "");
142fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
143fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
144e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    /**
145e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * Helper functions to retrieve information other than the stored value for
146e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * some predefined types
147e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     */
148ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    static bool FindListItemCount(const SkEvent& evt, int* count);
149e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    /**
150fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * Ensure that the items array can store n SkStrings where n is the count
151e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * extracted using FindListItemCount
152e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     */
153ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    static bool FindListItems(const SkEvent& evt, SkString items[]);
154ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    static bool FindSliderMin(const SkEvent& evt, SkScalar* min);
155ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    static bool FindSliderMax(const SkEvent& evt, SkScalar* max);
156fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
157e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    /**
158e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * Returns true if an action with the given label is found, false otherwise
159e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     */
160ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    static bool FindAction(const SkEvent& evt, const char label[]);
161e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com    /**
162fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * The following helper functions will return true if evt is generated from
163fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * a predefined item type and retrieve the corresponding state information.
164fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * They will return false and leave value unchanged if there's a type
165e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     * mismatch or slotName is incorrect
166e55f533f4c80818d542c2beac14a37600c3718f8yangsu@google.com     */
167ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    static bool FindListIndex(const SkEvent& evt, const char slotName[], int* value);
168ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    static bool FindSliderValue(const SkEvent& evt, const char slotName[], SkScalar* value);
169ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    static bool FindSwitchState(const SkEvent& evt, const char slotName[], bool* value);
170ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    static bool FindTriState(const SkEvent& evt, const char slotName[], TriState* value);
171ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    static bool FindText(const SkEvent& evt, const char slotName[], SkString* value);
172fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
174654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    SkString fTitle;
175654d72f94c855ceae34db0ee82d92844835c0d29yangsu@google.com    SkTDArray<Item*> fItems;
176fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // illegal
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkOSMenu(const SkOSMenu&);
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkOSMenu& operator=(const SkOSMenu&);
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
183