1 /*************************************************************************/
2 /*  canvas_item.h                                                        */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 #ifndef CANVAS_ITEM_H
31 #define CANVAS_ITEM_H
32 
33 #include "scene/main/node.h"
34 #include "scene/main/scene_main_loop.h"
35 #include "scene/resources/shader.h"
36 #include "scene/resources/texture.h"
37 
38 class CanvasLayer;
39 class Viewport;
40 class Font;
41 
42 class StyleBox;
43 
44 class CanvasItemMaterial : public Resource {
45 
46 	OBJ_TYPE(CanvasItemMaterial, Resource);
47 	RID material;
48 	Ref<Shader> shader;
49 
50 public:
51 	enum ShadingMode {
52 		SHADING_NORMAL,
53 		SHADING_UNSHADED,
54 		SHADING_ONLY_LIGHT,
55 	};
56 
57 protected:
58 	ShadingMode shading_mode;
59 
60 	bool _set(const StringName &p_name, const Variant &p_value);
61 	bool _get(const StringName &p_name, Variant &r_ret) const;
62 	void _get_property_list(List<PropertyInfo> *p_list) const;
63 
64 	static void _bind_methods();
65 
66 	void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
67 
68 public:
69 	void set_shader(const Ref<Shader> &p_shader);
70 	Ref<Shader> get_shader() const;
71 
72 	void set_shader_param(const StringName &p_param, const Variant &p_value);
73 	Variant get_shader_param(const StringName &p_param) const;
74 
75 	void set_shading_mode(ShadingMode p_mode);
76 	ShadingMode get_shading_mode() const;
77 
78 	virtual RID get_rid() const;
79 	CanvasItemMaterial();
80 	~CanvasItemMaterial();
81 };
82 
83 VARIANT_ENUM_CAST(CanvasItemMaterial::ShadingMode);
84 
85 class CanvasItem : public Node {
86 
87 	OBJ_TYPE(CanvasItem, Node);
88 
89 public:
90 	enum BlendMode {
91 
92 		BLEND_MODE_MIX, //default
93 		BLEND_MODE_ADD,
94 		BLEND_MODE_SUB,
95 		BLEND_MODE_MUL,
96 		BLEND_MODE_PREMULT_ALPHA
97 	};
98 
99 private:
100 	mutable SelfList<Node> xform_change;
101 
102 	RID canvas_item;
103 	String group;
104 
105 	CanvasLayer *canvas_layer;
106 
107 	float opacity;
108 	float self_opacity;
109 
110 	List<CanvasItem *> children_items;
111 	List<CanvasItem *>::Element *C;
112 
113 	BlendMode blend_mode;
114 	int light_mask;
115 
116 	bool first_draw;
117 	bool hidden;
118 	bool pending_update;
119 	bool toplevel;
120 	bool pending_children_sort;
121 	bool drawing;
122 	bool block_transform_notify;
123 	bool behind;
124 	bool use_parent_material;
125 	bool notify_local_transform;
126 
127 	Ref<CanvasItemMaterial> material;
128 
129 	mutable Matrix32 global_transform;
130 	mutable bool global_invalid;
131 
132 	void _raise_self();
133 
134 	void _propagate_visibility_changed(bool p_visible);
135 
136 	void _set_visible_(bool p_visible);
137 	bool _is_visible_() const;
138 
139 	void _update_callback();
140 
141 	void _enter_canvas();
142 	void _exit_canvas();
143 
144 	void _queue_sort_children();
145 	void _sort_children();
146 
147 	void _notify_transform(CanvasItem *p_node);
148 
_set_on_top(bool p_on_top)149 	void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); }
_is_on_top()150 	bool _is_on_top() const { return !is_draw_behind_parent_enabled(); }
151 
152 protected:
_notify_transform()153 	_FORCE_INLINE_ void _notify_transform() {
154 		if (!is_inside_tree()) return;
155 		_notify_transform(this);
156 		if (!block_transform_notify && notify_local_transform) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
157 	}
158 
159 	void item_rect_changed();
160 
161 	void _notification(int p_what);
162 	static void _bind_methods();
163 
164 public:
165 	enum {
166 		NOTIFICATION_TRANSFORM_CHANGED = SceneTree::NOTIFICATION_TRANSFORM_CHANGED, //unique
167 		NOTIFICATION_DRAW = 30,
168 		NOTIFICATION_VISIBILITY_CHANGED = 31,
169 		NOTIFICATION_ENTER_CANVAS = 32,
170 		NOTIFICATION_EXIT_CANVAS = 33,
171 		NOTIFICATION_LOCAL_TRANSFORM_CHANGED = 35,
172 		NOTIFICATION_WORLD_2D_CHANGED = 36,
173 
174 	};
175 
176 	/* EDITOR */
177 
178 	virtual Variant edit_get_state() const;
179 	virtual void edit_set_state(const Variant &p_state);
180 	virtual void edit_set_rect(const Rect2 &p_edit_rect);
181 	virtual void edit_rotate(float p_rot);
182 	virtual Size2 edit_get_minimum_size() const;
183 
184 	/* VISIBILITY */
185 
186 	bool is_visible() const;
187 	bool is_hidden() const;
188 	void show();
189 	void hide();
190 	void set_hidden(bool p_hidden);
191 
192 	void update();
193 
194 	void set_blend_mode(BlendMode p_blend_mode);
195 	BlendMode get_blend_mode() const;
196 
197 	virtual void set_light_mask(int p_light_mask);
198 	int get_light_mask() const;
199 
200 	void set_opacity(float p_opacity);
201 	float get_opacity() const;
202 
203 	void set_self_opacity(float p_self_opacity);
204 	float get_self_opacity() const;
205 
206 	/* DRAWING API */
207 
208 	void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0);
209 	void draw_rect(const Rect2 &p_rect, const Color &p_color);
210 	void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color);
211 	void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1));
212 	void draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
213 	void draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
214 	void draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect);
215 	void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture = Ref<Texture>(), float p_width = 1);
216 	void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>());
217 	void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>());
218 
219 	void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1);
220 	float draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", const Color &p_modulate = Color(1, 1, 1));
221 
222 	void draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale);
223 	void draw_set_transform_matrix(const Matrix32 &p_matrix);
224 
225 	/* RECT / TRANSFORM */
226 
227 	void set_as_toplevel(bool p_toplevel);
228 	bool is_set_as_toplevel() const;
229 
230 	void set_draw_behind_parent(bool p_enable);
231 	bool is_draw_behind_parent_enabled() const;
232 
233 	CanvasItem *get_parent_item() const;
234 
235 	virtual Rect2 get_item_rect() const = 0;
236 	virtual Matrix32 get_transform() const = 0;
237 
238 	virtual Matrix32 get_global_transform() const;
239 	virtual Matrix32 get_global_transform_with_canvas() const;
240 
241 	Rect2 get_item_and_children_rect() const;
242 
243 	CanvasItem *get_toplevel() const;
get_canvas_item()244 	_FORCE_INLINE_ RID get_canvas_item() const { return canvas_item; }
245 
246 	void set_block_transform_notify(bool p_enable);
247 	bool is_block_transform_notify_enabled() const;
248 
249 	Matrix32 get_canvas_transform() const;
250 	Matrix32 get_viewport_transform() const;
251 	Rect2 get_viewport_rect() const;
252 	RID get_viewport_rid() const;
253 	RID get_canvas() const;
254 	Ref<World2D> get_world_2d() const;
255 
256 	virtual void set_material(const Ref<CanvasItemMaterial> &p_material);
257 	Ref<CanvasItemMaterial> get_material() const;
258 
259 	virtual void set_use_parent_material(bool p_use_parent_material);
260 	bool get_use_parent_material() const;
261 
262 	InputEvent make_input_local(const InputEvent &pevent) const;
263 	Vector2 make_canvas_pos_local(const Vector2 &screen_point) const;
264 
265 	Vector2 get_global_mouse_pos() const;
266 	Vector2 get_local_mouse_pos() const;
267 
268 	void set_notify_local_transform(bool p_enable);
269 	bool is_local_transform_notification_enabled() const;
270 
271 	int get_canvas_layer() const;
272 
273 	CanvasItem();
274 	~CanvasItem();
275 };
276 
277 VARIANT_ENUM_CAST(CanvasItem::BlendMode);
278 
279 #endif // CANVAS_ITEM_H
280