1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef HEADER_SUPERTUX_GUI_MENU_HPP
18 #define HEADER_SUPERTUX_GUI_MENU_HPP
19 
20 #include <functional>
21 #include <memory>
22 #include <SDL.h>
23 
24 #include "gui/menu_action.hpp"
25 #include "math/vector.hpp"
26 #include "video/color.hpp"
27 
28 class Controller;
29 class DrawingContext;
30 class ItemAction;
31 class ItemBack;
32 class ItemBadguySelect;
33 class ItemColor;
34 class ItemColorChannelRGBA;
35 class ItemColorChannelOKLab;
36 class ItemColorDisplay;
37 class ItemControlField;
38 class ItemFile;
39 class ItemFloatField;
40 class ItemGoTo;
41 class ItemHorizontalLine;
42 class ItemInactive;
43 class ItemIntField;
44 class ItemLabel;
45 class ItemPaths;
46 class ItemScript;
47 class ItemScriptLine;
48 class ItemStringSelect;
49 class ItemTextField;
50 class ItemToggle;
51 class MenuItem;
52 class PathObject;
53 
54 class Menu
55 {
56 public:
57   Menu();
58   virtual ~Menu();
59 
60   virtual void menu_action(MenuItem& item) = 0;
61 
62   /** Executed before the menu is exited
63       @return true if it should perform the back action, false if it shouldn't */
on_back_action()64   virtual bool on_back_action() { return true; }
65 
66   /** Perform actions to bring the menu up to date with configuration changes */
refresh()67   virtual void refresh() {}
68 
69   virtual void on_window_resize();
70 
71   ItemHorizontalLine& add_hl();
72   ItemLabel& add_label(const std::string& text);
73   ItemAction& add_entry(int id, const std::string& text);
74   ItemAction& add_entry(const std::string& text, const std::function<void()>& callback);
75   ItemToggle& add_toggle(int id, const std::string& text, bool* toggled);
76   ItemToggle& add_toggle(int id, const std::string& text,
77                          const std::function<bool()>& get_func,
78                          const std::function<void(bool)>& set_func);
79   ItemInactive& add_inactive(const std::string& text);
80   ItemBack& add_back(const std::string& text, int id = -1);
81   ItemGoTo& add_submenu(const std::string& text, int submenu, int id = -1);
82   ItemControlField& add_controlfield(int id, const std::string& text, const std::string& mapping = "");
83   ItemStringSelect& add_string_select(int id, const std::string& text, int* selected, const std::vector<std::string>& strings);
84   ItemTextField& add_textfield(const std::string& text, std::string* input, int id = -1);
85   ItemScript& add_script(const std::string& text, std::string* script, int id = -1);
86   ItemScriptLine& add_script_line(std::string* input, int id = -1);
87   ItemIntField& add_intfield(const std::string& text, int* input, int id = -1);
88   ItemFloatField& add_floatfield(const std::string& text, float* input, int id = -1);
89   ItemBadguySelect& add_badguy_select(const std::string& text, std::vector<std::string>* badguys, int id = -1);
90   ItemFile& add_file(const std::string& text, std::string* input, const std::vector<std::string>& extensions,
91                      const std::string& basedir, int id = -1);
92 
93   ItemColor& add_color(const std::string& text, Color* color, int id = -1);
94   ItemColorDisplay& add_color_display(Color* color, int id = -1);
95   ItemColorChannelRGBA& add_color_channel_rgba(float* input, Color channel, int id = -1,
96     bool is_linear = false);
97   ItemColorChannelOKLab& add_color_channel_oklab(Color* color, int channel);
98   ItemPaths& add_path_settings(const std::string& text, PathObject& target, const std::string& path_ref);
99 
100   void process_input(const Controller& controller);
101 
102   /** Remove all entries from the menu */
103   void clear();
104 
get_item(int index)105   MenuItem& get_item(int index) { return *(m_items[index]); }
106 
107   MenuItem& get_item_by_id(int id);
108   const MenuItem& get_item_by_id(int id) const;
109 
110   int get_active_item_id() const;
111   void set_active_item(int id);
112 
113   void draw(DrawingContext& context);
get_center_pos() const114   Vector get_center_pos() const { return m_pos; }
115   void set_center_pos(float x, float y);
116 
117   void event(const SDL_Event& event);
118 
119   float get_width() const;
120   float get_height() const;
121 
122 protected:
123   /** returns true when the text is more important than action */
124   virtual bool is_sensitive() const;
125 
126   MenuItem& add_item(std::unique_ptr<MenuItem> menu_item);
127   MenuItem& add_item(std::unique_ptr<MenuItem> menu_item, int pos_);
128   void delete_item(int pos_);
129 
130 private:
131   void process_action(const MenuAction& menuaction);
132   void check_controlfield_change_event(const SDL_Event& event);
133   void draw_item(DrawingContext& context, int index);
134   /** Recalculates the width for this menu */
135   void calculate_width();
136 
137 private:
138   /** position of the menu (ie. center of the menu, not top/left) */
139   Vector m_pos;
140 
141   /* input implementation variables */
142   int m_delete_character;
143   char m_mn_input_char;
144   float m_menu_repeat_time;
145   float m_menu_width;
146 
147 public:
148   std::vector<std::unique_ptr<MenuItem> > m_items;
149 
150 private:
151   int m_arrange_left;
152 
153 protected:
154   int m_active_item;
155 
156 private:
157   Menu(const Menu&) = delete;
158   Menu& operator=(const Menu&) = delete;
159 };
160 
161 #endif
162 
163 /* EOF */
164