summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/joints_2d.cpp28
-rw-r--r--scene/2d/joints_2d.h6
-rw-r--r--scene/2d/parallax_background.cpp20
-rw-r--r--scene/2d/parallax_background.h4
-rw-r--r--scene/2d/ray_cast_2d.cpp17
-rw-r--r--scene/2d/ray_cast_2d.h4
-rw-r--r--scene/3d/baked_light_instance.cpp2
-rw-r--r--scene/3d/collision_polygon.cpp2
-rw-r--r--scene/gui/control.cpp15
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/gui/line_edit.cpp4
-rw-r--r--scene/gui/line_edit.h2
-rw-r--r--scene/gui/popup_menu.cpp14
-rw-r--r--scene/gui/rich_text_label.cpp18
-rw-r--r--scene/gui/tabs.cpp250
-rw-r--r--scene/gui/tabs.h20
-rw-r--r--scene/gui/text_edit.cpp5
-rw-r--r--scene/gui/text_edit.h1
-rw-r--r--scene/main/node.cpp2
-rw-r--r--scene/resources/packed_scene.cpp6
20 files changed, 390 insertions, 32 deletions
diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp
index c1e91c2ecd..1df936535f 100644
--- a/scene/2d/joints_2d.cpp
+++ b/scene/2d/joints_2d.cpp
@@ -126,7 +126,7 @@ void Joint2D::_bind_methods() {
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "node_a"), _SCS("set_node_a"),_SCS("get_node_a") );
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "node_b"), _SCS("set_node_b"),_SCS("get_node_b") );
- ADD_PROPERTY( PropertyInfo( Variant::REAL, "bias/bias",PROPERTY_HINT_RANGE,"0,0.9,0.01"), _SCS("set_bias"),_SCS("get_bias") );
+ ADD_PROPERTY( PropertyInfo( Variant::REAL, "bias/bias",PROPERTY_HINT_RANGE,"0,0.9,0.001"), _SCS("set_bias"),_SCS("get_bias") );
}
@@ -175,15 +175,37 @@ RID PinJoint2D::_configure_joint() {
//add a collision exception between both
Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
}
+ RID pj = Physics2DServer::get_singleton()->pin_joint_create(get_global_transform().get_origin(),body_a->get_rid(),body_b?body_b->get_rid():RID());
+ Physics2DServer::get_singleton()->pin_joint_set_param(pj, Physics2DServer::PIN_JOINT_SOFTNESS, softness);
+ return pj;
- return Physics2DServer::get_singleton()->pin_joint_create(get_global_transform().get_origin(),body_a->get_rid(),body_b?body_b->get_rid():RID());
+}
+
+void PinJoint2D::set_softness(real_t p_softness) {
+
+ softness=p_softness;
+ update();
+ if (get_joint().is_valid())
+ Physics2DServer::get_singleton()->pin_joint_set_param(get_joint(), Physics2DServer::PIN_JOINT_SOFTNESS, p_softness);
}
+real_t PinJoint2D::get_softness() const {
-PinJoint2D::PinJoint2D() {
+ return softness;
+}
+
+void PinJoint2D::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_softness","softness"), &PinJoint2D::set_softness);
+ ObjectTypeDB::bind_method(_MD("get_softness"), &PinJoint2D::get_softness);
+ ADD_PROPERTY( PropertyInfo( Variant::REAL, "softness", PROPERTY_HINT_EXP_RANGE,"0.00,16,0.01"), _SCS("set_softness"), _SCS("get_softness"));
+}
+
+PinJoint2D::PinJoint2D() {
+ softness = 0;
}
diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h
index ac72c6ce59..908e3a158e 100644
--- a/scene/2d/joints_2d.h
+++ b/scene/2d/joints_2d.h
@@ -72,13 +72,17 @@ class PinJoint2D : public Joint2D {
OBJ_TYPE(PinJoint2D,Joint2D);
+ real_t softness;
+
protected:
void _notification(int p_what);
virtual RID _configure_joint();
+ static void _bind_methods();
public:
-
+ void set_softness(real_t p_stiffness);
+ real_t get_softness() const;
PinJoint2D();
};
diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp
index 109546bde3..8bb4eb55ba 100644
--- a/scene/2d/parallax_background.cpp
+++ b/scene/2d/parallax_background.cpp
@@ -110,7 +110,10 @@ void ParallaxBackground::_update_scroll() {
if (!l)
continue;
- l->set_base_offset_and_scale(ofs,scale);
+ if (ignore_camera_zoom)
+ l->set_base_offset_and_scale(ofs, 1.0);
+ else
+ l->set_base_offset_and_scale(ofs, scale);
}
}
@@ -165,6 +168,18 @@ Point2 ParallaxBackground::get_limit_end() const {
return limit_end;
}
+void ParallaxBackground::set_ignore_camera_zoom(bool ignore){
+
+ ignore_camera_zoom = ignore;
+
+}
+
+bool ParallaxBackground::is_ignore_camera_zoom(){
+
+ return ignore_camera_zoom;
+
+}
+
void ParallaxBackground::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_camera_moved"),&ParallaxBackground::_camera_moved);
@@ -178,6 +193,8 @@ void ParallaxBackground::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_limit_begin"),&ParallaxBackground::get_limit_begin);
ObjectTypeDB::bind_method(_MD("set_limit_end","ofs"),&ParallaxBackground::set_limit_end);
ObjectTypeDB::bind_method(_MD("get_limit_end"),&ParallaxBackground::get_limit_end);
+ ObjectTypeDB::bind_method(_MD("set_ignore_camera_zoom"), &ParallaxBackground::set_ignore_camera_zoom);
+ ObjectTypeDB::bind_method(_MD("is_ignore_camera_zoom"), &ParallaxBackground::is_ignore_camera_zoom);
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/offset"),_SCS("set_scroll_offset"),_SCS("get_scroll_offset"));
@@ -185,6 +202,7 @@ void ParallaxBackground::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/base_scale"),_SCS("set_scroll_base_scale"),_SCS("get_scroll_base_scale"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/limit_begin"),_SCS("set_limit_begin"),_SCS("get_limit_begin"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/limit_end"),_SCS("set_limit_end"),_SCS("get_limit_end"));
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL, "scroll/ignore_camera_zoom"), _SCS("set_ignore_camera_zoom"), _SCS("is_ignore_camera_zoom"));
}
diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h
index 363236b2ad..8dede07a16 100644
--- a/scene/2d/parallax_background.h
+++ b/scene/2d/parallax_background.h
@@ -44,6 +44,7 @@ class ParallaxBackground : public CanvasLayer {
String group_name;
Point2 limit_begin;
Point2 limit_end;
+ bool ignore_camera_zoom;
void _update_scroll();
protected:
@@ -72,6 +73,9 @@ public:
void set_limit_end(const Point2& p_ofs);
Point2 get_limit_end() const;
+ void set_ignore_camera_zoom(bool ignore);
+ bool is_ignore_camera_zoom();
+
ParallaxBackground();
};
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 05594fd79c..acc4c620e6 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -53,6 +53,16 @@ uint32_t RayCast2D::get_layer_mask() const {
return layer_mask;
}
+void RayCast2D::set_type_mask(uint32_t p_mask) {
+
+ type_mask=p_mask;
+}
+
+uint32_t RayCast2D::get_type_mask() const {
+
+ return type_mask;
+}
+
bool RayCast2D::is_colliding() const{
return collided;
@@ -162,7 +172,7 @@ void RayCast2D::_notification(int p_what) {
Physics2DDirectSpaceState::RayResult rr;
- if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask)) {
+ if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask,type_mask)) {
collided=true;
against=rr.collider_id;
@@ -241,9 +251,13 @@ void RayCast2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&RayCast2D::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&RayCast2D::get_layer_mask);
+ ObjectTypeDB::bind_method(_MD("set_type_mask","mask"),&RayCast2D::set_type_mask);
+ ObjectTypeDB::bind_method(_MD("get_type_mask"),&RayCast2D::get_type_mask);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"type_mask",PROPERTY_HINT_FLAGS,"Static,Kinematic,Rigid,Character,Area"),_SCS("set_type_mask"),_SCS("get_type_mask"));
}
RayCast2D::RayCast2D() {
@@ -253,5 +267,6 @@ RayCast2D::RayCast2D() {
collided=false;
against_shape=0;
layer_mask=1;
+ type_mask=Physics2DDirectSpaceState::TYPE_MASK_COLLISION;
cast_to=Vector2(0,50);
}
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index c7616be523..8c3ce8b3b3 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -44,6 +44,7 @@ class RayCast2D : public Node2D {
Vector2 collision_normal;
Set<RID> exclude;
uint32_t layer_mask;
+ uint32_t type_mask;
Vector2 cast_to;
@@ -62,6 +63,9 @@ public:
void set_layer_mask(uint32_t p_mask);
uint32_t get_layer_mask() const;
+ void set_type_mask(uint32_t p_mask);
+ uint32_t get_type_mask() const;
+
bool is_colliding() const;
Object *get_collider() const;
int get_collider_shape() const;
diff --git a/scene/3d/baked_light_instance.cpp b/scene/3d/baked_light_instance.cpp
index b55093a779..1ae7866f0b 100644
--- a/scene/3d/baked_light_instance.cpp
+++ b/scene/3d/baked_light_instance.cpp
@@ -81,7 +81,7 @@ float BakedLightSampler::get_param(Param p_param) const{
void BakedLightSampler::set_resolution(int p_resolution){
- ERR_FAIL_COND(p_resolution<4 && p_resolution>32);
+ ERR_FAIL_COND(p_resolution<4 || p_resolution>32);
resolution=p_resolution;
VS::get_singleton()->baked_light_sampler_set_resolution(base,resolution);
}
diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp
index c857b4851a..bb0a1fca12 100644
--- a/scene/3d/collision_polygon.cpp
+++ b/scene/3d/collision_polygon.cpp
@@ -126,7 +126,7 @@ void CollisionPolygon::_notification(int p_what) {
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
- if (!can_update_body && shape_from>=0 && shape_from>=0) {
+ if (!can_update_body && shape_from>=0 && shape_to>=0) {
CollisionObject *co = get_parent()->cast_to<CollisionObject>();
if (co) {
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index a1c0644650..bd6b8078ff 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2713,6 +2713,21 @@ void Control::warp_mouse(const Point2& p_to_pos) {
get_viewport()->warp_mouse(get_global_transform().xform(p_to_pos));
}
+
+bool Control::is_text_field() const {
+/*
+ if (get_script_instance()) {
+ Variant v=p_point;
+ const Variant *p[2]={&v,&p_data};
+ Variant::CallError ce;
+ Variant ret = get_script_instance()->call("is_text_field",p,2,ce);
+ if (ce.error==Variant::CallError::CALL_OK)
+ return ret;
+ }
+ */
+ return false;
+}
+
void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_window_input_event"),&Control::_window_input_event);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index a759fafbc9..4311b299c8 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -382,6 +382,8 @@ public:
void warp_mouse(const Point2& p_to_pos);
+ virtual bool is_text_field() const;
+
Control();
~Control();
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index fec9e401f1..2b4d7db01e 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -782,6 +782,10 @@ void LineEdit::select(int p_from, int p_to) {
update();
}
+bool LineEdit::is_text_field() const {
+
+ return true;
+}
void LineEdit::_bind_methods() {
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index c19043e826..b1c4c8f616 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -112,6 +112,8 @@ public:
void select(int p_from=0, int p_to=-1);
virtual Size2 get_minimum_size() const;
+
+ virtual bool is_text_field() const;
LineEdit();
~LineEdit();
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index e706053592..6c21ea639f 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -323,8 +323,10 @@ void PopupMenu::_input_event(const InputEvent &p_event) {
invalidated_click=false;
break;
}
- if (over<0 || items[over].separator || items[over].disabled)
+ if (over<0 || items[over].separator || items[over].disabled) {
+ hide();
break; //non-activable
+ }
if (items[over].submenu!="") {
@@ -738,10 +740,18 @@ int PopupMenu::find_item_by_accelerator(uint32_t p_accel) const {
void PopupMenu::activate_item(int p_item) {
-
ERR_FAIL_INDEX(p_item,items.size());
ERR_FAIL_COND(items[p_item].separator);
emit_signal("item_pressed",items[p_item].ID);
+
+ //hide all parent PopupMenue's
+ Node *next = get_parent();
+ PopupMenu *pop = next->cast_to<PopupMenu>();
+ while (pop) {
+ pop->hide();
+ next = next->get_parent();
+ pop = next->cast_to<PopupMenu>();
+ }
hide();
}
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 7a607786ee..ef6a2ba6aa 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1503,10 +1503,10 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) {
void RichTextLabel::scroll_to_line(int p_line) {
+ p_line -= 1;
ERR_FAIL_INDEX(p_line,lines.size());
_validate_line_caches();
- vscroll->set_val(lines[p_line].height_accum_cache);
-
+ vscroll->set_val(lines[p_line].height_accum_cache-lines[p_line].height_cache);
}
@@ -1569,27 +1569,23 @@ bool RichTextLabel::search(const String& p_string,bool p_from_selection) {
it=_get_next_item(it);
}
- if (!it)
- line=lines.size()-1;
}
- scroll_to_line(line-2);
+ if (line > 1) {
+ line-=1;
+ }
+
+ scroll_to_line(line);
return true;
}
- } else if (it->type==ITEM_NEWLINE) {
-
- line=static_cast<ItemNewline*>(it)->line;
}
-
it=_get_next_item(it);
charidx=0;
}
-
-
return false;
}
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index a849d3ae72..6d84f028b3 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -64,6 +64,15 @@ Size2 Tabs::get_minimum_size() const {
ms.width+=bms.width;
ms.height=MAX(bms.height+tab_bg->get_minimum_size().height,ms.height);
}
+
+ if (tabs[i].close_button.is_valid()) {
+ Ref<Texture> cb=tabs[i].close_button;
+ Size2 bms = cb->get_size()+get_stylebox("button")->get_minimum_size();
+ bms.width+=get_constant("hseparation");
+
+ ms.width+=bms.width;
+ ms.height=MAX(bms.height+tab_bg->get_minimum_size().height,ms.height);
+ }
}
return ms;
@@ -77,22 +86,48 @@ void Tabs::_input_event(const InputEvent& p_event) {
Point2 pos( p_event.mouse_motion.x, p_event.mouse_motion.y );
- int hover=-1;
+ int hover_buttons=-1;
+ hover=-1;
for(int i=0;i<tabs.size();i++) {
+ // test hovering tab to display close button if policy says so
+ if (cb_displaypolicy == SHOW_HOVER) {
+ int ofs=tabs[i].ofs_cache;
+ int size = tabs[i].ofs_cache;
+ if (pos.x >=tabs[i].ofs_cache && pos.x<tabs[i].ofs_cache+tabs[i].size_cache) {
+ hover=i;
+ }
+ }
+
+
+ // test hovering right button and close button
if (tabs[i].rb_rect.has_point(pos)) {
- hover=i;
+ rb_hover=i;
+ hover_buttons = i;
break;
}
+ else if (tabs[i].cb_rect.has_point(pos)) {
+ cb_hover=i;
+ hover_buttons = i;
+ break;
+ }
+
+
+
}
- if (hover!=rb_hover) {
- rb_hover=hover;
- update();
+ if (hover_buttons == -1) { // no hover
+ rb_hover= hover_buttons;
+ cb_hover= hover_buttons;
}
+ update();
+
return;
}
+
+
+
if (rb_pressing && p_event.type==InputEvent::MOUSE_BUTTON &&
!p_event.mouse_button.pressed &&
p_event.mouse_button.button_index==BUTTON_LEFT) {
@@ -106,6 +141,20 @@ void Tabs::_input_event(const InputEvent& p_event) {
update();
}
+ if (cb_pressing && p_event.type==InputEvent::MOUSE_BUTTON &&
+ !p_event.mouse_button.pressed &&
+ p_event.mouse_button.button_index==BUTTON_LEFT) {
+
+ if (cb_hover!=-1) {
+ //pressed
+ emit_signal("tab_close",cb_hover);
+ }
+
+ cb_pressing=false;
+ update();
+ }
+
+
if (p_event.type==InputEvent::MOUSE_BUTTON &&
p_event.mouse_button.pressed &&
p_event.mouse_button.button_index==BUTTON_LEFT) {
@@ -122,6 +171,12 @@ void Tabs::_input_event(const InputEvent& p_event) {
return;
}
+ if (tabs[i].cb_rect.has_point(pos)) {
+ cb_pressing=true;
+ update();
+ return;
+ }
+
int ofs=tabs[i].ofs_cache;
int size = tabs[i].ofs_cache;
if (pos.x >=tabs[i].ofs_cache && pos.x<tabs[i].ofs_cache+tabs[i].size_cache) {
@@ -148,6 +203,8 @@ void Tabs::_notification(int p_what) {
case NOTIFICATION_MOUSE_EXIT: {
rb_hover=-1;
+ cb_hover=-1;
+ hover=-1;
update();
} break;
case NOTIFICATION_DRAW: {
@@ -186,7 +243,7 @@ void Tabs::_notification(int p_what) {
String s = tabs[i].text;
int lsize=0;
- int slen=font->get_string_size(s).width;;
+ int slen=font->get_string_size(s).width;
lsize+=slen;
Ref<Texture> icon;
@@ -211,6 +268,56 @@ void Tabs::_notification(int p_what) {
}
+ // Close button
+ switch (cb_displaypolicy) {
+ case SHOW_ALWAYS: {
+ if (tabs[i].close_button.is_valid()) {
+ Ref<StyleBox> style = get_stylebox("button");
+ Ref<Texture> rb=tabs[i].close_button;
+
+ lsize+=get_constant("hseparation");
+ lsize+=style->get_margin(MARGIN_LEFT);
+ lsize+=rb->get_width();
+ lsize+=style->get_margin(MARGIN_RIGHT);
+
+ }
+ } break;
+ case SHOW_ACTIVE_ONLY: {
+ if (i==current) {
+ if (tabs[i].close_button.is_valid()) {
+ Ref<StyleBox> style = get_stylebox("button");
+ Ref<Texture> rb=tabs[i].close_button;
+
+ lsize+=get_constant("hseparation");
+ lsize+=style->get_margin(MARGIN_LEFT);
+ lsize+=rb->get_width();
+ lsize+=style->get_margin(MARGIN_RIGHT);
+
+ }
+ }
+ } break;
+ case SHOW_HOVER: {
+ if (i==current || i==hover) {
+ if (tabs[i].close_button.is_valid()) {
+ Ref<StyleBox> style = get_stylebox("button");
+ Ref<Texture> rb=tabs[i].close_button;
+
+ lsize+=get_constant("hseparation");
+ lsize+=style->get_margin(MARGIN_LEFT);
+ lsize+=rb->get_width();
+ lsize+=style->get_margin(MARGIN_RIGHT);
+
+ }
+ }
+ } break;
+ case SHOW_NEVER: // by default, never show close button
+ default: {
+ // do nothing
+ } break;
+
+ }
+
+
Ref<StyleBox> sb;
int va;
Color col;
@@ -273,6 +380,103 @@ void Tabs::_notification(int p_what) {
}
+
+
+
+ // Close button
+ switch (cb_displaypolicy) {
+ case SHOW_ALWAYS: {
+ if (tabs[i].close_button.is_valid()) {
+ Ref<StyleBox> style = get_stylebox("button");
+ Ref<Texture> cb=tabs[i].close_button;
+
+ w+=get_constant("hseparation");
+
+ Rect2 cb_rect;
+ cb_rect.size=style->get_minimum_size()+cb->get_size();
+ cb_rect.pos.x=w;
+ cb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(cb_rect.size.y))/2;
+
+ if (cb_hover==i) {
+ if (cb_pressing)
+ get_stylebox("button_pressed")->draw(ci,cb_rect);
+ else
+ style->draw(ci,cb_rect);
+ }
+
+ w+=style->get_margin(MARGIN_LEFT);
+
+ cb->draw(ci,Point2i( w,cb_rect.pos.y+style->get_margin(MARGIN_TOP) ));
+ w+=cb->get_width();
+ w+=style->get_margin(MARGIN_RIGHT);
+ tabs[i].cb_rect=cb_rect;
+ }
+ } break;
+ case SHOW_ACTIVE_ONLY: {
+ if (current==i) {
+ if (tabs[i].close_button.is_valid()) {
+ Ref<StyleBox> style = get_stylebox("button");
+ Ref<Texture> cb=tabs[i].close_button;
+
+ w+=get_constant("hseparation");
+
+ Rect2 cb_rect;
+ cb_rect.size=style->get_minimum_size()+cb->get_size();
+ cb_rect.pos.x=w;
+ cb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(cb_rect.size.y))/2;
+
+ if (cb_hover==i) {
+ if (cb_pressing)
+ get_stylebox("button_pressed")->draw(ci,cb_rect);
+ else
+ style->draw(ci,cb_rect);
+ }
+
+ w+=style->get_margin(MARGIN_LEFT);
+
+ cb->draw(ci,Point2i( w,cb_rect.pos.y+style->get_margin(MARGIN_TOP) ));
+ w+=cb->get_width();
+ w+=style->get_margin(MARGIN_RIGHT);
+ tabs[i].cb_rect=cb_rect;
+ }
+ }
+ } break;
+ case SHOW_HOVER: {
+ if (current==i || hover==i) {
+ if (tabs[i].close_button.is_valid()) {
+ Ref<StyleBox> style = get_stylebox("button");
+ Ref<Texture> cb=tabs[i].close_button;
+
+ w+=get_constant("hseparation");
+
+ Rect2 cb_rect;
+ cb_rect.size=style->get_minimum_size()+cb->get_size();
+ cb_rect.pos.x=w;
+ cb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(cb_rect.size.y))/2;
+
+ if (cb_hover==i) {
+ if (cb_pressing)
+ get_stylebox("button_pressed")->draw(ci,cb_rect);
+ else
+ style->draw(ci,cb_rect);
+ }
+
+ w+=style->get_margin(MARGIN_LEFT);
+
+ cb->draw(ci,Point2i( w,cb_rect.pos.y+style->get_margin(MARGIN_TOP) ));
+ w+=cb->get_width();
+ w+=style->get_margin(MARGIN_RIGHT);
+ tabs[i].cb_rect=cb_rect;
+ }
+ }
+ } break;
+ case SHOW_NEVER:
+ default: {
+ // show nothing
+ } break;
+
+ }
+
w+=sb->get_margin(MARGIN_RIGHT);
tabs[i].size_cache=w-tabs[i].ofs_cache;
@@ -358,11 +562,29 @@ Ref<Texture> Tabs::get_tab_right_button(int p_tab) const{
}
+void Tabs::set_tab_close_button(int p_tab, const Ref<Texture>& p_close_button) {
+ ERR_FAIL_INDEX(p_tab, tabs.size());
+ tabs[p_tab].close_button=p_close_button;
+ update();
+ minimum_size_changed();
+}
+
+
+Ref<Texture> Tabs::get_tab_close_button(int p_tab) const{
+
+ ERR_FAIL_INDEX_V(p_tab,tabs.size(),Ref<Texture>());
+ return tabs[p_tab].close_button;
+
+}
+
void Tabs::add_tab(const String& p_str,const Ref<Texture>& p_icon) {
Tab t;
t.text=p_str;
t.icon=p_icon;
+
+ t.close_button = get_icon("Close","EditorIcons");
+
tabs.push_back(t);
update();
@@ -394,6 +616,11 @@ void Tabs::remove_tab(int p_idx) {
}
+void Tabs::set_tab_close_display_policy(CloseButtonDisplayPolicy p_cb_displaypolicy) {
+ cb_displaypolicy = p_cb_displaypolicy;
+}
+
+
void Tabs::set_tab_align(TabAlign p_align) {
tab_align=p_align;
@@ -423,14 +650,22 @@ void Tabs::_bind_methods() {
ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab")));
ADD_SIGNAL(MethodInfo("right_button_pressed",PropertyInfo(Variant::INT,"tab")));
+ ADD_SIGNAL(MethodInfo("tab_close",PropertyInfo(Variant::INT,"tab")));
+
ADD_PROPERTY( PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE,"-1,4096,1",PROPERTY_USAGE_EDITOR), _SCS("set_current_tab"), _SCS("get_current_tab") );
BIND_CONSTANT( ALIGN_LEFT );
BIND_CONSTANT( ALIGN_CENTER );
BIND_CONSTANT( ALIGN_RIGHT );
+
+ BIND_CONSTANT( SHOW_ACTIVE_ONLY );
+ BIND_CONSTANT( SHOW_ALWAYS );
+ BIND_CONSTANT( SHOW_HOVER );
+ BIND_CONSTANT( SHOW_NEVER );
}
+
Tabs::Tabs() {
current=0;
@@ -438,4 +673,7 @@ Tabs::Tabs() {
rb_hover=-1;
rb_pressing=false;
+ cb_hover=-1;
+ cb_pressing=false;
+ cb_displaypolicy = SHOW_NEVER; // Default : no close button
}
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 5cb0d9e916..1a8352bc93 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -42,6 +42,14 @@ public:
ALIGN_CENTER,
ALIGN_RIGHT
};
+
+ enum CloseButtonDisplayPolicy {
+
+ SHOW_ALWAYS,
+ SHOW_ACTIVE_ONLY,
+ SHOW_HOVER,
+ SHOW_NEVER
+ };
private:
@@ -53,6 +61,8 @@ private:
int size_cache;
Ref<Texture> right_button;
Rect2 rb_rect;
+ Ref<Texture> close_button;
+ Rect2 cb_rect;
};
Vector<Tab> tabs;
@@ -63,6 +73,12 @@ private:
int rb_hover;
bool rb_pressing;
+ int cb_hover;
+ bool cb_pressing;
+ CloseButtonDisplayPolicy cb_displaypolicy;
+
+ int hover; // hovered tab
+
protected:
void _input_event(const InputEvent& p_event);
@@ -82,6 +98,10 @@ public:
void set_tab_right_button(int p_tab,const Ref<Texture>& p_right_button);
Ref<Texture> get_tab_right_button(int p_tab) const;
+ void set_tab_close_button(int p_tab, const Ref<Texture>& p_close_button);
+ Ref<Texture> get_tab_close_button(int p_tab) const;
+ void set_tab_close_display_policy(CloseButtonDisplayPolicy p_cb_displaypolicy);
+
void set_tab_align(TabAlign p_align);
TabAlign get_tab_align() const;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index b5fdde30cd..be6c0d0a8b 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -709,7 +709,7 @@ void TextEdit::_notification(int p_what) {
if (in_region==-1 && !in_keyword && is_char && !prev_is_char) {
int to=j;
- while(_is_text_char(str[to]) && to<str.length())
+ while(to<str.length() && _is_text_char(str[to]))
to++;
uint32_t hash = String::hash(&str[j],to-j);
@@ -3568,7 +3568,10 @@ void TextEdit::set_show_line_numbers(bool p_show) {
update();
}
+bool TextEdit::is_text_field() const {
+ return true;
+}
void TextEdit::_bind_methods() {
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 1b448bb782..9ffe8a5bae 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -393,6 +393,7 @@ public:
String get_text_for_completion();
+ virtual bool is_text_field() const;
TextEdit();
~TextEdit();
};
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index dd4587c19f..631dc8dcc7 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1993,7 +1993,7 @@ void Node::_bind_methods() {
ObjectTypeDB::bind_method(_MD("has_node","path"),&Node::has_node);
ObjectTypeDB::bind_method(_MD("get_node:Node","path"),&Node::get_node);
ObjectTypeDB::bind_method(_MD("get_parent:Parent"),&Node::get_parent);
- ObjectTypeDB::bind_method(_MD("find_node:Node","mask","recursive","owned"),&Node::get_node,DEFVAL(true),DEFVAL(true));
+ ObjectTypeDB::bind_method(_MD("find_node:Node","mask","recursive","owned"),&Node::find_node,DEFVAL(true),DEFVAL(true));
ObjectTypeDB::bind_method(_MD("has_node_and_resource","path"),&Node::has_node_and_resource);
ObjectTypeDB::bind_method(_MD("get_node_and_resource","path"),&Node::_get_node_and_resource);
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index a9dc0e8bfb..fdf1692495 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -101,7 +101,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
if (i==0 && base_scene_idx>=0) {
//scene inheritance on root node
- print_line("scene inherit");
+ //print_line("scene inherit");
Ref<PackedScene> sdata = props[ base_scene_idx ];
ERR_FAIL_COND_V( !sdata.is_valid(), NULL);
node = sdata->instance(p_gen_edit_state);
@@ -112,7 +112,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
} else if (n.instance>=0) {
//instance a scene into this node
- print_line("instance");
+ //print_line("instance");
if (n.instance&FLAG_INSTANCE_IS_PLACEHOLDER) {
String path = props[n.instance&FLAG_MASK];
@@ -148,7 +148,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
#endif
}
} else if (ObjectTypeDB::is_type_enabled(snames[n.type])) {
- print_line("created");
+ //print_line("created");
//node belongs to this scene and must be created
Object * obj = ObjectTypeDB::instance(snames[ n.type ]);
if (!obj || !obj->cast_to<Node>()) {