1 /*
2    Copyright (C) 2008 - 2018 by Mark de Wever <koraq@xs4all.nl>
3    Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY.
11 
12    See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include "gui/widgets/styled_widget.hpp"
18 
19 #include "gui/core/widget_definition.hpp"
20 #include "gui/core/window_builder.hpp"
21 
22 namespace gui2
23 {
24 namespace implementation
25 {
26 	struct builder_label;
27 }
28 
29 // ------------ WIDGET -----------{
30 
31 /** Label showing a text. */
32 class label : public styled_widget
33 {
34 	friend struct implementation::builder_label;
35 
36 public:
37 	explicit label(const implementation::builder_label& builder);
38 
39 	/** See @ref widget::can_wrap. */
40 	virtual bool can_wrap() const override;
41 
42 	/** See @ref styled_widget::get_characters_per_line. */
43 	virtual unsigned get_characters_per_line() const override;
44 
45 	/** See @ref styled_widget::get_link_aware. */
46 	virtual bool get_link_aware() const override;
47 
48 	/** See @ref styled_widget::get_link_aware. */
49 	virtual color_t get_link_color() const override;
50 
51 	/** See @ref styled_widget::set_active. */
52 	virtual void set_active(const bool active) override;
53 
54 	/** See @ref styled_widget::get_active. */
55 	virtual bool get_active() const override;
56 
57 	/** See @ref styled_widget::get_state. */
58 	virtual unsigned get_state() const override;
59 
60 	/** See @ref widget::disable_click_dismiss. */
61 	bool disable_click_dismiss() const override;
62 
63 	/***** ***** ***** setters / getters for members ***** ****** *****/
64 
set_can_wrap(const bool wrap)65 	void set_can_wrap(const bool wrap)
66 	{
67 		can_wrap_ = wrap;
68 	}
69 
70 	void set_characters_per_line(const unsigned set_characters_per_line);
71 
72 	void set_link_aware(bool l);
73 
74 	void set_link_color(const color_t& color);
75 
can_mouse_focus() const76 	virtual bool can_mouse_focus() const override { return !tooltip().empty(); }
77 
set_can_shrink(bool can_shrink)78 	void set_can_shrink(bool can_shrink)
79 	{
80 		can_shrink_ = can_shrink;
81 	}
82 
83 	void set_text_alpha(unsigned short alpha);
84 
85 private:
86 	/**
87 	 * Possible states of the widget.
88 	 *
89 	 * Note the order of the states must be the same as defined in settings.hpp.
90 	 */
91 	enum state_t {
92 		ENABLED,
93 		DISABLED,
94 	};
95 
96 	void set_state(const state_t state);
97 
98 	/**
99 	 * Current state of the widget.
100 	 *
101 	 * The state of the widget determines what to render and how the widget
102 	 * reacts to certain 'events'.
103 	 */
104 	state_t state_;
105 
106 	/** Holds the label can wrap or not. */
107 	bool can_wrap_;
108 
109 	/**
110 	 * The maximum number of characters per line.
111 	 *
112 	 * The maximum is not an exact maximum, it uses the average character width.
113 	 */
114 	unsigned characters_per_line_;
115 
116 	/**
117 	 * Whether the label is link aware, rendering links with special formatting
118 	 * and handling click events.
119 	 */
120 	bool link_aware_;
121 
122 	/**
123 	 * What color links will be rendered in.
124 	 */
125 	color_t link_color_;
126 
127 	bool can_shrink_;
128 
129 	unsigned short text_alpha_;
130 
131 	/** Inherited from styled_widget. */
text_can_shrink()132 	virtual bool text_can_shrink() override
133 	{
134 		return can_shrink_;
135 	}
136 
137 public:
138 	/** Static type getter that does not rely on the widget being constructed. */
139 	static const std::string& type();
140 
141 private:
142 	/** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
143 	virtual const std::string& get_control_type() const override;
144 
145 	/***** ***** ***** signal handlers ***** ****** *****/
146 
147 	/**
148 	 * Left click signal handler: checks if we clicked on a hyperlink
149 	 */
150 	void signal_handler_left_button_click(const event::ui_event event, bool & handled);
151 
152 	/**
153 	 * Right click signal handler: checks if we clicked on a hyperlink, copied to clipboard
154 	 */
155 	void signal_handler_right_button_click(const event::ui_event event, bool & handled);
156 };
157 
158 // }---------- DEFINITION ---------{
159 
160 struct label_definition : public styled_widget_definition
161 {
162 
163 	explicit label_definition(const config& cfg);
164 
165 	struct resolution : public resolution_definition
166 	{
167 		explicit resolution(const config& cfg);
168 
169 		bool link_aware;
170 		color_t link_color;
171 	};
172 };
173 
174 // }---------- BUILDER -----------{
175 
176 namespace implementation
177 {
178 
179 struct builder_label : public builder_styled_widget
180 {
181 	builder_label(const config& cfg);
182 
183 	using builder_styled_widget::build;
184 
185 	widget* build() const;
186 
187 	bool wrap;
188 
189 	unsigned characters_per_line;
190 
191 	PangoAlignment text_alignment;
192 
193 	bool can_shrink;
194 };
195 
196 } // namespace implementation
197 
198 // }------------ END --------------
199 
200 } // namespace gui2
201