summaryrefslogtreecommitdiffstats
path: root/client/menu.h
blob: 809e798f03dba925f439b96a8ef6955799ad4415 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
   Copyright (C) 2009 Red Hat, Inc.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _H_MENU
#define _H_MENU

class CommandTarget {
public:
    virtual void do_command(int command) = 0;
    virtual ~CommandTarget() {}
};

class Menu {
public:
    Menu(CommandTarget& target, const std::string& name);

    enum ItemType {
        MENU_ITEM_TYPE_INVALID,
        MENU_ITEM_TYPE_COMMAND,
        MENU_ITEM_TYPE_MENU,
        MENU_ITEM_TYPE_SEPARATOR,
    };

    enum ItemState {
        MENU_ITEM_STATE_CHECKED = 1 << 0,
        MENU_ITEM_STATE_DIM     = 1 << 1,
    };

    Menu* ref() { _refs++; return this;}
    void unref() { if (!--_refs) delete this;}

    void set_name(const std::string& name) { _name = name;}
    const std::string& get_name() { return _name;}
    CommandTarget& get_target() { return _target;}

    void add_command(const std::string& name, int cmd_id, int state = 0);
    void add_separator();
    void add_sub(Menu* sub);

    void remove_command(int cmd_id);
    void remove_sub(Menu* menu);

    ItemType item_type_at(int pos);
    void command_at(int pos, std::string& name, int& cmd_id, int& state);
    Menu* sub_at(int pos);

    void clear();

private:
    virtual ~Menu();

    class MenuCommand {
    public:
        MenuCommand(const std::string& name, int cmd_id, int state)
            : _name (name)
            , _cmd_id (cmd_id)
            , _state (state)
        {
        }

        const std::string& get_name() { return _name;}
        int get_cmd_id() { return _cmd_id;}
        int get_state() { return _state;}

    private:
        std::string _name;
        int _cmd_id;
        int _state;
    };

    struct MenuItem {
        ItemType type;
        void *obj;
    };

    void add_item(MenuItem& item);

private:
    int _refs;
    CommandTarget& _target;
    std::string _name;
    std::vector<MenuItem> _items;
};

#endif