1 /*************************************************************************/
2 /* canvas_item.cpp */
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 #include "canvas_item.h"
31 #include "message_queue.h"
32 #include "os/input.h"
33 #include "scene/main/canvas_layer.h"
34 #include "scene/main/viewport.h"
35 #include "scene/resources/font.h"
36 #include "scene/resources/style_box.h"
37 #include "scene/resources/texture.h"
38 #include "scene/scene_string_names.h"
39 #include "servers/visual_server.h"
40
_set(const StringName & p_name,const Variant & p_value)41 bool CanvasItemMaterial::_set(const StringName &p_name, const Variant &p_value) {
42
43 if (p_name == SceneStringNames::get_singleton()->shader_shader) {
44 set_shader(p_value);
45 return true;
46 } else if (p_name == SceneStringNames::get_singleton()->shading_mode) {
47 set_shading_mode(ShadingMode(p_value.operator int()));
48 return true;
49 } else {
50
51 if (shader.is_valid()) {
52
53 StringName pr = shader->remap_param(p_name);
54 if (!pr) {
55 String n = p_name;
56 if (n.find("param/") == 0) { //backwards compatibility
57 pr = n.substr(6, n.length());
58 }
59 }
60 if (pr) {
61 VisualServer::get_singleton()->canvas_item_material_set_shader_param(material, pr, p_value);
62 return true;
63 }
64 }
65 }
66
67 return false;
68 }
69
_get(const StringName & p_name,Variant & r_ret) const70 bool CanvasItemMaterial::_get(const StringName &p_name, Variant &r_ret) const {
71
72 if (p_name == SceneStringNames::get_singleton()->shader_shader) {
73
74 r_ret = get_shader();
75 return true;
76 } else if (p_name == SceneStringNames::get_singleton()->shading_mode) {
77
78 r_ret = shading_mode;
79 return true;
80 } else {
81
82 if (shader.is_valid()) {
83
84 StringName pr = shader->remap_param(p_name);
85 if (pr) {
86 r_ret = VisualServer::get_singleton()->canvas_item_material_get_shader_param(material, pr);
87 return true;
88 }
89 }
90 }
91
92 return false;
93 }
94
_get_property_list(List<PropertyInfo> * p_list) const95 void CanvasItemMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
96
97 p_list->push_back(PropertyInfo(Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph"));
98 p_list->push_back(PropertyInfo(Variant::INT, "shader/shading_mode", PROPERTY_HINT_ENUM, "Normal,Unshaded,Light Only"));
99
100 if (!shader.is_null()) {
101
102 shader->get_param_list(p_list);
103 }
104 }
105
set_shader(const Ref<Shader> & p_shader)106 void CanvasItemMaterial::set_shader(const Ref<Shader> &p_shader) {
107
108 ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode() != Shader::MODE_CANVAS_ITEM);
109
110 shader = p_shader;
111
112 RID rid;
113 if (shader.is_valid())
114 rid = shader->get_rid();
115
116 VS::get_singleton()->canvas_item_material_set_shader(material, rid);
117 _change_notify(); //properties for shader exposed
118 emit_changed();
119 }
120
get_shader() const121 Ref<Shader> CanvasItemMaterial::get_shader() const {
122
123 return shader;
124 }
125
set_shader_param(const StringName & p_param,const Variant & p_value)126 void CanvasItemMaterial::set_shader_param(const StringName &p_param, const Variant &p_value) {
127
128 VS::get_singleton()->canvas_item_material_set_shader_param(material, p_param, p_value);
129 }
130
get_shader_param(const StringName & p_param) const131 Variant CanvasItemMaterial::get_shader_param(const StringName &p_param) const {
132
133 return VS::get_singleton()->canvas_item_material_get_shader_param(material, p_param);
134 }
135
get_rid() const136 RID CanvasItemMaterial::get_rid() const {
137
138 return material;
139 }
140
set_shading_mode(ShadingMode p_mode)141 void CanvasItemMaterial::set_shading_mode(ShadingMode p_mode) {
142
143 shading_mode = p_mode;
144 VS::get_singleton()->canvas_item_material_set_shading_mode(material, VS::CanvasItemShadingMode(p_mode));
145 }
146
get_shading_mode() const147 CanvasItemMaterial::ShadingMode CanvasItemMaterial::get_shading_mode() const {
148 return shading_mode;
149 }
150
_bind_methods()151 void CanvasItemMaterial::_bind_methods() {
152
153 ObjectTypeDB::bind_method(_MD("set_shader", "shader:Shader"), &CanvasItemMaterial::set_shader);
154 ObjectTypeDB::bind_method(_MD("get_shader:Shader"), &CanvasItemMaterial::get_shader);
155 ObjectTypeDB::bind_method(_MD("set_shader_param", "param", "value"), &CanvasItemMaterial::set_shader_param);
156 ObjectTypeDB::bind_method(_MD("get_shader_param", "param"), &CanvasItemMaterial::get_shader_param);
157 ObjectTypeDB::bind_method(_MD("set_shading_mode", "mode"), &CanvasItemMaterial::set_shading_mode);
158 ObjectTypeDB::bind_method(_MD("get_shading_mode"), &CanvasItemMaterial::get_shading_mode);
159
160 BIND_CONSTANT(SHADING_NORMAL);
161 BIND_CONSTANT(SHADING_UNSHADED);
162 BIND_CONSTANT(SHADING_ONLY_LIGHT);
163 }
164
get_argument_options(const StringName & p_function,int p_idx,List<String> * r_options) const165 void CanvasItemMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
166
167 String f = p_function.operator String();
168 if ((f == "get_shader_param" || f == "set_shader_param") && p_idx == 0) {
169
170 if (shader.is_valid()) {
171 List<PropertyInfo> pl;
172 shader->get_param_list(&pl);
173 for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) {
174 r_options->push_back("\"" + E->get().name.replace_first("shader_param/", "") + "\"");
175 }
176 }
177 }
178 Resource::get_argument_options(p_function, p_idx, r_options);
179 }
180
CanvasItemMaterial()181 CanvasItemMaterial::CanvasItemMaterial() {
182
183 material = VS::get_singleton()->canvas_item_material_create();
184 shading_mode = SHADING_NORMAL;
185 }
186
~CanvasItemMaterial()187 CanvasItemMaterial::~CanvasItemMaterial() {
188
189 VS::get_singleton()->free(material);
190 }
191
192 ///////////////////////////////////////////////////////////////////
193
is_visible() const194 bool CanvasItem::is_visible() const {
195
196 if (!is_inside_tree())
197 return false;
198
199 const CanvasItem *p = this;
200
201 while (p) {
202 if (p->hidden)
203 return false;
204 p = p->get_parent_item();
205 }
206
207 return true;
208 }
209
is_hidden() const210 bool CanvasItem::is_hidden() const {
211
212 /*if (!is_inside_scene())
213 return false;*/
214
215 return hidden;
216 }
217
_propagate_visibility_changed(bool p_visible)218 void CanvasItem::_propagate_visibility_changed(bool p_visible) {
219
220 notification(NOTIFICATION_VISIBILITY_CHANGED);
221
222 if (p_visible)
223 update(); //todo optimize
224 else
225 emit_signal(SceneStringNames::get_singleton()->hide);
226 _block();
227
228 for (int i = 0; i < get_child_count(); i++) {
229
230 CanvasItem *c = get_child(i)->cast_to<CanvasItem>();
231
232 if (c && !c->hidden) //should the toplevels stop propagation? i think so but..
233 c->_propagate_visibility_changed(p_visible);
234 }
235
236 _unblock();
237 }
238
show()239 void CanvasItem::show() {
240
241 if (!hidden)
242 return;
243
244 hidden = false;
245 VisualServer::get_singleton()->canvas_item_set_visible(canvas_item, true);
246
247 if (!is_inside_tree())
248 return;
249
250 _propagate_visibility_changed(true);
251 _change_notify("visibility/visible");
252 }
253
hide()254 void CanvasItem::hide() {
255
256 if (hidden)
257 return;
258
259 hidden = true;
260 VisualServer::get_singleton()->canvas_item_set_visible(canvas_item, false);
261
262 if (!is_inside_tree())
263 return;
264
265 _propagate_visibility_changed(false);
266 _change_notify("visibility/visible");
267 }
268
set_hidden(bool p_hidden)269 void CanvasItem::set_hidden(bool p_hidden) {
270
271 if (hidden == p_hidden) {
272 return;
273 }
274
275 _set_visible_(!p_hidden);
276 }
277
edit_get_state() const278 Variant CanvasItem::edit_get_state() const {
279
280 return Variant();
281 }
edit_set_state(const Variant & p_state)282 void CanvasItem::edit_set_state(const Variant &p_state) {
283 }
284
edit_set_rect(const Rect2 & p_edit_rect)285 void CanvasItem::edit_set_rect(const Rect2 &p_edit_rect) {
286
287 //used by editors, implement at will
288 }
289
edit_rotate(float p_rot)290 void CanvasItem::edit_rotate(float p_rot) {
291 }
292
edit_get_minimum_size() const293 Size2 CanvasItem::edit_get_minimum_size() const {
294
295 return Size2(-1, -1); //no limit
296 }
297
_update_callback()298 void CanvasItem::_update_callback() {
299
300 if (!is_inside_tree()) {
301 pending_update = false;
302 return;
303 }
304
305 VisualServer::get_singleton()->canvas_item_clear(get_canvas_item());
306 //todo updating = true - only allow drawing here
307 if (is_visible()) { //todo optimize this!!
308 if (first_draw) {
309 notification(NOTIFICATION_VISIBILITY_CHANGED);
310 first_draw = false;
311 }
312 drawing = true;
313 notification(NOTIFICATION_DRAW);
314 emit_signal(SceneStringNames::get_singleton()->draw);
315 if (get_script_instance()) {
316 Variant::CallError err;
317 get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_draw, NULL, 0);
318 }
319 drawing = false;
320 }
321 //todo updating = false
322 pending_update = false; // don't change to false until finished drawing (avoid recursive update)
323 }
324
get_global_transform_with_canvas() const325 Matrix32 CanvasItem::get_global_transform_with_canvas() const {
326
327 const CanvasItem *ci = this;
328 Matrix32 xform;
329 const CanvasItem *last_valid = NULL;
330
331 while (ci) {
332
333 last_valid = ci;
334 xform = ci->get_transform() * xform;
335 ci = ci->get_parent_item();
336 }
337
338 if (last_valid->canvas_layer)
339 return last_valid->canvas_layer->get_transform() * xform;
340 else if (is_inside_tree())
341 return get_viewport()->get_canvas_transform() * xform;
342
343 return xform;
344 }
345
get_global_transform() const346 Matrix32 CanvasItem::get_global_transform() const {
347
348 if (global_invalid) {
349
350 const CanvasItem *pi = get_parent_item();
351 if (pi)
352 global_transform = pi->get_global_transform() * get_transform();
353 else
354 global_transform = get_transform();
355
356 global_invalid = false;
357 }
358
359 return global_transform;
360 }
361
_queue_sort_children()362 void CanvasItem::_queue_sort_children() {
363
364 if (pending_children_sort)
365 return;
366
367 pending_children_sort = true;
368 MessageQueue::get_singleton()->push_call(this, "_sort_children");
369 }
370
_sort_children()371 void CanvasItem::_sort_children() {
372
373 pending_children_sort = false;
374
375 if (!is_inside_tree())
376 return;
377
378 for (int i = 0; i < get_child_count(); i++) {
379
380 Node *n = get_child(i);
381 CanvasItem *ci = n->cast_to<CanvasItem>();
382
383 if (ci) {
384 if (ci->toplevel || ci->group != "")
385 continue;
386 VisualServer::get_singleton()->canvas_item_raise(n->cast_to<CanvasItem>()->canvas_item);
387 }
388 }
389 }
390
_raise_self()391 void CanvasItem::_raise_self() {
392
393 if (!is_inside_tree())
394 return;
395
396 VisualServer::get_singleton()->canvas_item_raise(canvas_item);
397 }
398
_enter_canvas()399 void CanvasItem::_enter_canvas() {
400
401 if ((!get_parent() || !get_parent()->cast_to<CanvasItem>()) || toplevel) {
402
403 Node *n = this;
404
405 canvas_layer = NULL;
406
407 while (n) {
408
409 canvas_layer = n->cast_to<CanvasLayer>();
410 if (canvas_layer) {
411 break;
412 }
413 n = n->get_parent();
414 }
415
416 RID canvas;
417 if (canvas_layer)
418 canvas = canvas_layer->get_world_2d()->get_canvas();
419 else
420 canvas = get_viewport()->find_world_2d()->get_canvas();
421
422 VisualServer::get_singleton()->canvas_item_set_parent(canvas_item, canvas);
423
424 group = "root_canvas" + itos(canvas.get_id());
425
426 add_to_group(group);
427 get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE, group, "_raise_self");
428
429 } else {
430
431 CanvasItem *parent = get_parent_item();
432 canvas_layer = parent->canvas_layer;
433 VisualServer::get_singleton()->canvas_item_set_parent(canvas_item, parent->get_canvas_item());
434 parent->_queue_sort_children();
435 }
436
437 pending_update = false;
438 update();
439
440 notification(NOTIFICATION_ENTER_CANVAS);
441 }
442
_exit_canvas()443 void CanvasItem::_exit_canvas() {
444
445 notification(NOTIFICATION_EXIT_CANVAS, true); //reverse the notification
446 VisualServer::get_singleton()->canvas_item_set_parent(canvas_item, RID());
447 canvas_layer = NULL;
448 group = "";
449 }
450
_notification(int p_what)451 void CanvasItem::_notification(int p_what) {
452
453 switch (p_what) {
454 case NOTIFICATION_ENTER_TREE: {
455
456 first_draw = true;
457 pending_children_sort = false;
458 if (get_parent()) {
459 CanvasItem *ci = get_parent()->cast_to<CanvasItem>();
460 if (ci)
461 C = ci->children_items.push_back(this);
462 }
463 _enter_canvas();
464 if (!block_transform_notify && !xform_change.in_list()) {
465 get_tree()->xform_change_list.add(&xform_change);
466 }
467 } break;
468 case NOTIFICATION_MOVED_IN_PARENT: {
469
470 if (group != "") {
471 get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE, group, "_raise_self");
472 } else {
473 CanvasItem *p = get_parent_item();
474 ERR_FAIL_COND(!p);
475 p->_queue_sort_children();
476 }
477
478 } break;
479 case NOTIFICATION_EXIT_TREE: {
480 if (xform_change.in_list())
481 get_tree()->xform_change_list.remove(&xform_change);
482 _exit_canvas();
483 if (C) {
484 get_parent()->cast_to<CanvasItem>()->children_items.erase(C);
485 C = NULL;
486 }
487 global_invalid = true;
488 } break;
489 case NOTIFICATION_DRAW: {
490
491 } break;
492 case NOTIFICATION_TRANSFORM_CHANGED: {
493
494 } break;
495 case NOTIFICATION_VISIBILITY_CHANGED: {
496
497 emit_signal(SceneStringNames::get_singleton()->visibility_changed);
498 } break;
499 }
500 }
501
_set_visible_(bool p_visible)502 void CanvasItem::_set_visible_(bool p_visible) {
503
504 if (p_visible)
505 show();
506 else
507 hide();
508 }
_is_visible_() const509 bool CanvasItem::_is_visible_() const {
510
511 return !is_hidden();
512 }
513
update()514 void CanvasItem::update() {
515
516 if (!is_inside_tree())
517 return;
518 if (pending_update)
519 return;
520
521 pending_update = true;
522
523 MessageQueue::get_singleton()->push_call(this, "_update_callback");
524 }
525
set_opacity(float p_opacity)526 void CanvasItem::set_opacity(float p_opacity) {
527
528 opacity = p_opacity;
529 VisualServer::get_singleton()->canvas_item_set_opacity(canvas_item, opacity);
530 }
get_opacity() const531 float CanvasItem::get_opacity() const {
532
533 return opacity;
534 }
535
set_as_toplevel(bool p_toplevel)536 void CanvasItem::set_as_toplevel(bool p_toplevel) {
537
538 if (toplevel == p_toplevel)
539 return;
540
541 if (!is_inside_tree()) {
542 toplevel = p_toplevel;
543 return;
544 }
545
546 _exit_canvas();
547 toplevel = p_toplevel;
548 _enter_canvas();
549 }
550
is_set_as_toplevel() const551 bool CanvasItem::is_set_as_toplevel() const {
552
553 return toplevel;
554 }
555
get_parent_item() const556 CanvasItem *CanvasItem::get_parent_item() const {
557
558 if (toplevel)
559 return NULL;
560
561 Node *parent = get_parent();
562 if (!parent)
563 return NULL;
564
565 return parent->cast_to<CanvasItem>();
566 }
567
set_self_opacity(float p_self_opacity)568 void CanvasItem::set_self_opacity(float p_self_opacity) {
569
570 self_opacity = p_self_opacity;
571 VisualServer::get_singleton()->canvas_item_set_self_opacity(canvas_item, self_opacity);
572 }
get_self_opacity() const573 float CanvasItem::get_self_opacity() const {
574
575 return self_opacity;
576 }
577
set_blend_mode(BlendMode p_blend_mode)578 void CanvasItem::set_blend_mode(BlendMode p_blend_mode) {
579
580 ERR_FAIL_INDEX(p_blend_mode, 5);
581 blend_mode = p_blend_mode;
582 VisualServer::get_singleton()->canvas_item_set_blend_mode(canvas_item, VS::MaterialBlendMode(blend_mode));
583 }
584
get_blend_mode() const585 CanvasItem::BlendMode CanvasItem::get_blend_mode() const {
586
587 return blend_mode;
588 }
589
set_light_mask(int p_light_mask)590 void CanvasItem::set_light_mask(int p_light_mask) {
591
592 light_mask = p_light_mask;
593 VS::get_singleton()->canvas_item_set_light_mask(canvas_item, p_light_mask);
594 }
595
get_light_mask() const596 int CanvasItem::get_light_mask() const {
597
598 return light_mask;
599 }
600
item_rect_changed()601 void CanvasItem::item_rect_changed() {
602
603 update();
604 emit_signal(SceneStringNames::get_singleton()->item_rect_changed);
605 }
606
draw_line(const Point2 & p_from,const Point2 & p_to,const Color & p_color,float p_width)607 void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
608
609 if (!drawing) {
610 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
611 ERR_FAIL();
612 }
613
614 VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
615 }
616
draw_rect(const Rect2 & p_rect,const Color & p_color)617 void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color) {
618
619 if (!drawing) {
620 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
621 ERR_FAIL();
622 }
623
624 VisualServer::get_singleton()->canvas_item_add_rect(canvas_item, p_rect, p_color);
625 }
626
draw_circle(const Point2 & p_pos,float p_radius,const Color & p_color)627 void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color) {
628
629 if (!drawing) {
630 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
631 ERR_FAIL();
632 }
633
634 VisualServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color);
635 }
636
draw_texture(const Ref<Texture> & p_texture,const Point2 & p_pos,const Color & p_modulate)637 void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate) {
638
639 if (!drawing) {
640 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
641 ERR_FAIL();
642 }
643
644 ERR_FAIL_COND(p_texture.is_null());
645
646 p_texture->draw(canvas_item, p_pos, p_modulate);
647 }
648
draw_texture_rect(const Ref<Texture> & p_texture,const Rect2 & p_rect,bool p_tile,const Color & p_modulate,bool p_transpose)649 void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) {
650
651 if (!drawing) {
652 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
653 ERR_FAIL();
654 }
655
656 ERR_FAIL_COND(p_texture.is_null());
657 p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose);
658 }
draw_texture_rect_region(const Ref<Texture> & p_texture,const Rect2 & p_rect,const Rect2 & p_src_rect,const Color & p_modulate,bool p_transpose)659 void CanvasItem::draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) {
660
661 if (!drawing) {
662 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
663 ERR_FAIL();
664 }
665 ERR_FAIL_COND(p_texture.is_null());
666 p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose);
667 }
668
draw_style_box(const Ref<StyleBox> & p_style_box,const Rect2 & p_rect)669 void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect) {
670 if (!drawing) {
671 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
672 ERR_FAIL();
673 }
674
675 ERR_FAIL_COND(p_style_box.is_null());
676
677 p_style_box->draw(canvas_item, p_rect);
678 }
draw_primitive(const Vector<Point2> & p_points,const Vector<Color> & p_colors,const Vector<Point2> & p_uvs,Ref<Texture> p_texture,float p_width)679 void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, float p_width) {
680
681 if (!drawing) {
682 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
683 ERR_FAIL();
684 }
685
686 RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
687
688 VisualServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width);
689 }
draw_set_transform(const Point2 & p_offset,float p_rot,const Size2 & p_scale)690 void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) {
691
692 if (!drawing) {
693 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
694 ERR_FAIL();
695 }
696
697 Matrix32 xform(p_rot, p_offset);
698 xform.scale_basis(p_scale);
699 VisualServer::get_singleton()->canvas_item_add_set_transform(canvas_item, xform);
700 }
701
draw_set_transform_matrix(const Matrix32 & p_matrix)702 void CanvasItem::draw_set_transform_matrix(const Matrix32 &p_matrix) {
703
704 if (!drawing) {
705 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
706 ERR_FAIL();
707 }
708
709 VisualServer::get_singleton()->canvas_item_add_set_transform(canvas_item, p_matrix);
710 }
711
draw_polygon(const Vector<Point2> & p_points,const Vector<Color> & p_colors,const Vector<Point2> & p_uvs,Ref<Texture> p_texture)712 void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture) {
713
714 if (!drawing) {
715 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
716 ERR_FAIL();
717 }
718
719 RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
720
721 VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, p_colors, p_uvs, rid);
722 }
723
draw_colored_polygon(const Vector<Point2> & p_points,const Color & p_color,const Vector<Point2> & p_uvs,Ref<Texture> p_texture)724 void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture> p_texture) {
725
726 if (!drawing) {
727 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
728 ERR_FAIL();
729 }
730
731 Vector<Color> colors;
732 colors.push_back(p_color);
733 RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
734
735 VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid);
736 }
737
draw_string(const Ref<Font> & p_font,const Point2 & p_pos,const String & p_text,const Color & p_modulate,int p_clip_w)738 void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w) {
739
740 if (!drawing) {
741 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
742 ERR_FAIL();
743 }
744
745 ERR_FAIL_COND(p_font.is_null());
746 p_font->draw(canvas_item, p_pos, p_text, p_modulate, p_clip_w);
747 }
748
draw_char(const Ref<Font> & p_font,const Point2 & p_pos,const String & p_char,const String & p_next,const Color & p_modulate)749 float CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next, const Color &p_modulate) {
750
751 if (!drawing) {
752 ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
753 ERR_FAIL_V(0);
754 }
755
756 ERR_FAIL_COND_V(p_char.length() != 1, 0);
757 ERR_FAIL_COND_V(p_font.is_null(), 0);
758
759 return p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.c_str()[0], p_modulate);
760 }
761
_notify_transform(CanvasItem * p_node)762 void CanvasItem::_notify_transform(CanvasItem *p_node) {
763
764 if (p_node->xform_change.in_list() && p_node->global_invalid)
765 return; //nothing to do
766
767 p_node->global_invalid = true;
768
769 if (!p_node->xform_change.in_list()) {
770 if (!p_node->block_transform_notify) {
771 if (p_node->is_inside_tree())
772 get_tree()->xform_change_list.add(&p_node->xform_change);
773 }
774 }
775
776 for (List<CanvasItem *>::Element *E = p_node->children_items.front(); E; E = E->next()) {
777
778 CanvasItem *ci = E->get();
779 if (ci->toplevel)
780 continue;
781 _notify_transform(ci);
782 }
783 }
784
get_viewport_rect() const785 Rect2 CanvasItem::get_viewport_rect() const {
786
787 ERR_FAIL_COND_V(!is_inside_tree(), Rect2());
788 return get_viewport()->get_visible_rect();
789 }
790
get_canvas() const791 RID CanvasItem::get_canvas() const {
792
793 ERR_FAIL_COND_V(!is_inside_tree(), RID());
794
795 if (canvas_layer)
796 return canvas_layer->get_world_2d()->get_canvas();
797 else
798 return get_viewport()->find_world_2d()->get_canvas();
799 }
800
get_toplevel() const801 CanvasItem *CanvasItem::get_toplevel() const {
802
803 CanvasItem *ci = const_cast<CanvasItem *>(this);
804 while (!ci->toplevel && ci->get_parent() && ci->get_parent()->cast_to<CanvasItem>()) {
805 ci = ci->get_parent()->cast_to<CanvasItem>();
806 }
807
808 return ci;
809 }
810
get_world_2d() const811 Ref<World2D> CanvasItem::get_world_2d() const {
812
813 ERR_FAIL_COND_V(!is_inside_tree(), Ref<World2D>());
814
815 CanvasItem *tl = get_toplevel();
816
817 if (tl->canvas_layer) {
818 return tl->canvas_layer->get_world_2d();
819 } else if (tl->get_viewport()) {
820 return tl->get_viewport()->find_world_2d();
821 } else {
822 return Ref<World2D>();
823 }
824 }
825
get_viewport_rid() const826 RID CanvasItem::get_viewport_rid() const {
827
828 ERR_FAIL_COND_V(!is_inside_tree(), RID());
829 return get_viewport()->get_viewport();
830 }
831
set_block_transform_notify(bool p_enable)832 void CanvasItem::set_block_transform_notify(bool p_enable) {
833 block_transform_notify = p_enable;
834 }
835
is_block_transform_notify_enabled() const836 bool CanvasItem::is_block_transform_notify_enabled() const {
837
838 return block_transform_notify;
839 }
840
set_draw_behind_parent(bool p_enable)841 void CanvasItem::set_draw_behind_parent(bool p_enable) {
842
843 if (behind == p_enable)
844 return;
845 behind = p_enable;
846 VisualServer::get_singleton()->canvas_item_set_on_top(canvas_item, !behind);
847 }
848
is_draw_behind_parent_enabled() const849 bool CanvasItem::is_draw_behind_parent_enabled() const {
850
851 return behind;
852 }
853
set_material(const Ref<CanvasItemMaterial> & p_material)854 void CanvasItem::set_material(const Ref<CanvasItemMaterial> &p_material) {
855
856 material = p_material;
857 RID rid;
858 if (material.is_valid())
859 rid = material->get_rid();
860 VS::get_singleton()->canvas_item_set_material(canvas_item, rid);
861 _change_notify(); //properties for material exposed
862 }
863
set_use_parent_material(bool p_use_parent_material)864 void CanvasItem::set_use_parent_material(bool p_use_parent_material) {
865
866 use_parent_material = p_use_parent_material;
867 VS::get_singleton()->canvas_item_set_use_parent_material(canvas_item, p_use_parent_material);
868 }
869
get_use_parent_material() const870 bool CanvasItem::get_use_parent_material() const {
871
872 return use_parent_material;
873 }
874
get_material() const875 Ref<CanvasItemMaterial> CanvasItem::get_material() const {
876
877 return material;
878 }
879
make_canvas_pos_local(const Vector2 & screen_point) const880 Vector2 CanvasItem::make_canvas_pos_local(const Vector2 &screen_point) const {
881
882 ERR_FAIL_COND_V(!is_inside_tree(), screen_point);
883
884 Matrix32 local_matrix = (get_canvas_transform() *
885 get_global_transform())
886 .affine_inverse();
887
888 return local_matrix.xform(screen_point);
889 }
890
make_input_local(const InputEvent & p_event) const891 InputEvent CanvasItem::make_input_local(const InputEvent &p_event) const {
892
893 ERR_FAIL_COND_V(!is_inside_tree(), p_event);
894
895 return p_event.xform_by((get_canvas_transform() * get_global_transform()).affine_inverse());
896 }
897
get_global_mouse_pos() const898 Vector2 CanvasItem::get_global_mouse_pos() const {
899
900 ERR_FAIL_COND_V(!get_viewport(), Vector2());
901 return get_canvas_transform().affine_inverse().xform(get_viewport()->get_mouse_pos());
902 }
get_local_mouse_pos() const903 Vector2 CanvasItem::get_local_mouse_pos() const {
904
905 ERR_FAIL_COND_V(!get_viewport(), Vector2());
906
907 return get_global_transform().affine_inverse().xform(get_global_mouse_pos());
908 }
909
_bind_methods()910 void CanvasItem::_bind_methods() {
911
912 ObjectTypeDB::bind_method(_MD("_sort_children"), &CanvasItem::_sort_children);
913 ObjectTypeDB::bind_method(_MD("_raise_self"), &CanvasItem::_raise_self);
914 ObjectTypeDB::bind_method(_MD("_update_callback"), &CanvasItem::_update_callback);
915 ObjectTypeDB::bind_method(_MD("_set_visible_"), &CanvasItem::_set_visible_);
916 ObjectTypeDB::bind_method(_MD("_is_visible_"), &CanvasItem::_is_visible_);
917
918 ObjectTypeDB::bind_method(_MD("edit_set_state", "state"), &CanvasItem::edit_set_state);
919 ObjectTypeDB::bind_method(_MD("edit_get_state:Variant"), &CanvasItem::edit_get_state);
920 ObjectTypeDB::bind_method(_MD("edit_set_rect", "rect"), &CanvasItem::edit_set_rect);
921 ObjectTypeDB::bind_method(_MD("edit_rotate", "degrees"), &CanvasItem::edit_rotate);
922
923 ObjectTypeDB::bind_method(_MD("get_item_rect"), &CanvasItem::get_item_rect);
924 ObjectTypeDB::bind_method(_MD("get_item_and_children_rect"), &CanvasItem::get_item_and_children_rect);
925 //ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform);
926
927 ObjectTypeDB::bind_method(_MD("get_canvas_item"), &CanvasItem::get_canvas_item);
928
929 ObjectTypeDB::bind_method(_MD("is_visible"), &CanvasItem::is_visible);
930 ObjectTypeDB::bind_method(_MD("is_hidden"), &CanvasItem::is_hidden);
931 ObjectTypeDB::bind_method(_MD("show"), &CanvasItem::show);
932 ObjectTypeDB::bind_method(_MD("hide"), &CanvasItem::hide);
933 ObjectTypeDB::bind_method(_MD("set_hidden", "hidden"), &CanvasItem::set_hidden);
934
935 ObjectTypeDB::bind_method(_MD("update"), &CanvasItem::update);
936
937 ObjectTypeDB::bind_method(_MD("set_as_toplevel", "enable"), &CanvasItem::set_as_toplevel);
938 ObjectTypeDB::bind_method(_MD("is_set_as_toplevel"), &CanvasItem::is_set_as_toplevel);
939
940 ObjectTypeDB::bind_method(_MD("set_blend_mode", "blend_mode"), &CanvasItem::set_blend_mode);
941 ObjectTypeDB::bind_method(_MD("get_blend_mode"), &CanvasItem::get_blend_mode);
942
943 ObjectTypeDB::bind_method(_MD("set_light_mask", "light_mask"), &CanvasItem::set_light_mask);
944 ObjectTypeDB::bind_method(_MD("get_light_mask"), &CanvasItem::get_light_mask);
945
946 ObjectTypeDB::bind_method(_MD("set_opacity", "opacity"), &CanvasItem::set_opacity);
947 ObjectTypeDB::bind_method(_MD("get_opacity"), &CanvasItem::get_opacity);
948 ObjectTypeDB::bind_method(_MD("set_self_opacity", "self_opacity"), &CanvasItem::set_self_opacity);
949 ObjectTypeDB::bind_method(_MD("get_self_opacity"), &CanvasItem::get_self_opacity);
950
951 ObjectTypeDB::bind_method(_MD("set_draw_behind_parent", "enable"), &CanvasItem::set_draw_behind_parent);
952 ObjectTypeDB::bind_method(_MD("is_draw_behind_parent_enabled"), &CanvasItem::is_draw_behind_parent_enabled);
953
954 ObjectTypeDB::bind_method(_MD("_set_on_top", "on_top"), &CanvasItem::_set_on_top);
955 ObjectTypeDB::bind_method(_MD("_is_on_top"), &CanvasItem::_is_on_top);
956 //ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform);
957
958 ObjectTypeDB::bind_method(_MD("draw_line", "from", "to", "color", "width"), &CanvasItem::draw_line, DEFVAL(1.0));
959 ObjectTypeDB::bind_method(_MD("draw_rect", "rect", "color"), &CanvasItem::draw_rect);
960 ObjectTypeDB::bind_method(_MD("draw_circle", "pos", "radius", "color"), &CanvasItem::draw_circle);
961 ObjectTypeDB::bind_method(_MD("draw_texture", "texture:Texture", "pos", "modulate"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)));
962 ObjectTypeDB::bind_method(_MD("draw_texture_rect", "texture:Texture", "rect", "tile", "modulate", "transpose"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
963 ObjectTypeDB::bind_method(_MD("draw_texture_rect_region", "texture:Texture", "rect", "src_rect", "modulate", "transpose"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
964 ObjectTypeDB::bind_method(_MD("draw_style_box", "style_box:StyleBox", "rect"), &CanvasItem::draw_style_box);
965 ObjectTypeDB::bind_method(_MD("draw_primitive", "points", "colors", "uvs", "texture:Texture", "width"), &CanvasItem::draw_primitive, DEFVAL(Variant()), DEFVAL(1.0));
966 ObjectTypeDB::bind_method(_MD("draw_polygon", "points", "colors", "uvs", "texture:Texture"), &CanvasItem::draw_polygon, DEFVAL(Vector2Array()), DEFVAL(Variant()));
967 ObjectTypeDB::bind_method(_MD("draw_colored_polygon", "points", "color", "uvs", "texture:Texture"), &CanvasItem::draw_colored_polygon, DEFVAL(Vector2Array()), DEFVAL(Variant()));
968 ObjectTypeDB::bind_method(_MD("draw_string", "font:Font", "pos", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1));
969 ObjectTypeDB::bind_method(_MD("draw_char", "font:Font", "pos", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1)));
970
971 ObjectTypeDB::bind_method(_MD("draw_set_transform", "pos", "rot", "scale"), &CanvasItem::draw_set_transform);
972 ObjectTypeDB::bind_method(_MD("draw_set_transform_matrix", "xform"), &CanvasItem::draw_set_transform_matrix);
973 ObjectTypeDB::bind_method(_MD("get_transform"), &CanvasItem::get_transform);
974 ObjectTypeDB::bind_method(_MD("get_global_transform"), &CanvasItem::get_global_transform);
975 ObjectTypeDB::bind_method(_MD("get_global_transform_with_canvas"), &CanvasItem::get_global_transform_with_canvas);
976 ObjectTypeDB::bind_method(_MD("get_viewport_transform"), &CanvasItem::get_viewport_transform);
977 ObjectTypeDB::bind_method(_MD("get_viewport_rect"), &CanvasItem::get_viewport_rect);
978 ObjectTypeDB::bind_method(_MD("get_canvas_transform"), &CanvasItem::get_canvas_transform);
979 ObjectTypeDB::bind_method(_MD("get_local_mouse_pos"), &CanvasItem::get_local_mouse_pos);
980 ObjectTypeDB::bind_method(_MD("get_global_mouse_pos"), &CanvasItem::get_global_mouse_pos);
981 ObjectTypeDB::bind_method(_MD("get_canvas"), &CanvasItem::get_canvas);
982 ObjectTypeDB::bind_method(_MD("get_world_2d"), &CanvasItem::get_world_2d);
983 //ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport);
984
985 ObjectTypeDB::bind_method(_MD("set_material", "material:CanvasItemMaterial"), &CanvasItem::set_material);
986 ObjectTypeDB::bind_method(_MD("get_material:CanvasItemMaterial"), &CanvasItem::get_material);
987
988 ObjectTypeDB::bind_method(_MD("set_use_parent_material", "enable"), &CanvasItem::set_use_parent_material);
989 ObjectTypeDB::bind_method(_MD("get_use_parent_material"), &CanvasItem::get_use_parent_material);
990
991 ObjectTypeDB::bind_method(_MD("make_canvas_pos_local", "screen_point"),
992 &CanvasItem::make_canvas_pos_local);
993 ObjectTypeDB::bind_method(_MD("make_input_local", "event"), &CanvasItem::make_input_local);
994
995 BIND_VMETHOD(MethodInfo("_draw"));
996
997 ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "visibility/visible"), _SCS("_set_visible_"), _SCS("_is_visible_"));
998 ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "visibility/opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_opacity"), _SCS("get_opacity"));
999 ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "visibility/self_opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_self_opacity"), _SCS("get_self_opacity"));
1000 ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "visibility/behind_parent"), _SCS("set_draw_behind_parent"), _SCS("is_draw_behind_parent_enabled"));
1001 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visibility/on_top", PROPERTY_HINT_NONE, "", 0), _SCS("_set_on_top"), _SCS("_is_on_top")); //compatibility
1002
1003 ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "visibility/blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"), _SCS("get_blend_mode"));
1004 ADD_PROPERTYNO(PropertyInfo(Variant::INT, "visibility/light_mask", PROPERTY_HINT_ALL_FLAGS), _SCS("set_light_mask"), _SCS("get_light_mask"));
1005 ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "material/material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial"), _SCS("set_material"), _SCS("get_material"));
1006 ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "material/use_parent"), _SCS("set_use_parent_material"), _SCS("get_use_parent_material"));
1007 //exporting these two things doesn't really make much sense i think
1008 //ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transform/toplevel"), _SCS("set_as_toplevel"),_SCS("is_set_as_toplevel") );
1009 //ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),_SCS("set_transform_notify"),_SCS("is_transform_notify_enabled"));
1010
1011 ADD_SIGNAL(MethodInfo("draw"));
1012 ADD_SIGNAL(MethodInfo("visibility_changed"));
1013 ADD_SIGNAL(MethodInfo("hide"));
1014 ADD_SIGNAL(MethodInfo("item_rect_changed"));
1015
1016 BIND_CONSTANT(BLEND_MODE_MIX);
1017 BIND_CONSTANT(BLEND_MODE_ADD);
1018 BIND_CONSTANT(BLEND_MODE_SUB);
1019 BIND_CONSTANT(BLEND_MODE_MUL);
1020 BIND_CONSTANT(BLEND_MODE_PREMULT_ALPHA);
1021
1022 BIND_CONSTANT(NOTIFICATION_DRAW);
1023 BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED);
1024 BIND_CONSTANT(NOTIFICATION_ENTER_CANVAS);
1025 BIND_CONSTANT(NOTIFICATION_EXIT_CANVAS);
1026 BIND_CONSTANT(NOTIFICATION_TRANSFORM_CHANGED);
1027 }
1028
get_canvas_transform() const1029 Matrix32 CanvasItem::get_canvas_transform() const {
1030
1031 ERR_FAIL_COND_V(!is_inside_tree(), Matrix32());
1032
1033 if (canvas_layer)
1034 return canvas_layer->get_transform();
1035 else if (get_parent()->cast_to<CanvasItem>())
1036 return get_parent()->cast_to<CanvasItem>()->get_canvas_transform();
1037 else
1038 return get_viewport()->get_canvas_transform();
1039 }
1040
get_viewport_transform() const1041 Matrix32 CanvasItem::get_viewport_transform() const {
1042
1043 ERR_FAIL_COND_V(!is_inside_tree(), Matrix32());
1044
1045 if (canvas_layer) {
1046
1047 if (get_viewport()) {
1048 return get_viewport()->get_final_transform() * canvas_layer->get_transform();
1049 } else {
1050 return canvas_layer->get_transform();
1051 }
1052
1053 } else {
1054 return get_viewport()->get_final_transform() * get_viewport()->get_canvas_transform();
1055 }
1056 }
1057
set_notify_local_transform(bool p_enable)1058 void CanvasItem::set_notify_local_transform(bool p_enable) {
1059 notify_local_transform = p_enable;
1060 }
1061
is_local_transform_notification_enabled() const1062 bool CanvasItem::is_local_transform_notification_enabled() const {
1063 return notify_local_transform;
1064 }
1065
get_canvas_layer() const1066 int CanvasItem::get_canvas_layer() const {
1067
1068 if (canvas_layer)
1069 return canvas_layer->get_layer();
1070 else
1071 return 0;
1072 }
1073
get_item_and_children_rect() const1074 Rect2 CanvasItem::get_item_and_children_rect() const {
1075
1076 Rect2 rect = get_item_rect();
1077
1078 for (int i = 0; i < get_child_count(); i++) {
1079 CanvasItem *c = get_child(i)->cast_to<CanvasItem>();
1080 if (c) {
1081 Rect2 sir = c->get_transform().xform(c->get_item_and_children_rect());
1082 rect = rect.merge(sir);
1083 }
1084 }
1085
1086 return rect;
1087 }
1088
CanvasItem()1089 CanvasItem::CanvasItem() :
1090 xform_change(this) {
1091
1092 canvas_item = VisualServer::get_singleton()->canvas_item_create();
1093 hidden = false;
1094 pending_update = false;
1095 opacity = 1;
1096 self_opacity = 1;
1097 toplevel = false;
1098 pending_children_sort = false;
1099 first_draw = false;
1100 blend_mode = BLEND_MODE_MIX;
1101 drawing = false;
1102 behind = false;
1103 block_transform_notify = false;
1104 // viewport=NULL;
1105 canvas_layer = NULL;
1106 use_parent_material = false;
1107 global_invalid = true;
1108 notify_local_transform = false;
1109 light_mask = 1;
1110
1111 C = NULL;
1112 }
1113
~CanvasItem()1114 CanvasItem::~CanvasItem() {
1115
1116 VisualServer::get_singleton()->free(canvas_item);
1117 }
1118