1 /*
2  * Copyright (C) 2002-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (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, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #ifndef WL_UI_BASIC_SLIDER_H
20 #define WL_UI_BASIC_SLIDER_H
21 
22 #include "graphic/styles/text_panel_style.h"
23 #include "ui_basic/panel.h"
24 
25 namespace UI {
26 
27 struct DiscreteSlider;
28 
29 /**
30  * \brief This class defines a generic slide bar.
31  *
32  * The callbacks for the slider value are done by two signal instances.
33  */
34 class Slider : public Panel {
35 
36 	friend struct DiscreteSlider;
37 
38 protected:
39 	/**
40 	 * Text conventions: Sentence case for the 'tooltip_text'
41 	 */
42 	Slider(Panel* parent,
43 	       int32_t x,
44 	       int32_t y,
45 	       uint32_t w,
46 	       uint32_t h,
47 	       int32_t min_value,
48 	       int32_t max_value,
49 	       int32_t value,
50 	       UI::SliderStyle style,
51 	       const std::string& tooltip_text,
52 	       uint32_t cursor_size,
53 	       bool enabled,
54 	       int32_t x_gap,
55 	       int32_t y_gap,
56 	       int32_t bar_size);
57 
58 public:
is_snap_target()59 	bool is_snap_target() const override {
60 		return true;
61 	}
62 
get_value()63 	int32_t get_value() const {
64 		return value_;
65 	}
get_max_value()66 	int32_t get_max_value() const {
67 		return max_value_;
68 	}
get_min_value()69 	int32_t get_min_value() const {
70 		return min_value_;
71 	}
72 
73 	void set_value(int32_t);
74 	void set_max_value(int32_t);
75 	void set_min_value(int32_t);
76 
77 	void set_enabled(bool enabled);
78 
79 protected:
80 	void layout() override;
81 	void calculate_cursor_position();
82 
83 	//  drawing
get_x_gap()84 	int32_t get_x_gap() const {
85 		return x_gap_;
86 	}
get_y_gap()87 	int32_t get_y_gap() const {
88 		return y_gap_;
89 	}
get_bar_size()90 	int32_t get_bar_size() const {
91 		return bar_size_;
92 	}
93 	void draw_cursor(RenderTarget&, int32_t x, int32_t y, int32_t w, int32_t h);
94 
95 	//  mouse events
96 	bool handle_mouserelease(uint8_t btn, int32_t, int32_t) override;
97 	void handle_mousein(bool inside) override;
98 	void cursor_moved(int32_t pointer, int32_t x, int32_t y);
99 	void cursor_pressed(int32_t pointer);
100 	void bar_pressed(int32_t pointer, int32_t ofs);
101 
102 private:
103 	void send_value_changed();
104 	void set_highlighted(bool highlighted);
105 
106 public:
107 	boost::signals2::signal<void()> changed;
108 	boost::signals2::signal<void(int32_t)> changedto;
109 
110 private:
111 	int32_t min_value_;  //  cursor values
112 	int32_t max_value_;
113 	int32_t value_;
114 	int32_t relative_move_;
115 
116 	bool highlighted_;  //  mouse over
117 	bool pressed_;      //  the cursor is pressed
118 	bool enabled_;      //  enabled widget
119 
120 	const UI::PanelStyleInfo* cursor_style_;  // Cursor color and texture. Not owned.
121 
122 protected:
123 	int32_t x_gap_;  //  draw positions
124 	int32_t y_gap_;
125 	int32_t bar_size_;
126 
127 	int32_t cursor_pos_;   //  cursor position
128 	int32_t cursor_size_;  //  cursor width
129 };
130 
131 /**
132  * \brief This class defines an horizontal slide bar.
133  */
134 struct HorizontalSlider : public Slider {
135 	HorizontalSlider(Panel* const parent,
136 	                 const int32_t x,
137 	                 const int32_t y,
138 	                 const uint32_t w,
139 	                 const uint32_t h,
140 	                 const int32_t min_value,
141 	                 const int32_t max_value,
142 	                 const int32_t value,
143 	                 UI::SliderStyle style,
144 	                 const std::string& tooltip_text = std::string(),
145 	                 const uint32_t cursor_size = 20,
146 	                 const bool enabled = true)
147 	   : Slider(parent,
148 	            x,
149 	            y,
150 	            w,
151 	            h,
152 	            min_value,
153 	            max_value,
154 	            value,
155 	            style,
156 	            tooltip_text,
157 	            cursor_size,
158 	            enabled,
159 	            cursor_size / 2,
160 	            h / 2 - 2,
161 	            w - cursor_size) {
162 	}
163 
164 protected:
165 	void draw(RenderTarget& dst) override;
166 	bool handle_mousemove(uint8_t btn, int32_t x, int32_t y, int32_t, int32_t) override;
167 	bool handle_mousepress(uint8_t btn, int32_t x, int32_t y) override;
168 	void layout() override;
169 };
170 
171 /**
172  * \brief This class defines a verical slide bar.
173  */
174 struct VerticalSlider : public Slider {
175 	VerticalSlider(Panel* const parent,
176 	               const int32_t x,
177 	               const int32_t y,
178 	               const uint32_t w,
179 	               const uint32_t h,
180 	               const int32_t min_value,
181 	               const int32_t max_value,
182 	               const int32_t value,
183 	               UI::SliderStyle style,
184 	               const uint32_t cursor_size = 20,
185 	               const std::string& tooltip_text = std::string(),
186 	               const bool enabled = true)
187 	   : Slider(parent,
188 	            x,
189 	            y,
190 	            w,
191 	            h,
192 	            min_value,
193 	            max_value,
194 	            value,
195 	            style,
196 	            tooltip_text,
197 	            cursor_size,
198 	            enabled,
199 	            w / 2 - 2,
200 	            cursor_size / 2,
201 	            h - cursor_size) {
202 	}
203 
204 protected:
205 	void draw(RenderTarget& dst) override;
206 	bool handle_mousemove(uint8_t btn, int32_t x, int32_t y, int32_t, int32_t) override;
207 	bool handle_mousepress(uint8_t btn, int32_t x, int32_t y) override;
208 	void layout() override;
209 };
210 
211 /**
212  * \brief This class defines an discrete slide bar. We do not derive from
213  * Slider, but rather embed it, as we need to re-size it and add the labels.
214  */
215 struct DiscreteSlider : public Panel {
216 	DiscreteSlider(Panel* const parent,
217 	               const int32_t x,
218 	               const int32_t y,
219 	               const uint32_t w,
220 	               const uint32_t h,
221 	               const std::vector<std::string>& labels_in,
222 	               uint32_t value_,
223 	               UI::SliderStyle style,
224 	               const std::string& tooltip_text = std::string(),
225 	               const uint32_t cursor_size = 20,
226 	               const bool enabled = true);
227 
228 	void set_labels(std::vector<std::string>);
229 
230 	boost::signals2::signal<void()> changed;
231 	boost::signals2::signal<void(int32_t)> changedto;
232 
233 protected:
234 	void draw(RenderTarget& dst) override;
235 	void layout() override;
236 
237 private:
238 	// We need the style to initialize the slider, so it has to come first.
239 	const UI::TextPanelStyleInfo& style;
240 
241 protected:
242 	HorizontalSlider slider;
243 
244 private:
245 	std::vector<std::string> labels;
246 };
247 }  // namespace UI
248 
249 #endif  // end of include guard: WL_UI_BASIC_SLIDER_H
250