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
28class Controller;
29class DrawingContext;
30class ItemAction;
31class ItemBack;
32class ItemBadguySelect;
33class ItemColor;
34class ItemColorChannel;
35class ItemColorDisplay;
36class ItemControlField;
37class ItemFile;
38class ItemGoTo;
39class ItemHorizontalLine;
40class ItemInactive;
41class ItemIntField;
42class ItemLabel;
43class ItemFloatField;
44class ItemScript;
45class ItemScriptLine;
46class ItemStringSelect;
47class ItemTextField;
48class ItemToggle;
49class MenuItem;
50
51class Menu
52{
53public:
54 Menu();
55 virtual ~Menu();
56
57 virtual void menu_action(MenuItem& item) = 0;
58
59 /** Executed before the menu is exited
60 @return true if it should perform the back action, false if it shouldn't */
61 virtual bool on_back_action() { return true; }
62
63 /** Perform actions to bring the menu up to date with configuration changes */
64 virtual void refresh() {}
65
66 virtual void on_window_resize();
67
68 ItemHorizontalLine& add_hl();
69 ItemLabel& add_label(const std::string& text);
70 ItemAction& add_entry(int id, const std::string& text);
71 ItemAction& add_entry(const std::string& text, std::function<void()> callback);
72 ItemToggle& add_toggle(int id, const std::string& text, bool* toggled);
73 ItemToggle& add_toggle(int id, const std::string& text,
74 std::function<bool()> get_func,
75 std::function<void(bool)> set_func);
76 ItemInactive& add_inactive(const std::string& text);
77 ItemBack& add_back(const std::string& text, int id = -1);
78 ItemGoTo& add_submenu(const std::string& text, int submenu, int id = -1);
79 ItemControlField& add_controlfield(int id, const std::string& text, const std::string& mapping = "");
80 ItemStringSelect& add_string_select(int id, const std::string& text, int* selected, const std::vector<std::string>& strings);
81 ItemTextField& add_textfield(const std::string& text, std::string* input, int id = -1);
82 ItemScript& add_script(const std::string& text, std::string* script, int id = -1);
83 ItemScriptLine& add_script_line(std::string* input, int id = -1);
84 ItemIntField& add_intfield(const std::string& text, int* input, int id = -1);
85 ItemFloatField& add_floatfield(const std::string& text, float* input, int id = -1);
86 ItemBadguySelect& add_badguy_select(const std::string& text, std::vector<std::string>* badguys, int id = -1);
87 ItemFile& add_file(const std::string& text, std::string* input, const std::vector<std::string>& extensions,
88 const std::string& basedir, int id = -1);
89
90 ItemColor& add_color(const std::string& text, Color* color, int id = -1);
91 ItemColorDisplay& add_color_display(Color* color, int id = -1);
92 ItemColorChannel& add_color_channel(float* input, Color channel, int id = -1,
93 bool is_linear = false);
94
95 void process_input(const Controller& controller);
96
97 /** Remove all entries from the menu */
98 void clear();
99
100 MenuItem& get_item(int index) { return *(m_items[index]); }
101
102 MenuItem& get_item_by_id(int id);
103 const MenuItem& get_item_by_id(int id) const;
104
105 int get_active_item_id() const;
106 void set_active_item(int id);
107
108 void draw(DrawingContext& context);
109 Vector get_center_pos() const { return m_pos; }
110 void set_center_pos(float x, float y);
111
112 void event(const SDL_Event& event);
113
114 float get_width() const;
115 float get_height() const;
116
117protected:
118 /** returns true when the text is more important than action */
119 virtual bool is_sensitive() const;
120
121 MenuItem& add_item(std::unique_ptr<MenuItem> menu_item);
122 MenuItem& add_item(std::unique_ptr<MenuItem> menu_item, int pos_);
123 void delete_item(int pos_);
124
125private:
126 void process_action(const MenuAction& menuaction);
127 void check_controlfield_change_event(const SDL_Event& event);
128 void draw_item(DrawingContext& context, int index);
129 /** Recalculates the width for this menu */
130 void calculate_width();
131
132private:
133 /** position of the menu (ie. center of the menu, not top/left) */
134 Vector m_pos;
135
136 /* input implementation variables */
137 int m_delete_character;
138 char m_mn_input_char;
139 float m_menu_repeat_time;
140 float m_menu_width;
141
142public:
143 std::vector<std::unique_ptr<MenuItem> > m_items;
144
145private:
146 int m_arrange_left;
147
148protected:
149 int m_active_item;
150
151private:
152 Menu(const Menu&) = delete;
153 Menu& operator=(const Menu&) = delete;
154};
155
156#endif
157
158/* EOF */
159