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 
20 #ifndef WL_UI_BASIC_BUTTON_H
21 #define WL_UI_BASIC_BUTTON_H
22 
23 #include "graphic/styles/button_style.h"
24 #include "ui_basic/panel.h"
25 
26 namespace UI {
27 
28 enum class ButtonDisableStyle {
29 	kMonochrome = 2,   // Greyed out. Can be combined with the other 2 styles.
30 	kPermpressed = 4,  // Button will appear pressed.
31 	kFlat = 8,         // Button will appear flat.
32 };
33 inline ButtonDisableStyle operator&(ButtonDisableStyle a, ButtonDisableStyle b) {
34 	return static_cast<ButtonDisableStyle>(static_cast<int>(a) & static_cast<int>(b));
35 }
36 inline ButtonDisableStyle operator|(ButtonDisableStyle a, ButtonDisableStyle b) {
37 	return static_cast<ButtonDisableStyle>(static_cast<int>(a) | static_cast<int>(b));
38 }
39 
40 /// This is simply a button. Override void clicked() to react to the click.
41 /// This is all that is needed in most cases, but if there is a need to give a
42 /// callback function to the button, there are some templates for that below.
43 struct Button : public NamedPanel {
44 	enum class VisualState {
45 		kRaised,       // Normal raised Button
46 		kPermpressed,  // Button will appear pressed
47 		kFlat          // Flat button with simple coloured outline
48 	};
49 
50 	enum class ImageMode {
51 		kShrink,   // Shrink foreground image to fit into the button
52 		kUnscaled  // Show the foreground image without any scaling
53 	};
54 
55 private:
56 	Button  // Common constructor
57 	   (Panel* const parent,
58 	    const std::string& name,
59 	    int32_t const x,
60 	    int32_t const y,
61 	    uint32_t const w,
62 	    uint32_t const h,
63 	    UI::ButtonStyle style,
64 	    const Image* title_image,
65 	    const std::string& title_text,
66 	    const std::string& tooltip_text,
67 	    UI::Button::VisualState state,
68 	    UI::Button::ImageMode mode);
69 
70 public:
71 	/**
72 	 * Text conventions: Title Case for the 'title_text', Sentence case for the 'tooltip_text'
73 	 */
74 	Button  /// for textual buttons
75 	   (Panel* const parent,
76 	    const std::string& name,
77 	    int32_t const x,
78 	    int32_t const y,
79 	    uint32_t const w,
80 	    uint32_t const h,
81 	    UI::ButtonStyle style,
82 	    const std::string& title_text,
83 	    const std::string& tooltip_text = std::string(),
84 	    UI::Button::VisualState state = UI::Button::VisualState::kRaised);
85 
86 	/**
87 	 * Text conventions: Sentence case for the 'tooltip_text'
88 	 */
89 	Button  /// for pictorial buttons
90 	   (Panel* const parent,
91 	    const std::string& name,
92 	    const int32_t x,
93 	    const int32_t y,
94 	    const uint32_t w,
95 	    const uint32_t h,
96 	    UI::ButtonStyle style,
97 	    const Image* title_image,
98 	    const std::string& tooltip_text = std::string(),
99 	    UI::Button::VisualState state = UI::Button::VisualState::kRaised,
100 	    UI::Button::ImageMode mode = UI::Button::ImageMode::kShrink);
101 	~Button() override;
102 
103 	void set_pic(const Image* pic);
104 	void set_title(const std::string&);
get_titleButton105 	const std::string& get_title() const {
106 		return title_;
107 	}
108 
enabledButton109 	bool enabled() const {
110 		return enabled_;
111 	}
112 	void set_enabled(bool on);
set_repeatingButton113 	void set_repeating(bool const on) {
114 		repeating_ = on;
115 	}
is_snap_targetButton116 	bool is_snap_target() const override {
117 		return true;
118 	}
119 
120 	// Drawing and event handlers
121 	void draw(RenderTarget&) override;
122 	void think() override;
123 
124 	void handle_mousein(bool inside) override;
125 	bool handle_mousepress(uint8_t btn, int32_t x, int32_t y) override;
126 	bool handle_mouserelease(uint8_t btn, int32_t x, int32_t y) override;
127 	bool handle_mousemove(uint8_t, int32_t, int32_t, int32_t, int32_t) override;
128 
129 	/// Sets the visual style of the button
130 	void set_visual_state(UI::Button::VisualState state);
styleButton131 	UI::Button::VisualState style() const {
132 		return visual_state_;
133 	}
134 
135 	/// Sets the visual style of the disabled button
136 	void set_disable_style(UI::ButtonDisableStyle input_style);
137 
138 	/// Convenience function. If 'pressed', sets the style to kPermpressed, otherwise to kRaised.
139 	void set_perm_pressed(bool pressed);
140 
141 	/// Change the background style of the button.
142 	void set_style(UI::ButtonStyle bstyle);
143 
144 	/// Convenience function. Toggles between raised and permpressed style
145 	void toggle();
146 
147 	boost::signals2::signal<void()> sigclicked;
148 	boost::signals2::signal<void()> sigmousein;
149 	boost::signals2::signal<void()> sigmouseout;
150 
151 protected:
152 	bool highlighted_;  //  mouse is over the button
153 	bool pressed_;      //  mouse is clicked over the button
154 	bool enabled_;
155 	UI::Button::VisualState visual_state_;
156 	UI::ButtonDisableStyle disable_style_;
157 	bool repeating_;
158 	const UI::Button::ImageMode image_mode_;
159 
160 	uint32_t time_nextact_;
161 
162 	std::string title_;         //  title string used when title_image_ == nullptr
163 	const Image* title_image_;  //  custom icon on the button
164 
165 	const UI::ButtonStyleInfo* style_;  // Background color and texture. Not owned.
166 };
167 
168 }  // namespace UI
169 
170 #endif  // end of include guard: WL_UI_BASIC_BUTTON_H
171