diff options
Diffstat (limited to 'scene/gui')
89 files changed, 1500 insertions, 471 deletions
diff --git a/scene/gui/SCsub b/scene/gui/SCsub index 055d2f2474..bbe59b3054 100644 --- a/scene/gui/SCsub +++ b/scene/gui/SCsub @@ -3,5 +3,3 @@ Import('env') env.add_source_files(env.scene_sources,"*.cpp") Export('env') - - diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 0c63a3bc74..698dbce2b5 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index e187a85eae..83c66326c5 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index b63b3de530..6fff90809e 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h index c357814baf..6e63e8bdac 100644 --- a/scene/gui/box_container.h +++ b/scene/gui/box_container.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index edeb18bfc1..b9ce46d738 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -137,8 +137,10 @@ void Button::_notification(int p_what) { text_ofs.y+=font->get_ascent(); font->draw( ci, text_ofs.floor(), text, color,clip_text?text_clip:-1); if (!_icon.is_null()) { + + int valign = size.height-style->get_minimum_size().y; - _icon->draw(ci,Point2(style->get_offset().x, Math::floor( (size.height-_icon->get_height())/2.0 ) ),is_disabled()?Color(1,1,1,0.4):Color(1,1,1) ); + _icon->draw(ci,style->get_offset()+Point2(0, Math::floor( (valign-_icon->get_height())/2.0 ) ),is_disabled()?Color(1,1,1,0.4):Color(1,1,1) ); } diff --git a/scene/gui/button.h b/scene/gui/button.h index 690179b90c..bd244f5087 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/button_array.cpp b/scene/gui/button_array.cpp index b86e32dda7..9e3476899f 100644 --- a/scene/gui/button_array.cpp +++ b/scene/gui/button_array.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/button_array.h b/scene/gui/button_array.h index ea2c1e4968..39661eaabd 100644 --- a/scene/gui/button_array.h +++ b/scene/gui/button_array.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/button_group.cpp b/scene/gui/button_group.cpp index c92d7f2696..04ba5fc06d 100644 --- a/scene/gui/button_group.cpp +++ b/scene/gui/button_group.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/button_group.h b/scene/gui/button_group.h index 74e847e937..38c61991b7 100644 --- a/scene/gui/button_group.h +++ b/scene/gui/button_group.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp index 8a22a38980..844175e4c1 100644 --- a/scene/gui/center_container.cpp +++ b/scene/gui/center_container.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/center_container.h b/scene/gui/center_container.h index 4d8d06ac8c..dc95533525 100644 --- a/scene/gui/center_container.h +++ b/scene/gui/center_container.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp index 2aa82bc5f5..1381d6eb60 100644 --- a/scene/gui/check_box.cpp +++ b/scene/gui/check_box.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h index 171fd55351..95dd4891d4 100644 --- a/scene/gui/check_box.h +++ b/scene/gui/check_box.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp index d765aefe5e..ecaea251a5 100644 --- a/scene/gui/check_button.cpp +++ b/scene/gui/check_button.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h index b90bb31c2d..022ade2193 100644 --- a/scene/gui/check_button.h +++ b/scene/gui/check_button.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index c30d473610..7d6c986d96 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 0756e88cf2..95c26a9c6f 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index 6c74bc3977..920c6bf1e6 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -52,6 +52,14 @@ void Container::add_child_notify(Node *p_child) { } +void Container::move_child_notify(Node *p_child) { + + if (!p_child->cast_to<Control>()) + return; + + queue_sort(); +} + void Container::remove_child_notify(Node *p_child) { @@ -97,6 +105,8 @@ void Container::fit_child_in_rect(Control *p_child,const Rect2& p_rect) { p_child->set_pos(r.pos); p_child->set_size(r.size); + p_child->set_rotation(0); + p_child->set_scale(Vector2(1,1)); } void Container::queue_sort() { diff --git a/scene/gui/container.h b/scene/gui/container.h index ba9bf2d60f..1c7587c155 100644 --- a/scene/gui/container.h +++ b/scene/gui/container.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -42,6 +42,7 @@ protected: void queue_sort(); virtual void add_child_notify(Node *p_child); + virtual void move_child_notify(Node *p_child); virtual void remove_child_notify(Node *p_child); void _notification(int p_what); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index bd6b8078ff..23a7ae00da 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -580,8 +580,8 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_DRAW: { - Matrix32 xform; - xform.set_origin(get_pos()); + Matrix32 xform=Matrix32(data.rotation,get_pos()); + xform.scale_basis(data.scale); VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(),xform); VisualServer::get_singleton()->canvas_item_set_custom_rect( get_canvas_item(),true, Rect2(Point2(),get_size())); //emit_signal(SceneStringNames::get_singleton()->draw); @@ -916,6 +916,7 @@ void Control::_window_show_tooltip() { void Control::_window_call_input(Control *p_control,const InputEvent& p_input) { + _block(); while(p_control) { @@ -932,6 +933,9 @@ void Control::_window_call_input(Control *p_control,const InputEvent& p_input) { break; p_control=p_control->data.parent; } + + _unblock(); + } void Control::_window_input_event(InputEvent p_event) { @@ -1067,6 +1071,7 @@ void Control::_window_input_event(InputEvent p_event) { Size2 pos = mpos; pos = window->focus_inv_xform.xform(pos); + window->mouse_over->drop_data(pos,window->drag_data); window->drag_data=Variant(); //change mouse accordingly @@ -1927,6 +1932,7 @@ void Control::set_size(const Size2& p_size) { data.margin[3] = _s2a( y+h, data.anchor[3], ph ); _size_changed(); + } @@ -2412,9 +2418,9 @@ Control::CursorShape Control::get_cursor_shape(const Point2& p_pos) const { Matrix32 Control::get_transform() const { - Matrix32 xf; - xf.set_origin(get_pos()); - return xf; + Matrix32 xform=Matrix32(data.rotation,get_pos()); + xform.scale_basis(data.scale); + return xform; } String Control::_get_tooltip() const { @@ -2728,6 +2734,39 @@ bool Control::is_text_field() const { return false; } + +void Control::_set_rotation_deg(float p_rot) { + set_rotation(Math::deg2rad(p_rot)); +} + +float Control::_get_rotation_deg() const { + return Math::rad2deg(get_rotation()); +} + +void Control::set_rotation(float p_rotation) { + + data.rotation=p_rotation; + update(); + _notify_transform(); +} + +float Control::get_rotation() const{ + + return data.rotation; +} + +void Control::set_scale(const Vector2& p_scale){ + + data.scale=p_scale; + update(); + _notify_transform(); +} +Vector2 Control::get_scale() const{ + + return data.scale; +} + + void Control::_bind_methods() { ObjectTypeDB::bind_method(_MD("_window_input_event"),&Control::_window_input_event); @@ -2756,15 +2795,21 @@ void Control::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_size","size"),&Control::set_size); ObjectTypeDB::bind_method(_MD("set_custom_minimum_size","size"),&Control::set_custom_minimum_size); ObjectTypeDB::bind_method(_MD("set_global_pos","pos"),&Control::set_global_pos); + ObjectTypeDB::bind_method(_MD("set_rotation","rotation"),&Control::set_rotation); + ObjectTypeDB::bind_method(_MD("_set_rotation_deg","rotation"),&Control::_set_rotation_deg); + ObjectTypeDB::bind_method(_MD("set_scale","scale"),&Control::set_scale); ObjectTypeDB::bind_method(_MD("get_margin","margin"),&Control::get_margin); ObjectTypeDB::bind_method(_MD("get_begin"),&Control::get_begin); ObjectTypeDB::bind_method(_MD("get_end"),&Control::get_end); ObjectTypeDB::bind_method(_MD("get_pos"),&Control::get_pos); ObjectTypeDB::bind_method(_MD("get_size"),&Control::get_size); + ObjectTypeDB::bind_method(_MD("get_rotation"),&Control::get_rotation); + ObjectTypeDB::bind_method(_MD("get_scale"),&Control::get_scale); ObjectTypeDB::bind_method(_MD("get_custom_minimum_size"),&Control::get_custom_minimum_size); ObjectTypeDB::bind_method(_MD("get_parent_area_size"),&Control::get_size); ObjectTypeDB::bind_method(_MD("get_global_pos"),&Control::get_global_pos); ObjectTypeDB::bind_method(_MD("get_rect"),&Control::get_rect); + ObjectTypeDB::bind_method(_MD("_get_rotation_deg"),&Control::_get_rotation_deg); ObjectTypeDB::bind_method(_MD("get_global_rect"),&Control::get_global_rect); ObjectTypeDB::bind_method(_MD("set_area_as_parent_rect","margin"),&Control::set_area_as_parent_rect,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("show_modal","exclusive"),&Control::show_modal,DEFVAL(false)); @@ -2846,6 +2891,8 @@ void Control::_bind_methods() { ADD_PROPERTYNZ( PropertyInfo(Variant::VECTOR2,"rect/pos", PROPERTY_HINT_NONE, "",PROPERTY_USAGE_EDITOR), _SCS("set_pos"),_SCS("get_pos") ); ADD_PROPERTYNZ( PropertyInfo(Variant::VECTOR2,"rect/size", PROPERTY_HINT_NONE, "",PROPERTY_USAGE_EDITOR), _SCS("set_size"),_SCS("get_size") ); ADD_PROPERTYNZ( PropertyInfo(Variant::VECTOR2,"rect/min_size"), _SCS("set_custom_minimum_size"),_SCS("get_custom_minimum_size") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::REAL,"rect/rotation",PROPERTY_HINT_RANGE,"-1080,1080,0.01"), _SCS("_set_rotation_deg"),_SCS("_get_rotation_deg") ); + ADD_PROPERTYNO( PropertyInfo(Variant::VECTOR2,"rect/scale"), _SCS("set_scale"),_SCS("get_scale") ); ADD_PROPERTYNZ( PropertyInfo(Variant::STRING,"hint/tooltip", PROPERTY_HINT_MULTILINE_TEXT), _SCS("set_tooltip"),_SCS("_get_tooltip") ); ADD_PROPERTYINZ( PropertyInfo(Variant::NODE_PATH,"focus_neighbour/left" ), _SCS("set_focus_neighbour"),_SCS("get_focus_neighbour"),MARGIN_LEFT ); ADD_PROPERTYINZ( PropertyInfo(Variant::NODE_PATH,"focus_neighbour/top" ), _SCS("set_focus_neighbour"),_SCS("get_focus_neighbour"),MARGIN_TOP ); @@ -2928,6 +2975,8 @@ Control::Control() { data.v_size_flags=SIZE_FILL; data.expand=1; data.pending_min_size_update=false; + data.rotation=0; + data.scale=Vector2(1,1); for (int i=0;i<4;i++) { diff --git a/scene/gui/control.h b/scene/gui/control.h index 4311b299c8..280e88e85d 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -107,7 +107,10 @@ private: float margin[4]; AnchorType anchor[4]; - FocusMode focus_mode; + FocusMode focus_mode; + + float rotation; + Vector2 scale; bool pending_resize; @@ -211,6 +214,8 @@ private: void _size_changed(); String _get_tooltip() const; + void _set_rotation_deg(float p_rot); + float _get_rotation_deg() const; protected: bool window_has_modal_stack() const; @@ -299,6 +304,13 @@ public: Rect2 get_rect() const; Rect2 get_global_rect() const; Rect2 get_window_rect() const; ///< use with care, as it blocks waiting for the visual server + + void set_rotation(float p_rotation); + float get_rotation() const; + + void set_scale(const Vector2& p_scale); + Vector2 get_scale() const; + void set_area_as_parent_rect(int p_margin=0); @@ -382,7 +394,7 @@ public: void warp_mouse(const Point2& p_to_pos); - virtual bool is_text_field() const; + virtual bool is_text_field() const; Control(); ~Control(); diff --git a/scene/gui/custom_button.cpp b/scene/gui/custom_button.cpp index 53a3bf0914..a70af05418 100644 --- a/scene/gui/custom_button.cpp +++ b/scene/gui/custom_button.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/custom_button.h b/scene/gui/custom_button.h index 49fcf7408f..2492750489 100644 --- a/scene/gui/custom_button.h +++ b/scene/gui/custom_button.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 0c0f924f52..9f08b6f845 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -308,7 +308,9 @@ void AcceptDialog::_bind_methods() { ADD_SIGNAL( MethodInfo("confirmed") ); ADD_SIGNAL( MethodInfo("custom_action",PropertyInfo(Variant::STRING,"action")) ); - + ADD_PROPERTYNZ( PropertyInfo(Variant::STRING,"dialog/text",PROPERTY_HINT_MULTILINE_TEXT,"",PROPERTY_USAGE_DEFAULT_INTL),_SCS("set_text"),_SCS("get_text")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "dialog/hide_on_ok"),_SCS("set_hide_on_ok"),_SCS("get_hide_on_ok") ); + } diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index 67c574a420..7c06ded866 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 8e428fd71c..955a02d0f9 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -46,6 +46,11 @@ VBoxContainer *FileDialog::get_vbox() { } void FileDialog::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + refresh->set_icon(get_icon("reload")); + } if (p_what==NOTIFICATION_DRAW) { @@ -618,7 +623,7 @@ void FileDialog::_update_drives() { } } -bool FileDialog::default_show_hidden_files=true; +bool FileDialog::default_show_hidden_files=false; void FileDialog::_bind_methods() { @@ -645,7 +650,7 @@ void FileDialog::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_vbox:VBoxContainer"),&FileDialog::get_vbox); ObjectTypeDB::bind_method(_MD("set_access","access"),&FileDialog::set_access); ObjectTypeDB::bind_method(_MD("get_access"),&FileDialog::get_access); - ObjectTypeDB::bind_method(_MD("set_show_hidden_files"),&FileDialog::set_show_hidden_files); + ObjectTypeDB::bind_method(_MD("set_show_hidden_files","show"),&FileDialog::set_show_hidden_files); ObjectTypeDB::bind_method(_MD("is_showing_hidden_files"),&FileDialog::is_showing_hidden_files); ObjectTypeDB::bind_method(_MD("_select_drive"),&FileDialog::_select_drive); ObjectTypeDB::bind_method(_MD("_make_dir"),&FileDialog::_make_dir); @@ -700,6 +705,10 @@ FileDialog::FileDialog() { pathhb->add_child(dir); dir->set_h_size_flags(SIZE_EXPAND_FILL); + refresh = memnew( ToolButton ); + refresh->connect("pressed",this,"_update_file_list"); + pathhb->add_child(refresh); + drives = memnew( OptionButton ); pathhb->add_child(drives); drives->connect("item_selected",this,"_select_drive"); diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index ec42c7744a..491655e4ce 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,6 +34,7 @@ #include "scene/gui/line_edit.h" #include "scene/gui/option_button.h" #include "scene/gui/dialogs.h" +#include "scene/gui/tool_button.h" #include "os/dir_access.h" #include "box_container.h" /** @@ -86,6 +87,8 @@ private: OptionButton *filter; DirAccess *dir_access; ConfirmationDialog *confirm_save; + + ToolButton *refresh; Vector<String> filters; diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index 105f66f368..a514f1b3d7 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h index 8d8bc27293..588bb17fa1 100644 --- a/scene/gui/grid_container.h +++ b/scene/gui/grid_container.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 40fade840c..f035cb7722 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -235,6 +235,37 @@ int ItemList::get_current() const { return current; } +void ItemList::move_item(int p_item,int p_to_pos) { + + ERR_FAIL_INDEX(p_item,items.size()); + ERR_FAIL_INDEX(p_to_pos,items.size()+1); + + Item it=items[p_item]; + items.remove(p_item);; + + if (p_to_pos>p_item) { + p_to_pos--; + } + + if (p_to_pos>=items.size()) { + items.push_back(it); + } else { + items.insert(p_to_pos,it); + } + + if (current<0) { + //do none + } if (p_item==current) { + current=p_to_pos; + } else if (p_to_pos>p_item && current>p_item && current<p_to_pos) { + current--; + } else if (p_to_pos<p_item && current<p_item && current>p_to_pos) { + current++; + } + + + update(); +} int ItemList::get_item_count() const{ diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index 7cf58a6426..bd3cf6484e 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -101,6 +101,7 @@ public: void set_current(int p_current); int get_current() const; + void move_item(int p_item,int p_to_pos); int get_item_count() const; void remove_item(int p_idx); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 002e49cbcf..e8097c79a4 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/label.h b/scene/gui/label.h index 4ea9f5d377..3c14add60d 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 2b4d7db01e..db463c133b 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -145,6 +145,13 @@ void LineEdit::_input_event(InputEvent p_event) { int old_cursor_pos = cursor_pos; text = undo_text; + + Ref<Font> font = get_font("font"); + + cached_width = 0; + for (int i = 0; i<text.length(); i++) + cached_width += font->get_char_size(text[i]).width; + if(old_cursor_pos > text.length()) { set_cursor_pos(text.length()); } else { @@ -164,6 +171,15 @@ void LineEdit::_input_event(InputEvent p_event) { selection_clear(); undo_text = text; text = text.substr(cursor_pos,text.length()-cursor_pos); + + Ref<Font> font = get_font("font"); + + cached_width = 0; + if (font != NULL) { + for (int i = 0; i < text.length(); i++) + cached_width += font->get_char_size(text[i]).width; + } + set_cursor_pos(0); emit_signal("text_changed",text); _change_notify("text"); @@ -192,6 +208,9 @@ void LineEdit::_input_event(InputEvent p_event) { } } break; + case (KEY_A): { //Select All + select(); + } break; default: { handled=false;} } @@ -303,6 +322,18 @@ void LineEdit::_input_event(InputEvent p_event) { } } +void LineEdit::set_align(Align p_align) { + + ERR_FAIL_INDEX(p_align, 4); + align = p_align; + update(); +} + +LineEdit::Align LineEdit::get_align() const{ + + return align; +} + Variant LineEdit::get_drag_data(const Point2& p_point) { if (selection.drag_attempt && selection.enabled) { @@ -325,7 +356,15 @@ void LineEdit::drop_data(const Point2& p_point,const Variant& p_data){ if (p_data.get_type()==Variant::STRING) { set_cursor_at_pixel_pos(p_point.x); int selected = selection.end - selection.begin; + + Ref<Font> font = get_font("font"); + if (font != NULL) { + for (int i = selection.begin; i < selection.end; i++) + cached_width -= font->get_char_size(text[i]).width; + } + text.erase(selection.begin, selected); + append_at_cursor(p_data); selection.begin = cursor_pos-selected; selection.end = cursor_pos; @@ -365,8 +404,25 @@ void LineEdit::_notification(int p_what) { get_stylebox("focus")->draw( ci, Rect2( Point2(), size ) ); } - - int ofs=style->get_offset().x; + int x_ofs=0; + + switch (align) { + + case ALIGN_FILL: + case ALIGN_LEFT: { + + x_ofs=style->get_offset().x; + } break; + case ALIGN_CENTER: { + + x_ofs=x_ofs=int(size.width-(cached_width))/2; + } break; + case ALIGN_RIGHT: { + + x_ofs=x_ofs=int(size.width-style->get_offset().x-(cached_width)); + } break; + } + int ofs_max=width-style->get_minimum_size().width; int char_ofs=window_pos; @@ -391,29 +447,29 @@ void LineEdit::_notification(int p_what) { int char_width=font->get_char_size( cchar,next ).width; // end of widget, break! - if ( (ofs+char_width) > ofs_max ) + if ((x_ofs + char_width) > ofs_max) break; bool selected=selection.enabled && char_ofs>=selection.begin && char_ofs<selection.end; if (selected) - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2( Point2( ofs , y_ofs ),Size2( char_width, y_area )),selection_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, y_area)), selection_color); - font->draw_char(ci,Point2( ofs , y_ofs+font_ascent ), cchar, next,selected?font_color_selected:font_color ); + font->draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, selected ? font_color_selected : font_color); if (char_ofs==cursor_pos && has_focus()) VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( - Point2( ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color ); + Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color ); - ofs+=char_width; + x_ofs+=char_width; char_ofs++; } if (char_ofs==cursor_pos && has_focus()) //may be at the end VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( - Point2( ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color ); + Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color ); } break; case NOTIFICATION_FOCUS_ENTER: { @@ -484,13 +540,36 @@ void LineEdit::shift_selection_check_post(bool p_shift) { void LineEdit::set_cursor_at_pixel_pos(int p_x) { - int ofs=window_pos; - int pixel_ofs=get_stylebox("normal")->get_offset().x; - Ref<Font> font=get_font("font"); + Ref<Font> font = get_font("font"); + int ofs = window_pos; + Ref<StyleBox> style = get_stylebox("normal"); + int pixel_ofs = 0; + Size2 size = get_size(); + + switch (align) { + + case ALIGN_FILL: + case ALIGN_LEFT: { + + pixel_ofs = int(style->get_offset().x); + } break; + case ALIGN_CENTER: { + + pixel_ofs=int(size.width-(cached_width))/2; + } break; + case ALIGN_RIGHT: { + + pixel_ofs=int(size.width-style->get_offset().x-(cached_width)); + } break; + } + while (ofs<text.length()) { - int char_w=font->get_char_size( text[ofs] ).width; + int char_w = 0; + if (font != NULL) { + char_w = font->get_char_size(text[ofs]).width; + } pixel_ofs+=char_w; if (pixel_ofs > p_x) { //found what we look for @@ -523,6 +602,10 @@ void LineEdit::delete_char() { if ((text.length()<=0) || (cursor_pos==0)) return; + Ref<Font> font = get_font("font"); + if (font != NULL) { + cached_width -= font->get_char_size(text[cursor_pos - 1]).width; + } text.erase( cursor_pos-1, 1 ); @@ -593,13 +676,15 @@ void LineEdit::set_cursor_pos(int p_pos) { int width_to_cursor=0; int wp=window_pos; - for (int i=window_pos;i<cursor_pos;i++) - width_to_cursor+=font->get_char_size( text[i] ).width; + if (font != NULL) { + for (int i=window_pos;i<cursor_pos;i++) + width_to_cursor+=font->get_char_size( text[i] ).width; - while(width_to_cursor>=window_width && wp<text.length()) { - - width_to_cursor-=font->get_char_size( text[ wp ] ).width; - wp++; + while (width_to_cursor >= window_width && wp < text.length()) { + + width_to_cursor -= font->get_char_size(text[wp]).width; + wp++; + } } if (wp!=window_pos) @@ -626,17 +711,26 @@ void LineEdit::append_at_cursor(String p_text) { if ( ( max_length <= 0 ) || (text.length()+p_text.length() <= max_length)) { undo_text = text; + + Ref<Font> font = get_font("font"); + if (font != NULL) { + for (int i = 0; i < p_text.length(); i++) + cached_width += font->get_char_size(p_text[i]).width; + } + else { + cached_width = 0; + } + String pre = text.substr( 0, cursor_pos ); String post = text.substr( cursor_pos, text.length()-cursor_pos ); text=pre+p_text+post; set_cursor_pos(cursor_pos+p_text.length()); - } - } void LineEdit::clear_internal() { + cached_width = 0; cursor_pos=0; window_pos=0; undo_text=""; @@ -676,6 +770,20 @@ void LineEdit::selection_delete() { if (selection.enabled) { undo_text = text; + + if (text.size() > 0) + { + Ref<Font> font = get_font("font"); + if (font != NULL) { + for (int i = selection.begin; i < selection.end; i++) + cached_width -= font->get_char_size(text[i]).width; + } + } + else + { + cached_width = 0; + } + text.erase(selection.begin,selection.end-selection.begin); cursor_pos-=CLAMP( cursor_pos-selection.begin, 0, selection.end-selection.begin); @@ -789,6 +897,8 @@ bool LineEdit::is_text_field() const { void LineEdit::_bind_methods() { + ObjectTypeDB::bind_method(_MD("set_align", "align"), &LineEdit::set_align); + ObjectTypeDB::bind_method(_MD("get_align"), &LineEdit::get_align); ObjectTypeDB::bind_method(_MD("_input_event"),&LineEdit::_input_event); ObjectTypeDB::bind_method(_MD("clear"),&LineEdit::clear); @@ -809,15 +919,22 @@ void LineEdit::_bind_methods() { ADD_SIGNAL( MethodInfo("text_changed", PropertyInfo( Variant::STRING, "text" )) ); ADD_SIGNAL( MethodInfo("text_entered", PropertyInfo( Variant::STRING, "text" )) ); + BIND_CONSTANT(ALIGN_LEFT); + BIND_CONSTANT(ALIGN_CENTER); + BIND_CONSTANT(ALIGN_RIGHT); + BIND_CONSTANT(ALIGN_FILL); + ADD_PROPERTY( PropertyInfo( Variant::STRING, "text" ), _SCS("set_text"),_SCS("get_text") ); + ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), _SCS("set_align"), _SCS("get_align")); ADD_PROPERTY( PropertyInfo( Variant::INT, "max_length" ), _SCS("set_max_length"),_SCS("get_max_length") ); ADD_PROPERTY( PropertyInfo( Variant::BOOL, "editable" ), _SCS("set_editable"),_SCS("is_editable") ); ADD_PROPERTY( PropertyInfo( Variant::BOOL, "secret" ), _SCS("set_secret"),_SCS("is_secret") ); - } LineEdit::LineEdit() { + align = ALIGN_LEFT; + cached_width = 0; cursor_pos=0; window_pos=0; max_length = 0; diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index b1c4c8f616..bf6459361a 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,7 +36,18 @@ class LineEdit : public Control { OBJ_TYPE( LineEdit, Control ); - + +public: + enum Align { + + ALIGN_LEFT, + ALIGN_CENTER, + ALIGN_RIGHT, + ALIGN_FILL + }; +private: + Align align; + bool editable; bool pass; @@ -46,6 +57,8 @@ class LineEdit : public Control { int cursor_pos; int window_pos; int max_length; // 0 for no maximum + + int cached_width; struct Selection { @@ -83,7 +96,8 @@ class LineEdit : public Control { protected: static void _bind_methods(); public: - + void set_align(Align p_align); + Align get_align() const; virtual Variant get_drag_data(const Point2& p_point); virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const; @@ -119,4 +133,7 @@ public: }; + +VARIANT_ENUM_CAST(LineEdit::Align); + #endif diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp index f10ca6353a..fde5df6b72 100644 --- a/scene/gui/margin_container.cpp +++ b/scene/gui/margin_container.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/margin_container.h b/scene/gui/margin_container.h index 56f2344ea7..df9a5c9361 100644 --- a/scene/gui/margin_container.h +++ b/scene/gui/margin_container.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 13ff7074ea..26540843de 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -54,6 +54,8 @@ void MenuButton::_unhandled_key_input(InputEvent p_event) { int item = popup->find_item_by_accelerator(code); + + if (item>=0 && ! popup->is_item_disabled(item)) popup->activate_item(item); /* diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h index 47e7382d34..2df632811f 100644 --- a/scene/gui/menu_button.h +++ b/scene/gui/menu_button.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index ff94a37be0..5c8e5a7381 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -77,9 +77,14 @@ void OptionButton::_selected(int p_which) { } } - ERR_FAIL_COND(selid==-1); + if (selid==-1 && p_which>=0 && p_which<popup->get_item_count()) { + _select(p_which,true); + } else { - _select(selid,true); + ERR_FAIL_COND(selid==-1); + + _select(selid,true); + } } @@ -299,7 +304,7 @@ void OptionButton::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_item_count"),&OptionButton::get_item_count); ObjectTypeDB::bind_method(_MD("add_separator"),&OptionButton::add_separator); ObjectTypeDB::bind_method(_MD("clear"),&OptionButton::clear); - ObjectTypeDB::bind_method(_MD("select"),&OptionButton::select); + ObjectTypeDB::bind_method(_MD("select","idx"),&OptionButton::select); ObjectTypeDB::bind_method(_MD("get_selected"),&OptionButton::get_selected); ObjectTypeDB::bind_method(_MD("get_selected_ID"),&OptionButton::get_selected_ID); ObjectTypeDB::bind_method(_MD("get_selected_metadata"),&OptionButton::get_selected_metadata); diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 7d850479aa..34e2bdd384 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/panel.cpp b/scene/gui/panel.cpp index d9ba20810b..d40daa972c 100644 --- a/scene/gui/panel.cpp +++ b/scene/gui/panel.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/panel.h b/scene/gui/panel.h index 7e6be62923..ee4bcd139e 100644 --- a/scene/gui/panel.h +++ b/scene/gui/panel.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/panel_container.cpp b/scene/gui/panel_container.cpp index 5ee061356e..bcf75b79f8 100644 --- a/scene/gui/panel_container.cpp +++ b/scene/gui/panel_container.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/panel_container.h b/scene/gui/panel_container.h index c09479241c..a40519c9f2 100644 --- a/scene/gui/panel_container.h +++ b/scene/gui/panel_container.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index 5ce7e2e0d3..03ef50c491 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -45,6 +45,16 @@ void Popup::_notification(int p_what) { emit_signal("popup_hide"); } } + + if (p_what==NOTIFICATION_ENTER_TREE) { + //small helper to make editing of these easier in editor +#ifdef TOOLS_ENABLED + if (get_tree()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) { + set_as_toplevel(false); + } +#endif + } + } void Popup::_fix_size() { diff --git a/scene/gui/popup.h b/scene/gui/popup.h index 6c72a3c82b..9c66e6d7bd 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 6c21ea639f..a93d8e524f 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -170,7 +170,14 @@ void PopupMenu::_activate_submenu(int over) { Point2 p = get_global_pos(); Rect2 pr(p,get_size()); Ref<StyleBox> style = get_stylebox("panel"); - pm->set_pos(p+Point2(get_size().width,items[over]._ofs_cache-style->get_offset().y)); + + Point2 pos = p+Point2(get_size().width,items[over]._ofs_cache-style->get_offset().y); + Size2 size = pm->get_size(); + // fix pos + if (pos.x+size.width > get_viewport_rect().size.width) + pos.x=p.x-size.width; + + pm->set_pos(pos); pm->popup(); PopupMenu *pum = pm->cast_to<PopupMenu>(); @@ -323,11 +330,14 @@ void PopupMenu::_input_event(const InputEvent &p_event) { invalidated_click=false; break; } - if (over<0 || items[over].separator || items[over].disabled) { + if (over<0) { hide(); break; //non-activable } + if (items[over].separator || items[over].disabled) + break; + if (items[over].submenu!="") { _activate_submenu(over); @@ -360,10 +370,13 @@ void PopupMenu::_input_event(const InputEvent &p_event) { } int over=_get_mouse_over(Point2(m.x,m.y)); - int id = (over<0 || items[over].separator || items[over].disabled)?-1:items[over].ID; + int id = (over<0 || items[over].separator || items[over].disabled)?-1:(items[over].ID>=0?items[over].ID:over); - if (id<0) + if (id<0) { + mouse_over=-1; + update(); break; + } if (items[over].submenu!="" && submenu_over!=over) { submenu_over=over; @@ -511,7 +524,7 @@ void PopupMenu::add_icon_item(const Ref<Texture>& p_icon,const String& p_label,i item.icon=p_icon; item.text=p_label; item.accel=p_accel; - item.ID=(p_ID<0)?idcount++:p_ID; + item.ID=p_ID; items.push_back(item); update(); } @@ -520,7 +533,7 @@ void PopupMenu::add_item(const String& p_label,int p_ID,uint32_t p_accel) { Item item; item.text=XL_MESSAGE(p_label); item.accel=p_accel; - item.ID=(p_ID<0)?idcount++:p_ID; + item.ID=p_ID; items.push_back(item); update(); } @@ -529,7 +542,7 @@ void PopupMenu::add_submenu_item(const String& p_label, const String& p_submenu, Item item; item.text=XL_MESSAGE(p_label); - item.ID=(p_ID<0)?idcount++:p_ID; + item.ID=p_ID; item.submenu=p_submenu; items.push_back(item); update(); @@ -541,7 +554,7 @@ void PopupMenu::add_icon_check_item(const Ref<Texture>& p_icon,const String& p_l item.icon=p_icon; item.text=XL_MESSAGE(p_label); item.accel=p_accel; - item.ID=(p_ID<0)?idcount++:p_ID; + item.ID=p_ID; item.checkable=true; items.push_back(item); update(); @@ -551,7 +564,7 @@ void PopupMenu::add_check_item(const String& p_label,int p_ID,uint32_t p_accel) Item item; item.text=XL_MESSAGE(p_label); item.accel=p_accel; - item.ID=(p_ID<0)?idcount++:p_ID; + item.ID=p_ID; item.checkable=true; items.push_back(item); update(); @@ -740,9 +753,11 @@ 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); + int id = items[p_item].ID>=0?items[p_item].ID:p_item; + emit_signal("item_pressed",id); //hide all parent PopupMenue's Node *next = get_parent(); @@ -774,8 +789,9 @@ void PopupMenu::add_separator() { void PopupMenu::clear() { items.clear(); + mouse_over=-1; update(); - idcount=0; + } @@ -882,7 +898,7 @@ void PopupMenu::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_item_icon","idx","icon"),&PopupMenu::set_item_icon); ObjectTypeDB::bind_method(_MD("set_item_accelerator","idx","accel"),&PopupMenu::set_item_accelerator); ObjectTypeDB::bind_method(_MD("set_item_metadata","idx","metadata"),&PopupMenu::set_item_metadata); - ObjectTypeDB::bind_method(_MD("set_item_checked","idx"),&PopupMenu::set_item_checked); + ObjectTypeDB::bind_method(_MD("set_item_checked","idx","checked"),&PopupMenu::set_item_checked); ObjectTypeDB::bind_method(_MD("set_item_disabled","idx","disabled"),&PopupMenu::set_item_disabled); ObjectTypeDB::bind_method(_MD("set_item_submenu","idx","submenu"),&PopupMenu::set_item_submenu); ObjectTypeDB::bind_method(_MD("set_item_as_separator","idx","enable"),&PopupMenu::set_item_as_separator); @@ -923,7 +939,7 @@ void PopupMenu::set_invalidate_click_until_motion() { PopupMenu::PopupMenu() { - idcount=0; + mouse_over=-1; set_focus_mode(FOCUS_ALL); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index ed78fe6738..624f4f542a 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -59,7 +59,6 @@ class PopupMenu : public Popup { Timer *submenu_timer; List<Rect2> autohide_areas; Vector<Item> items; - int idcount; int mouse_over; int submenu_over; Rect2 parent_rect; diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp index e7e2c88f4a..fc0e7be34f 100644 --- a/scene/gui/progress_bar.cpp +++ b/scene/gui/progress_bar.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/progress_bar.h b/scene/gui/progress_bar.h index 33b0d5c185..f50df346ac 100644 --- a/scene/gui/progress_bar.h +++ b/scene/gui/progress_bar.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index ad708d16f0..25b7952da1 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -216,11 +216,10 @@ void Range::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_val"),&Range::get_val); ObjectTypeDB::bind_method(_MD("get_value"),&Range::get_val); ObjectTypeDB::bind_method(_MD("get_min"),&Range::get_min); - ObjectTypeDB::bind_method(_MD("get_max"),&Range::get_max); - ObjectTypeDB::bind_method(_MD("get_step"),&Range::get_step); - ObjectTypeDB::bind_method(_MD("get_page"),&Range::get_page); - ObjectTypeDB::bind_method(_MD("get_unit_value"),&Range::get_unit_value); - ObjectTypeDB::bind_method(_MD("get_rounded_values"),&Range::get_rounded_values); + ObjectTypeDB::bind_method(_MD("get_max"),&Range::get_max); + ObjectTypeDB::bind_method(_MD("get_step"),&Range::get_step); + ObjectTypeDB::bind_method(_MD("get_page"),&Range::get_page); + ObjectTypeDB::bind_method(_MD("get_unit_value"),&Range::get_unit_value); ObjectTypeDB::bind_method(_MD("set_val","value"),&Range::set_val); ObjectTypeDB::bind_method(_MD("set_value","value"),&Range::set_val); ObjectTypeDB::bind_method(_MD("set_min","minimum"),&Range::set_min); @@ -228,7 +227,8 @@ void Range::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_step","step"),&Range::set_step); ObjectTypeDB::bind_method(_MD("set_page","pagesize"),&Range::set_page); ObjectTypeDB::bind_method(_MD("set_unit_value","value"),&Range::set_unit_value); - ObjectTypeDB::bind_method(_MD("set_rounded_values"),&Range::set_rounded_values); + ObjectTypeDB::bind_method(_MD("set_rounded_values","enabled"),&Range::set_rounded_values); + ObjectTypeDB::bind_method(_MD("is_rounded_values"),&Range::is_rounded_values); ObjectTypeDB::bind_method(_MD("set_exp_unit_value","enabled"),&Range::set_exp_unit_value); ObjectTypeDB::bind_method(_MD("is_unit_value_exp"),&Range::is_unit_value_exp); @@ -243,17 +243,19 @@ void Range::_bind_methods() { ADD_PROPERTY( PropertyInfo( Variant::REAL, "range/step" ), _SCS("set_step"), _SCS("get_step") ); ADD_PROPERTY( PropertyInfo( Variant::REAL, "range/page" ), _SCS("set_page"), _SCS("get_page") ); ADD_PROPERTY( PropertyInfo( Variant::REAL, "range/value" ), _SCS("set_val"), _SCS("get_val") ); - ADD_PROPERTY( PropertyInfo( Variant::REAL, "range/exp_edit" ), _SCS("set_exp_unit_value"), _SCS("is_unit_value_exp") ); - ADD_PROPERTY( PropertyInfo( Variant::BOOL, "rounded_values" ), _SCS("set_rounded_values"), _SCS("get_rounded_values") ); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "range/exp_edit" ), _SCS("set_exp_unit_value"), _SCS("is_unit_value_exp") ); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "range/rounded" ), _SCS("set_rounded_values"), _SCS("is_rounded_values") ); } -void Range::set_rounded_values(bool p){ - _rounded_values = p; +void Range::set_rounded_values(bool p_enable) { + + _rounded_values = p_enable; } -bool Range::get_rounded_values() const{ - return _rounded_values; +bool Range::is_rounded_values() const { + + return _rounded_values; } void Range::set_exp_unit_value(bool p_enable) { diff --git a/scene/gui/range.h b/scene/gui/range.h index 48361ddb0e..2967c2790c 100644 --- a/scene/gui/range.h +++ b/scene/gui/range.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -72,22 +72,23 @@ public: void set_step(double p_step); void set_page(double p_page); void set_unit_value(double p_value); - void set_rounded_values(bool); - + double get_val() const; double get_min() const; double get_max() const; double get_step() const; double get_page() const; double get_unit_value() const; - bool get_rounded_values() const; + + void set_rounded_values(bool p_enable); + bool is_rounded_values() const; void set_exp_unit_value(bool p_enable); bool is_unit_value_exp() const; void share(Range *p_range); void unshare(); - + Range(); ~Range(); diff --git a/scene/gui/reference_frame.cpp b/scene/gui/reference_frame.cpp index b90ea8292d..d037664a62 100644 --- a/scene/gui/reference_frame.cpp +++ b/scene/gui/reference_frame.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/reference_frame.h b/scene/gui/reference_frame.h index 8915b1df0c..5d3694e6e8 100644 --- a/scene/gui/reference_frame.h +++ b/scene/gui/reference_frame.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index ef6a2ba6aa..d4ac2652dc 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,35 +30,62 @@ #include "scene/scene_string_names.h" #include "os/keyboard.h" #include "os/os.h" -RichTextLabel::Item *RichTextLabel::_get_next_item(Item* p_item) { +RichTextLabel::Item *RichTextLabel::_get_next_item(Item* p_item,bool p_free) { - if (p_item->subitems.size()) { + if (p_free) { - return p_item->subitems.front()->get(); - } else if (!p_item->parent) { - return NULL; - } else if (p_item->E->next()) { + if (p_item->subitems.size()) { + + return p_item->subitems.front()->get(); + } else if (!p_item->parent) { + return NULL; + } else if (p_item->E->next()) { + + return p_item->E->next()->get(); + } else { + //go up until something with a next is found + while (p_item->parent && !p_item->E->next()) { + p_item=p_item->parent; + } + + + if (p_item->parent) + return p_item->E->next()->get(); + else + return NULL; - return p_item->E->next()->get(); - } else { - //go up until something with a next is found - while (p_item->parent && !p_item->E->next()) { - p_item=p_item->parent; } + } else { + if (p_item->subitems.size() && p_item->type!=ITEM_TABLE) { - if (p_item && p_item->parent) - return p_item->E->next()->get(); - else + return p_item->subitems.front()->get(); + } else if (p_item->type==ITEM_FRAME) { return NULL; + } else if (p_item->E->next()) { + + return p_item->E->next()->get(); + } else { + //go up until something with a next is found + while (p_item->type!=ITEM_FRAME && !p_item->E->next()) { + p_item=p_item->parent; + } + + + if (p_item->type!=ITEM_FRAME) + return p_item->E->next()->get(); + else + return NULL; + } } return NULL; } -void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos,Item **r_click_item,int *r_click_char,bool *r_outside,int p_char_count) { + +void RichTextLabel::_process_line(ItemFrame *p_frame,const Vector2& p_ofs,int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos,Item **r_click_item,int *r_click_char,bool *r_outside,int p_char_count) { RID ci; if (r_outside) @@ -70,7 +97,7 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p *r_click_item=NULL; } - Line &l = lines[p_line]; + Line &l = p_frame->lines[p_line]; Item *it = l.from; @@ -91,10 +118,13 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p l.offset_caches.clear(); l.height_caches.clear(); l.char_count=0; + l.minimum_width=0; } int wofs=margin; int spaces_size=0; + int align_ofs=0; + if (p_mode!=PROCESS_CACHE && align!=ALIGN_FILL) wofs+=line_ofs; @@ -125,7 +155,7 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p case ALIGN_LEFT: l.offset_caches.push_back(0); break;\ case ALIGN_CENTER: l.offset_caches.push_back(((p_width-margin)-used)/2); break;\ case ALIGN_RIGHT: l.offset_caches.push_back(((p_width-margin)-used)); break;\ - case ALIGN_FILL: l.offset_caches.push_back((p_width-margin)-used+spaces_size); break;\ + case ALIGN_FILL: l.offset_caches.push_back((p_width-margin)-used/*+spaces_size*/); break;\ }\ l.height_caches.push_back(line_height);\ l.space_caches.push_back(spaces);\ @@ -135,10 +165,11 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p spaces=0;\ spaces_size=0;\ wofs=begin;\ + align_ofs=0;\ if (p_mode!=PROCESS_CACHE) {\ lh=line<l.height_caches.size()?l.height_caches[line]:1;\ }\ - if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=y && p_click_pos.y<=y+lh && p_click_pos.x<wofs) {\ + if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=p_ofs.y+y && p_click_pos.y<=p_ofs.y+y+lh && p_click_pos.x<p_ofs.x+wofs) {\ if (r_outside) *r_outside=true;\ *r_click_item=it;\ *r_click_char=rchar;\ @@ -148,12 +179,15 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p #define ENSURE_WIDTH(m_width) \ + if (p_mode==PROCESS_CACHE) { \ + l.minimum_width=MAX(l.minimum_width,wofs+m_width);\ + }\ if (wofs + m_width > p_width) {\ if (p_mode==PROCESS_CACHE) {\ if (spaces>0) \ spaces-=1;\ }\ - if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=y && p_click_pos.y<=y+lh && p_click_pos.x>wofs) {\ + if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=p_ofs.y+y && p_click_pos.y<=p_ofs.y+y+lh && p_click_pos.x>p_ofs.x+wofs) {\ if (r_outside) *r_outside=true; \ *r_click_item=it;\ *r_click_char=rchar;\ @@ -165,7 +199,7 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p #define ADVANCE(m_width) \ {\ - if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=y && p_click_pos.y<=y+lh && p_click_pos.x>=wofs && p_click_pos.x<wofs+m_width) {\ + if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=p_ofs.y+y && p_click_pos.y<=p_ofs.y+y+lh && p_click_pos.x>=p_ofs.x+wofs && p_click_pos.x<p_ofs.x+wofs+m_width) {\ if (r_outside) *r_outside=false; \ *r_click_item=it;\ *r_click_char=rchar;\ @@ -218,8 +252,10 @@ if (m_height > line_height) {\ underline=true; } + } else if (p_mode==PROCESS_CACHE) { l.char_count+=text->text.length(); + } rchar=0; @@ -246,6 +282,8 @@ if (m_height > line_height) {\ if (c[end]==' ') { + fw+=cw; + /* if (p_mode==PROCESS_CACHE) { fw+=cw; } else if (align==ALIGN_FILL && line<l.space_caches.size() && l.space_caches[line]>0) { @@ -254,7 +292,7 @@ if (m_height > line_height) {\ found_space=true; } else { fw+=cw; - } + }*/ } else { fw+=cw; } @@ -262,23 +300,26 @@ if (m_height > line_height) {\ end++; } - - ENSURE_WIDTH(w); - //print_line("END: "+String::chr(c[end])+"."); if (end && c[end-1]==' ') { - spaces++; if (p_mode==PROCESS_CACHE) { spaces_size+=font->get_char_size(' ').width; + } else if (align==ALIGN_FILL) { + int ln = MIN(l.offset_caches.size()-1,line); + if (l.space_caches[ln]) { + align_ofs = spaces * l.offset_caches[ln] / l.space_caches[ln]; + } } + spaces++; + /* if (found_space) { int ln = MIN(l.offset_caches.size()-1,line); fw+=l.offset_caches[ln]/l.space_caches[ln]; - } + }*/ } @@ -294,7 +335,7 @@ if (m_height > line_height) {\ - if (p_mode==PROCESS_POINTER && r_click_char && p_click_pos.y>=y && p_click_pos.y<=y+lh) { + if (p_mode==PROCESS_POINTER && r_click_char && p_click_pos.y>=p_ofs.y+y && p_click_pos.y<=p_ofs.y+y+lh) { //int o = (wofs+w)-p_click_pos.x; @@ -303,7 +344,7 @@ if (m_height > line_height) {\ cw=tab_size*font->get_char_size(' ').width; } - if (p_click_pos.x-cw/2>pofs) { + if (p_click_pos.x-cw/2>p_ofs.x+align_ofs+pofs) { rchar=int((&c[i])-cf); //print_line("GOT: "+itos(rchar)); @@ -337,13 +378,13 @@ if (m_height > line_height) {\ if (selected) { cw = font->get_char_size(c[i],c[i+1]).x; - draw_rect(Rect2(pofs,y,cw,lh),selection_bg); + draw_rect(Rect2(p_ofs.x+pofs,p_ofs.y+y,cw,lh),selection_bg); if (visible) - font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],selection_fg); + font->draw_char(ci,p_ofs+Point2(align_ofs+pofs,y+lh-(fh-ascent)),c[i],c[i+1],selection_fg); } else { if (visible) - cw=font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color); + cw=font->draw_char(ci,p_ofs+Point2(align_ofs+pofs,y+lh-(fh-ascent)),c[i],c[i+1],color); } p_char_count++; @@ -359,7 +400,7 @@ if (m_height > line_height) {\ uc.a*=0.5; //VS::get_singleton()->canvas_item_add_line(ci,Point2(pofs,y+ascent+2),Point2(pofs+cw,y+ascent+2),uc); int uy = y+lh-fh+ascent+2; - VS::get_singleton()->canvas_item_add_line(ci,Point2(pofs,uy),Point2(pofs+cw,uy),uc); + VS::get_singleton()->canvas_item_add_line(ci,p_ofs+Point2(align_ofs+pofs,uy),p_ofs+Point2(align_ofs+pofs+cw,uy),uc); } ofs+=cw; } @@ -397,7 +438,7 @@ if (m_height > line_height) {\ bool visible = visible_characters<0 || p_char_count<visible_characters; if (p_mode==PROCESS_DRAW && visible) { - img->image->draw(ci,Point2(wofs,y+lh-font->get_descent()-img->image->get_height())); + img->image->draw(ci,p_ofs+Point2(align_ofs+wofs,y+lh-font->get_descent()-img->image->get_height())); } p_char_count++; @@ -435,6 +476,148 @@ if (m_height > line_height) {\ #endif } break; + case ITEM_TABLE: { + + lh=0; + ItemTable *table = static_cast<ItemTable*>(it); + int hseparation=get_constant("table_hseparation"); + int vseparation=get_constant("table_vseparation"); + Color ccolor = _find_color(table,p_base_color); + Vector2 draw_ofs = Point2(wofs,y); + int max_y=get_size().height; + + if (p_mode==PROCESS_CACHE) { + + int idx=0; + //set minimums to zero + for(int i=0;i<table->columns.size();i++) { + table->columns[i].min_width=0; + table->columns[i].width=0; + } + //compute minimum width for each cell + for (List<Item*>::Element *E=table->subitems.front();E;E=E->next()) { + ERR_CONTINUE(E->get()->type!=ITEM_FRAME); //children should all be frames + ItemFrame *frame = static_cast<ItemFrame*>(E->get()); + + int column = idx % table->columns.size(); + + int ly=0; + + + for(int i=0;i<frame->lines.size();i++) { + + _process_line(frame,Point2(),ly,p_width,i,PROCESS_CACHE,cfont,Color()); + table->columns[column].min_width=MAX( table->columns[i].min_width, frame->lines[i].minimum_width ); + } + idx++; + } + + //compute available width and total radio (for expanders) + + + int total_ratio=0; + int available_width=p_width - hseparation * (table->columns.size() -1); + table->total_width=hseparation; + + for(int i=0;i<table->columns.size();i++) { + available_width-=table->columns[i].min_width; + if (table->columns[i].expand) + total_ratio+=table->columns[i].expand_ratio; + } + + //assign actual widths + + for(int i=0;i<table->columns.size();i++) { + table->columns[i].width = table->columns[i].min_width; + if (table->columns[i].expand) + table->columns[i].width+=table->columns[i].expand_ratio*available_width/total_ratio; + table->total_width+=table->columns[i].width+hseparation; + } + + //compute caches properly again with the right width + idx=0; + for (List<Item*>::Element *E=table->subitems.front();E;E=E->next()) { + ERR_CONTINUE(E->get()->type!=ITEM_FRAME); //children should all be frames + ItemFrame *frame = static_cast<ItemFrame*>(E->get()); + + int column = idx % table->columns.size(); + + + for(int i=0;i<frame->lines.size();i++) { + + int ly=0; + _process_line(frame,Point2(),ly,table->columns[column].width,i,PROCESS_CACHE,cfont,Color()); + frame->lines[i].height_cache=ly; //actual height + frame->lines[i].height_accum_cache=ly; //actual height + } + idx++; + } + + } + + + + Point2 offset(align_ofs+hseparation,vseparation); + + int row_height=0; + //draw using computed caches + int idx=0; + for (List<Item*>::Element *E=table->subitems.front();E;E=E->next()) { + ERR_CONTINUE(E->get()->type!=ITEM_FRAME); //children should all be frames + ItemFrame *frame = static_cast<ItemFrame*>(E->get()); + + int column = idx % table->columns.size(); + + int ly=0; + int yofs=0; + + + int lines_h = frame->lines[frame->lines.size()-1].height_accum_cache - (frame->lines[0].height_accum_cache - frame->lines[0].height_cache); + int lines_ofs = p_ofs.y+offset.y+draw_ofs.y; + + bool visible = lines_ofs < get_size().height && lines_ofs+lines_h >=0; + + for(int i=0;i<frame->lines.size();i++) { + + + if (visible) { + if (p_mode==PROCESS_DRAW) { + _process_line(frame,p_ofs+offset+draw_ofs+Vector2(0,yofs),ly,table->columns[column].width,i,PROCESS_DRAW,cfont,ccolor); + } else if (p_mode==PROCESS_POINTER) { + _process_line(frame,p_ofs+offset+draw_ofs+Vector2(0,yofs),ly,table->columns[column].width,i,PROCESS_POINTER,cfont,ccolor,p_click_pos,r_click_item,r_click_char,r_outside); + } + } + + yofs+=frame->lines[i].height_cache; + if (p_mode==PROCESS_CACHE) { + frame->lines[i].height_accum_cache=offset.y+draw_ofs.y+frame->lines[i].height_cache; + } + + } + + row_height=MAX(yofs,row_height); + offset.x+=table->columns[column].width+hseparation; + + if (column==table->columns.size()-1) { + + offset.y+=row_height+vseparation; + offset.x=hseparation; + row_height=0; + } + idx++; + } + + int total_height = offset.y; + if (row_height) { + total_height=row_height+vseparation; + } + + + + ADVANCE( table->total_width ); + CHECK_HEIGHT( total_height ); + + } break; default: {} @@ -445,7 +628,7 @@ if (m_height > line_height) {\ it = _get_next_item(it); - if (p_mode == PROCESS_POINTER && r_click_item && itp && !it && p_click_pos.y>y+lh) { + if (p_mode == PROCESS_POINTER && r_click_item && itp && !it && p_click_pos.y>p_ofs.y+y+lh) { //at the end of all, return this if (r_outside) *r_outside=true; *r_click_item=itp; @@ -453,9 +636,9 @@ if (m_height > line_height) {\ return; } - if (it && (p_line+1 < lines.size()) && lines[p_line+1].from==it) { + if (it && (p_line+1 < p_frame->lines.size()) && p_frame->lines[p_line+1].from==it) { - if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=y && p_click_pos.y<=y+lh) { + if (p_mode==PROCESS_POINTER && r_click_item && p_click_pos.y>=p_ofs.y+y && p_click_pos.y<=p_ofs.y+y+lh) { //went to next line, but pointer was on the previous one if (r_outside) *r_outside=true; *r_click_item=itp; @@ -493,8 +676,8 @@ void RichTextLabel::_scroll_changed(double) { void RichTextLabel::_update_scroll() { int total_height=0; - if (lines.size()) - total_height=lines[lines.size()-1].height_accum_cache; + if (main->lines.size()) + total_height=main->lines[main->lines.size()-1].height_accum_cache; bool exceeds = total_height > get_size().height && scroll_active; @@ -503,18 +686,18 @@ void RichTextLabel::_update_scroll() { if (exceeds) { scroll_visible=true; - first_invalid_line=0; + main->first_invalid_line=0; scroll_w=vscroll->get_combined_minimum_size().width; vscroll->show(); vscroll->set_anchor_and_margin( MARGIN_LEFT, ANCHOR_END,scroll_w); - _validate_line_caches(); + _validate_line_caches(main); } else { scroll_visible=false; vscroll->hide(); scroll_w=0; - _validate_line_caches(); + _validate_line_caches(main); } } @@ -527,7 +710,7 @@ void RichTextLabel::_notification(int p_what) { case NOTIFICATION_RESIZED: { - first_invalid_line=0; //invalidate ALL + main->first_invalid_line=0; //invalidate ALL update(); } break; @@ -535,7 +718,7 @@ void RichTextLabel::_notification(int p_what) { if (use_bbcode) parse_bbcode(bbcode); - first_invalid_line=0; //invalidate ALL + main->first_invalid_line=0; //invalidate ALL update(); } break; @@ -550,7 +733,7 @@ void RichTextLabel::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - _validate_line_caches(); + _validate_line_caches(main); _update_scroll(); @@ -571,25 +754,25 @@ void RichTextLabel::_notification(int p_what) { int from_line = 0; int total_chars = 0; - while (from_line<lines.size()) { + while (from_line<main->lines.size()) { - if (lines[from_line].height_accum_cache>=ofs) + if (main->lines[from_line].height_accum_cache>=ofs) break; from_line++; - total_chars+=lines[from_line].char_count; + total_chars+=main->lines[from_line].char_count; } - if (from_line>=lines.size()) + if (from_line>=main->lines.size()) break; //nothing to draw - int y = (lines[from_line].height_accum_cache - lines[from_line].height_cache) - ofs; + int y = (main->lines[from_line].height_accum_cache - main->lines[from_line].height_cache) - ofs; Ref<Font> base_font=get_font("normal_font"); Color base_color=get_color("default_color"); - while (y<size.height && from_line<lines.size()) { + while (y<size.height && from_line<main->lines.size()) { - _process_line(y,size.width-scroll_w,from_line,PROCESS_DRAW,base_font,base_color,Point2i(),NULL,NULL,NULL,total_chars); - total_chars+=lines[from_line].char_count; + _process_line(main,Point2(),y,size.width-scroll_w,from_line,PROCESS_DRAW,base_font,base_color,Point2i(),NULL,NULL,NULL,total_chars); + total_chars+=main->lines[from_line].char_count; from_line++; } } @@ -597,7 +780,7 @@ void RichTextLabel::_notification(int p_what) { } -void RichTextLabel::_find_click(const Point2i& p_click,Item **r_click_item,int *r_click_char,bool *r_outside) { +void RichTextLabel::_find_click(ItemFrame* p_frame,const Point2i& p_click,Item **r_click_item,int *r_click_char,bool *r_outside) { if (r_click_item) *r_click_item=NULL; @@ -609,26 +792,26 @@ void RichTextLabel::_find_click(const Point2i& p_click,Item **r_click_item,int * //todo, change to binary search int from_line = 0; - while (from_line<lines.size()) { + while (from_line<p_frame->lines.size()) { - if (lines[from_line].height_accum_cache>=ofs) + if (p_frame->lines[from_line].height_accum_cache>=ofs) break; from_line++; } - if (from_line>=lines.size()) + if (from_line>=p_frame->lines.size()) return; - int y = (lines[from_line].height_accum_cache - lines[from_line].height_cache) - ofs; + int y = (p_frame->lines[from_line].height_accum_cache - p_frame->lines[from_line].height_cache) - ofs; Ref<Font> base_font=get_font("normal_font"); Color base_color=get_color("default_color"); - while (y<size.height && from_line<lines.size()) { + while (y<size.height && from_line<p_frame->lines.size()) { - _process_line(y,size.width-scroll_w,from_line,PROCESS_POINTER,base_font,base_color,p_click,r_click_item,r_click_char,r_outside); + _process_line(p_frame,Point2(),y,size.width-scroll_w,from_line,PROCESS_POINTER,base_font,base_color,p_click,r_click_item,r_click_char,r_outside); if (r_click_item && *r_click_item) return; from_line++; @@ -643,13 +826,13 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2& p_pos) const if (!underline_meta || selection.click) return CURSOR_ARROW; - if (first_invalid_line<lines.size()) + if (main->first_invalid_line<main->lines.size()) return CURSOR_ARROW; //invalid int line=0; Item *item=NULL; - ((RichTextLabel*)(this))->_find_click(p_pos,&item,&line); + ((RichTextLabel*)(this))->_find_click(main,p_pos,&item,&line); if (item && ((RichTextLabel*)(this))->_find_meta(item,NULL)) @@ -665,7 +848,7 @@ void RichTextLabel::_input_event(InputEvent p_event) { case InputEvent::MOUSE_BUTTON: { - if (first_invalid_line<lines.size()) + if (main->first_invalid_line<main->lines.size()) return; const InputEventMouseButton& b = p_event.mouse_button; @@ -680,7 +863,7 @@ void RichTextLabel::_input_event(InputEvent p_event) { Item *item=NULL; bool outside; - _find_click(Point2i(b.x,b.y),&item,&line,&outside); + _find_click(main,Point2i(b.x,b.y),&item,&line,&outside); if (item) { @@ -719,7 +902,7 @@ void RichTextLabel::_input_event(InputEvent p_event) { case InputEvent::KEY: { const InputEventKey &k=p_event.key; - if (k.pressed) { + if (k.pressed && !k.mod.alt && !k.mod.shift && !k.mod.meta) { bool handled=true; switch(k.scancode) { case KEY_PAGEUP: { @@ -765,6 +948,7 @@ void RichTextLabel::_input_event(InputEvent p_event) { default: handled=false; } + if (handled) accept_event(); } @@ -772,7 +956,7 @@ void RichTextLabel::_input_event(InputEvent p_event) { } break; case InputEvent::MOUSE_MOTION: { - if (first_invalid_line<lines.size()) + if (main->first_invalid_line<main->lines.size()) return; const InputEventMouseMotion& m = p_event.mouse_motion; @@ -781,7 +965,7 @@ void RichTextLabel::_input_event(InputEvent p_event) { int line=0; Item *item=NULL; - _find_click(Point2i(m.x,m.y),&item,&line); + _find_click(main,Point2i(m.x,m.y),&item,&line); if (!item) return; // do not update @@ -949,9 +1133,9 @@ bool RichTextLabel::_find_meta(Item *p_item,Variant *r_meta) { } -void RichTextLabel::_validate_line_caches() { +void RichTextLabel::_validate_line_caches(ItemFrame* p_frame) { - if (first_invalid_line==lines.size()) + if (p_frame->first_invalid_line==p_frame->lines.size()) return; //validate invalid lines!s @@ -959,24 +1143,24 @@ void RichTextLabel::_validate_line_caches() { Ref<Font> base_font=get_font("normal_font"); - for(int i=first_invalid_line;i<lines.size();i++) { + for(int i=p_frame->first_invalid_line;i<p_frame->lines.size();i++) { int y=0; - _process_line(y,size.width-scroll_w,i,PROCESS_CACHE,base_font,Color()); - lines[i].height_cache=y; - lines[i].height_accum_cache=y; + _process_line(p_frame,Point2(),y,size.width-scroll_w,i,PROCESS_CACHE,base_font,Color()); + p_frame->lines[i].height_cache=y; + p_frame->lines[i].height_accum_cache=y; if (i>0) - lines[i].height_accum_cache+=lines[i-1].height_accum_cache; + p_frame->lines[i].height_accum_cache+=p_frame->lines[i-1].height_accum_cache; } int total_height=0; - if (lines.size()) - total_height=lines[lines.size()-1].height_accum_cache; + if (p_frame->lines.size()) + total_height=p_frame->lines[p_frame->lines.size()-1].height_accum_cache; - first_invalid_line=lines.size(); + main->first_invalid_line=p_frame->lines.size(); updating_scroll=true; vscroll->set_max(total_height); @@ -989,17 +1173,20 @@ void RichTextLabel::_validate_line_caches() { } -void RichTextLabel::_invalidate_current_line() { +void RichTextLabel::_invalidate_current_line(ItemFrame* p_frame) { - if (lines.size()-1 <= first_invalid_line) { + if (p_frame->lines.size()-1 <= p_frame->first_invalid_line) { - first_invalid_line=lines.size()-1; + p_frame->first_invalid_line=p_frame->lines.size()-1; update(); } } void RichTextLabel::add_text(const String& p_text) { + if (current->type==ITEM_TABLE) + return; //can't add anything here + int pos=0; while (pos<p_text.length()) { @@ -1026,7 +1213,7 @@ void RichTextLabel::add_text(const String& p_text) { //append text condition! ItemText *ti = static_cast<ItemText*>(current->subitems.back()->get()); ti->text+=line; - _invalidate_current_line(); + _invalidate_current_line(main); } else { //append item condition @@ -1042,11 +1229,11 @@ void RichTextLabel::add_text(const String& p_text) { if (eol) { ItemNewline *item = memnew( ItemNewline ); - item->line=lines.size(); + item->line=current_frame->lines.size(); _add_item(item,false); - lines.resize(lines.size()+1); - lines[lines.size()-1].from=item; - _invalidate_current_line(); + current_frame->lines.resize(current_frame->lines.size()+1); + current_frame->lines[current_frame->lines.size()-1].from=item; + _invalidate_current_line(current_frame); } @@ -1054,25 +1241,38 @@ void RichTextLabel::add_text(const String& p_text) { } } -void RichTextLabel::_add_item(Item *p_item, bool p_enter) { +void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline) { + + p_item->parent=current; p_item->E=current->subitems.push_back(p_item); p_item->index=current_idx++; + if (p_enter) current=p_item; - if (lines[lines.size()-1].from==NULL) { - lines[lines.size()-1].from=p_item; + if (p_ensure_newline && current_frame->lines[current_frame->lines.size()-1].from) { + _invalidate_current_line(current_frame); + current_frame->lines.resize( current_frame->lines.size() +1 ); + + } + + if (current_frame->lines[current_frame->lines.size()-1].from==NULL) { + current_frame->lines[current_frame->lines.size()-1].from=p_item; } + p_item->line=current_frame->lines.size()-1; - _invalidate_current_line(); + _invalidate_current_line(current_frame); } void RichTextLabel::add_image(const Ref<Texture>& p_image) { + if (current->type==ITEM_TABLE) + return; + ERR_FAIL_COND(p_image.is_null()); ItemImage *item = memnew( ItemImage ); @@ -1083,15 +1283,18 @@ void RichTextLabel::add_image(const Ref<Texture>& p_image) { void RichTextLabel::add_newline() { + if (current->type==ITEM_TABLE) + return; ItemNewline *item = memnew( ItemNewline ); - item->line=lines.size(); - lines.resize(lines.size()+1); + item->line=current_frame->lines.size(); + current_frame->lines.resize(current_frame->lines.size()+1); _add_item(item,false); } void RichTextLabel::push_font(const Ref<Font>& p_font) { + ERR_FAIL_COND(current->type==ITEM_TABLE); ERR_FAIL_COND(p_font.is_null()); ItemFont *item = memnew( ItemFont ); @@ -1101,6 +1304,7 @@ void RichTextLabel::push_font(const Ref<Font>& p_font) { } void RichTextLabel::push_color(const Color& p_color) { + ERR_FAIL_COND(current->type==ITEM_TABLE); ItemColor *item = memnew( ItemColor ); item->color=p_color; @@ -1109,6 +1313,7 @@ void RichTextLabel::push_color(const Color& p_color) { } void RichTextLabel::push_underline() { + ERR_FAIL_COND(current->type==ITEM_TABLE); ItemUnderline *item = memnew( ItemUnderline ); _add_item(item,true); @@ -1117,47 +1322,40 @@ void RichTextLabel::push_underline() { void RichTextLabel::push_align(Align p_align) { - lines.resize(lines.size()+1); + ERR_FAIL_COND(current->type==ITEM_TABLE); ItemAlign *item = memnew( ItemAlign ); item->align=p_align; - _add_item(item,true); - - ItemNewline *itemnl = memnew( ItemNewline ); - itemnl->line=lines.size()-1; - _add_item(itemnl,false); + _add_item(item,true,true); } void RichTextLabel::push_indent(int p_level) { + ERR_FAIL_COND(current->type==ITEM_TABLE); ERR_FAIL_COND(p_level<0); - lines.resize(lines.size()+1); - ItemIndent *item = memnew( ItemIndent ); item->level=p_level; - _add_item(item,true); - - ItemNewline *itemnl = memnew( ItemNewline ); - itemnl->line=lines.size()-1; - _add_item(itemnl,false); + _add_item(item,true,true); } void RichTextLabel::push_list(ListType p_list) { + ERR_FAIL_COND(current->type==ITEM_TABLE); ERR_FAIL_INDEX(p_list,3); ItemList *item = memnew( ItemList ); item->list_type=p_list; - _add_item(item,true); + _add_item(item,true,true); } void RichTextLabel::push_meta(const Variant& p_meta) { + ERR_FAIL_COND(current->type==ITEM_TABLE); ItemMeta *item = memnew( ItemMeta ); item->meta=p_meta; @@ -1165,9 +1363,62 @@ void RichTextLabel::push_meta(const Variant& p_meta) { } +void RichTextLabel::push_table(int p_columns) { + + ERR_FAIL_COND( p_columns < 1); + ItemTable *item = memnew( ItemTable ); + + item->columns.resize(p_columns); + item->total_width=0; + for(int i=0;i<item->columns.size();i++) { + item->columns[i].expand=false; + item->columns[i].expand_ratio=1; + } + _add_item(item,true,true); + +} + +void RichTextLabel::set_table_column_expand(int p_column,bool p_expand,int p_ratio) { + + ERR_FAIL_COND(current->type!=ITEM_TABLE); + ItemTable *table = static_cast<ItemTable*>(current); + ERR_FAIL_INDEX(p_column,table->columns.size()); + table->columns[p_column].expand=p_expand; + table->columns[p_column].expand_ratio=p_ratio; +} + +void RichTextLabel::push_cell(){ + + ERR_FAIL_COND(current->type!=ITEM_TABLE); + + ItemFrame *item = memnew( ItemFrame ); + item->parent_frame=current_frame; + _add_item(item,true); + current_frame=item; + item->cell=true; + item->parent_line=item->parent_frame->lines.size()-1; + item->lines.resize(1); + item->lines[0].from=NULL; + item->first_invalid_line=0; + +} + +int RichTextLabel::get_current_table_column() const { + + ERR_FAIL_COND_V(current->type!=ITEM_TABLE,-1); + + ItemTable *table = static_cast<ItemTable*>(current); + + return table->subitems.size() % table->columns.size(); + +} + void RichTextLabel::pop() { ERR_FAIL_COND(!current->parent); + if (current->type==ITEM_FRAME) { + current_frame = static_cast<ItemFrame*>(current)->parent_frame; + } current=current->parent; } @@ -1175,9 +1426,10 @@ void RichTextLabel::clear() { main->_clear_children(); current=main; - lines.clear(); - lines.resize(1); - first_invalid_line=0; + current_frame=main; + main->lines.clear(); + main->lines.resize(1); + main->first_invalid_line=0; update(); selection.click=NULL; selection.active=false; @@ -1188,7 +1440,7 @@ void RichTextLabel::clear() { void RichTextLabel::set_tab_size(int p_spaces) { tab_size=p_spaces; - first_invalid_line=0; + main->first_invalid_line=0; update(); } @@ -1344,6 +1596,30 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) { push_font(mono_font); pos=brk_end+1; tag_stack.push_front(tag); + } else if (tag.begins_with("table=")) { + + int columns = tag.substr(6,tag.length()).to_int(); + if (columns<1) + columns=1; + //use monospace font + push_table(columns); + pos=brk_end+1; + tag_stack.push_front("table"); + } else if (tag=="cell") { + + push_cell(); + pos=brk_end+1; + tag_stack.push_front(tag); + } else if (tag.begins_with("cell=")) { + + int ratio = tag.substr(6,tag.length()).to_int(); + if (ratio<1) + ratio=1; + //use monospace font + set_table_column_expand(get_current_table_column(),true,ratio); + push_cell(); + pos=brk_end+1; + tag_stack.push_front("cell"); } else if (tag=="u") { //use underline @@ -1503,16 +1779,15 @@ 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-lines[p_line].height_cache); + ERR_FAIL_INDEX(p_line,main->lines.size()); + _validate_line_caches(main); + vscroll->set_val(main->lines[p_line].height_accum_cache-main->lines[p_line].height_cache); } int RichTextLabel::get_line_count() const { - return lines.size(); + return current_frame->lines.size(); } void RichTextLabel::set_selection_enabled(bool p_enabled) { @@ -1556,32 +1831,31 @@ bool RichTextLabel::search(const String& p_string,bool p_from_selection) { selection.active=true; update(); - if (line==-1) { + _validate_line_caches(main); - while(it) { + int fh = _find_font(t).is_valid()?_find_font(t)->get_height():get_font("normal_font")->get_height(); - if (it->type==ITEM_NEWLINE) { + float offset =0; - line=static_cast<ItemNewline*>(it)->line; - break; + int line = t->line; + Item *item =t; + while(item) { + if (item->type==ITEM_FRAME) { + ItemFrame *frame = static_cast<ItemFrame*>(item); + if (line>=0 && line<frame->lines.size()) { + offset+=frame->lines[line].height_accum_cache-frame->lines[line].height_cache; + line=frame->line; } - - it=_get_next_item(it); } - + item=item->parent; } - - if (line > 1) { - line-=1; - } - - scroll_to_line(line); + vscroll->set_val(offset-fh); return true; } } - it=_get_next_item(it); + it=_get_next_item(it,true); charidx=0; } @@ -1620,7 +1894,7 @@ void RichTextLabel::selection_copy() { if (item==selection.to) break; - item=_get_next_item(item); + item=_get_next_item(item,true); } if (text!="") { @@ -1673,6 +1947,9 @@ void RichTextLabel::_bind_methods() { ObjectTypeDB::bind_method(_MD("push_list","type"),&RichTextLabel::push_list); ObjectTypeDB::bind_method(_MD("push_meta","data"),&RichTextLabel::push_meta); ObjectTypeDB::bind_method(_MD("push_underline"),&RichTextLabel::push_underline); + ObjectTypeDB::bind_method(_MD("push_table","columns"),&RichTextLabel::push_table); + ObjectTypeDB::bind_method(_MD("set_table_column_expand","column","expand","ratio"),&RichTextLabel::set_table_column_expand); + ObjectTypeDB::bind_method(_MD("push_cell"),&RichTextLabel::push_cell); ObjectTypeDB::bind_method(_MD("pop"),&RichTextLabel::pop); ObjectTypeDB::bind_method(_MD("clear"),&RichTextLabel::clear); @@ -1688,10 +1965,11 @@ void RichTextLabel::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_v_scroll"),&RichTextLabel::get_v_scroll); + ObjectTypeDB::bind_method(_MD("scroll_to_line","line"),&RichTextLabel::scroll_to_line); + ObjectTypeDB::bind_method(_MD("set_tab_size","spaces"),&RichTextLabel::set_tab_size); ObjectTypeDB::bind_method(_MD("get_tab_size"),&RichTextLabel::get_tab_size); - ObjectTypeDB::bind_method(_MD("set_selection_enabled","enabled"),&RichTextLabel::set_selection_enabled); ObjectTypeDB::bind_method(_MD("is_selection_enabled"),&RichTextLabel::is_selection_enabled); @@ -1724,7 +2002,7 @@ void RichTextLabel::_bind_methods() { BIND_CONSTANT( LIST_LETTERS ); BIND_CONSTANT( LIST_DOTS ); - BIND_CONSTANT( ITEM_MAIN ); + BIND_CONSTANT( ITEM_FRAME ); BIND_CONSTANT( ITEM_TEXT ); BIND_CONSTANT( ITEM_IMAGE ); BIND_CONSTANT( ITEM_NEWLINE ); @@ -1752,8 +2030,8 @@ int RichTextLabel::get_visible_characters() const { int RichTextLabel::get_total_character_count() const { int tc=0; - for(int i=0;i<lines.size();i++) - tc+=lines[i].char_count; + for(int i=0;i<current_frame->lines.size();i++) + tc+=current_frame->lines[i].char_count; return tc; } @@ -1762,12 +2040,13 @@ int RichTextLabel::get_total_character_count() const { RichTextLabel::RichTextLabel() { - main = memnew( ItemMain ); + main = memnew( ItemFrame ); main->index=0; current=main; - lines.resize(1); - lines[0].from=main; - first_invalid_line=0; + main->lines.resize(1); + main->lines[0].from=main; + main->first_invalid_line=0; + current_frame=main; tab_size=4; default_align=ALIGN_LEFT; underline_meta=true; diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index eaa8d5d60a..635fe87ad4 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -54,7 +54,7 @@ public: enum ItemType { - ITEM_MAIN, + ITEM_FRAME, ITEM_TEXT, ITEM_IMAGE, ITEM_NEWLINE, @@ -64,6 +64,7 @@ public: ITEM_ALIGN, ITEM_INDENT, ITEM_LIST, + ITEM_TABLE, ITEM_META }; @@ -72,6 +73,24 @@ protected: static void _bind_methods(); private: + struct Item; + + struct Line { + + Item *from; + Vector<int> offset_caches; + Vector<int> height_caches; + Vector<int> space_caches; + int height_cache; + int height_accum_cache; + int char_count; + int minimum_width; + + Line() { from=NULL; char_count=0; } + }; + + + struct Item { int index; @@ -79,18 +98,26 @@ private: ItemType type; List<Item*> subitems; List<Item*>::Element *E; + int line; void _clear_children() { while (subitems.size()) { memdelete(subitems.front()->get()); subitems.pop_front(); } } - Item() { parent=NULL; E=NULL; } + Item() { parent=NULL; E=NULL; line=0;} virtual ~Item() { _clear_children(); } }; - struct ItemMain : public Item { + struct ItemFrame : public Item{ + + int parent_line; + bool cell; + Vector<Line> lines; + int first_invalid_line; + ItemFrame *parent_frame; - ItemMain() { type=ITEM_MAIN; } + ItemFrame() { type=ITEM_FRAME; parent_frame=NULL; cell=false; parent_line=0; } }; + struct ItemText : public Item { String text; @@ -150,11 +177,28 @@ private: ItemNewline() { type=ITEM_NEWLINE; } }; - ItemMain *main; + + struct ItemTable : public Item{ + + struct Column { + bool expand; + int expand_ratio; + int min_width; + int width; + }; + + Vector<Column> columns; + int total_width; + ItemTable() { type=ITEM_TABLE; } + }; + + ItemFrame *main; Item *current; + ItemFrame *current_frame; VScrollBar *vscroll; + bool scroll_visible; bool scroll_follow; bool scroll_following; @@ -163,34 +207,16 @@ private: bool updating_scroll; int current_idx; - struct Line { - - Item *from; - Vector<int> offset_caches; - Vector<int> height_caches; - Vector<int> space_caches; - int height_cache; - int height_accum_cache; - int char_count; - - Line() { from=NULL; char_count=0; } - }; - - - - - Vector<Line> lines; - int first_invalid_line; int tab_size; bool underline_meta; Align default_align; - void _invalidate_current_line(); - void _validate_line_caches(); + void _invalidate_current_line(ItemFrame *p_frame); + void _validate_line_caches(ItemFrame *p_frame); - void _add_item(Item *p_item, bool p_enter=false); + void _add_item(Item *p_item, bool p_enter=false,bool p_ensure_newline=false); @@ -227,8 +253,8 @@ private: int visible_characters; - void _process_line(int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos=Point2i(),Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL,int p_char_count=0); - void _find_click(const Point2i& p_click,Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL); + void _process_line(ItemFrame *p_frame,const Vector2& p_ofs,int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos=Point2i(),Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL,int p_char_count=0); + void _find_click(ItemFrame *p_frame, const Point2i& p_click,Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL); Ref<Font> _find_font(Item *p_item); @@ -242,12 +268,12 @@ private: void _scroll_changed(double); void _input_event(InputEvent p_event); - Item *_get_next_item(Item* p_item); + Item *_get_next_item(Item* p_item, bool p_free=false); bool use_bbcode; String bbcode; - + void _update_all_lines(); protected: void _notification(int p_what); @@ -264,6 +290,10 @@ public: void push_indent(int p_level); void push_list(ListType p_list); void push_meta(const Variant& p_data); + void push_table(int p_columns); + void set_table_column_expand(int p_column, bool p_expand, int p_ratio=1); + int get_current_table_column() const; + void push_cell(); void pop(); void clear(); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index b1fd914fcd..0fd4286f38 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h index 367bc3eb53..a629ddc56c 100644 --- a/scene/gui/scroll_bar.h +++ b/scene/gui/scroll_bar.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 8f753f51bc..a2fc038f9e 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -195,11 +195,19 @@ void ScrollContainer::_notification(int p_what) { Rect2 r = Rect2(-scroll,minsize); if (!scroll_h) { r.pos.x=0; - r.size.width=size.width; + if (c->get_h_size_flags()&SIZE_EXPAND) + r.size.width=MAX(size.width,minsize.width); + else + r.size.width=minsize.width; } if (!scroll_v) { r.pos.y=0; r.size.height=size.height; + if (c->get_v_size_flags()&SIZE_EXPAND) + r.size.height=MAX(size.height,minsize.height); + else + r.size.height=minsize.height; + } fit_child_in_rect(c,r); } diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index b8d37be08c..50ae236714 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/separator.cpp b/scene/gui/separator.cpp index 5e822a10ad..626b093a2f 100644 --- a/scene/gui/separator.cpp +++ b/scene/gui/separator.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/separator.h b/scene/gui/separator.h index 17e9c11e34..7a7dc92b93 100644 --- a/scene/gui/separator.h +++ b/scene/gui/separator.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index b6292c544b..7ef9d4216b 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -50,9 +50,9 @@ void Slider::_input_event(InputEvent p_event) { grab.pos=orientation==VERTICAL?mb.y:mb.x; double max = orientation==VERTICAL ? get_size().height : get_size().width ; if (orientation==VERTICAL) - set_val( ( ( -(double)grab.pos / max) * ( get_max() - get_min() ) ) + get_max() ); + set_unit_value( 1 - ((double)grab.pos / max) ); else - set_val( ( ( (double)grab.pos / max) * ( get_max() - get_min() ) ) + get_min() ); + set_unit_value((double)grab.pos / max); grab.active=true; grab.uvalue=get_unit_value(); } else { diff --git a/scene/gui/slider.h b/scene/gui/slider.h index 5850c48ce3..f85e6d1807 100644 --- a/scene/gui/slider.h +++ b/scene/gui/slider.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index a48136f541..38c61ded2c 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -68,6 +68,25 @@ void SpinBox::_line_edit_input(const InputEvent& p_event) { } +void SpinBox::_range_click_timeout() { + + if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + + int pos_y = Input::get_singleton()->get_mouse_pos().y-get_global_pos().y; + bool up = pos_y < (get_size().height/2); + set_val( get_val() + (up?get_step():-get_step())); + + if (range_click_timer->is_one_shot()) { + range_click_timer->set_wait_time(0.075); + range_click_timer->set_one_shot(false); + range_click_timer->start(); + } + + } else { + range_click_timer->stop(); + } +} + void SpinBox::_input_event(const InputEvent& p_event) { @@ -85,6 +104,10 @@ void SpinBox::_input_event(const InputEvent& p_event) { set_val( get_val() + (up?get_step():-get_step())); + range_click_timer->set_wait_time(0.6); + range_click_timer->set_one_shot(true); + range_click_timer->start(); + } break; case BUTTON_RIGHT: { @@ -112,6 +135,8 @@ void SpinBox::_input_event(const InputEvent& p_event) { if (p_event.type==InputEvent::MOUSE_BUTTON && !p_event.mouse_button.pressed && p_event.mouse_button.button_index==1) { //set_default_cursor_shape(CURSOR_ARROW); + range_click_timer->stop(); + if (drag.enabled) { drag.enabled=false; Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); @@ -167,6 +192,7 @@ void SpinBox::_notification(int p_what) { Size2i size = get_size(); updown->draw(ci,Point2i(size.width-updown->get_width(),(size.height-updown->get_height())/2)); + } else if (p_what==NOTIFICATION_FOCUS_EXIT) { @@ -227,6 +253,7 @@ void SpinBox::_bind_methods() { ObjectTypeDB::bind_method(_MD("_line_edit_focus_exit"),&SpinBox::_line_edit_focus_exit); ObjectTypeDB::bind_method(_MD("get_line_edit"),&SpinBox::get_line_edit); ObjectTypeDB::bind_method(_MD("_line_edit_input"),&SpinBox::_line_edit_input); + ObjectTypeDB::bind_method(_MD("_range_click_timeout"),&SpinBox::_range_click_timeout); ADD_PROPERTY(PropertyInfo(Variant::BOOL,"editable"),_SCS("set_editable"),_SCS("is_editable")); @@ -248,4 +275,8 @@ SpinBox::SpinBox() { line_edit->connect("focus_exit",this,"_line_edit_focus_exit",Vector<Variant>(),CONNECT_DEFERRED); line_edit->connect("input_event",this,"_line_edit_input"); drag.enabled=false; + + range_click_timer = memnew( Timer ); + range_click_timer->connect("timeout",this,"_range_click_timeout"); + add_child(range_click_timer); } diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 4c8cb8432a..acaea822ab 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,6 +31,7 @@ #include "scene/gui/line_edit.h" #include "scene/gui/range.h" +#include "scene/main/timer.h" class SpinBox : public Range { @@ -39,6 +40,9 @@ class SpinBox : public Range { LineEdit *line_edit; int last_w; + Timer *range_click_timer; + void _range_click_timeout(); + void _text_entered(const String& p_string); virtual void _value_changed(double); String prefix; diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index d7ee7a6b86..b0d089fcf3 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -435,8 +435,8 @@ void SplitContainer::_bind_methods() { ADD_SIGNAL( MethodInfo("dragged",PropertyInfo(Variant::INT,"offset"))); ADD_PROPERTY( PropertyInfo(Variant::INT,"split/offset"),_SCS("set_split_offset"),_SCS("get_split_offset")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"split/collapsed"),_SCS("set_collapsed"),_SCS("is_collapsed")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"split/dragger_visible"),_SCS("set_dragger_visible"),_SCS("is_dragger_visible")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"split/collapsed"),_SCS("set_collapsed"),_SCS("is_collapsed")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"split/dragger_visible"),_SCS("set_dragger_visible"),_SCS("is_dragger_visible")); } @@ -451,6 +451,7 @@ SplitContainer::SplitContainer(bool p_vertical) { dragging=false; collapsed=false; dragger_visible=true; + } diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index d7f56c6fb4..c8cfa3d69b 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 6fa701340d..91d0fc157e 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index 602d248b46..979ce927a0 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 6d84f028b3..14cd0bee8e 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -58,7 +58,7 @@ Size2 Tabs::get_minimum_size() const { if (tabs[i].right_button.is_valid()) { Ref<Texture> rb=tabs[i].right_button; - Size2 bms = rb->get_size()+get_stylebox("button")->get_minimum_size(); + Size2 bms = rb->get_size();//+get_stylebox("button")->get_minimum_size(); bms.width+=get_constant("hseparation"); ms.width+=bms.width; @@ -67,14 +67,14 @@ Size2 Tabs::get_minimum_size() const { 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(); + 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); } } + ms.width=0; //should make this optional return ms; } @@ -86,6 +86,23 @@ void Tabs::_input_event(const InputEvent& p_event) { Point2 pos( p_event.mouse_motion.x, p_event.mouse_motion.y ); + hilite_arrow=-1; + if (buttons_visible) { + + Ref<Texture> incr = get_icon("increment"); + Ref<Texture> decr = get_icon("decrement"); + + int limit=get_size().width-incr->get_width()-decr->get_width(); + + if (pos.x>limit+decr->get_width()) { + hilite_arrow=1; + } else if (pos.x>limit) { + hilite_arrow=0; + } + } + + + int hover_buttons=-1; hover=-1; for(int i=0;i<tabs.size();i++) { @@ -103,11 +120,13 @@ void Tabs::_input_event(const InputEvent& p_event) { // test hovering right button and close button if (tabs[i].rb_rect.has_point(pos)) { rb_hover=i; + cb_hover=-1; hover_buttons = i; break; } else if (tabs[i].cb_rect.has_point(pos)) { cb_hover=i; + rb_hover=-1; hover_buttons = i; break; } @@ -162,9 +181,34 @@ void Tabs::_input_event(const InputEvent& p_event) { // clicks Point2 pos( p_event.mouse_button.x, p_event.mouse_button.y ); + if (buttons_visible) { + + Ref<Texture> incr = get_icon("increment"); + Ref<Texture> decr = get_icon("decrement"); + + int limit=get_size().width-incr->get_width()-decr->get_width(); + + if (pos.x>limit+decr->get_width()) { + if (missing_right) { + offset++; + update(); + } + return; + } else if (pos.x>limit) { + if (offset>0) { + offset--; + update(); + } + return; + } + } + + int found=-1; for(int i=0;i<tabs.size();i++) { + if (i<offset) + continue; if (tabs[i].rb_rect.has_point(pos)) { rb_pressing=true; update(); @@ -224,7 +268,46 @@ void Tabs::_notification(int p_what) { int w=0; - int mw = get_minimum_size().width; + int mw = 0; + + { + + + // h+=MIN( get_constant("label_valign_fg"), get_constant("label_valign_bg") ); + + for(int i=0;i<tabs.size();i++) { + + Ref<Texture> tex = tabs[i].icon; + if (tex.is_valid()) { + if (tabs[i].text!="") + mw+=get_constant("hseparation"); + + } + mw+=font->get_string_size(tabs[i].text).width; + if (current==i) + mw+=tab_fg->get_minimum_size().width; + else + mw+=tab_bg->get_minimum_size().width; + + if (tabs[i].right_button.is_valid()) { + Ref<Texture> rb=tabs[i].right_button; + Size2 bms = rb->get_size();//+get_stylebox("button")->get_minimum_size(); + bms.width+=get_constant("hseparation"); + + mw+=bms.width; + } + + 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"); + mw+=bms.width; + } + } + + } + + if (tab_align==ALIGN_CENTER) { w=(get_size().width-mw)/2; @@ -237,8 +320,19 @@ void Tabs::_notification(int p_what) { w=0; } + Ref<Texture> incr = get_icon("increment"); + Ref<Texture> decr = get_icon("decrement"); + Ref<Texture> incr_hl = get_icon("increment_hilite"); + Ref<Texture> decr_hl = get_icon("decrement_hilite"); + + int limit=get_size().width - incr->get_size().width - decr->get_size().width; + + missing_right=false; + for(int i=0;i<tabs.size();i++) { + if (i<offset) + continue; tabs[i].ofs_cache=w; String s = tabs[i].text; @@ -246,6 +340,8 @@ void Tabs::_notification(int p_what) { int slen=font->get_string_size(s).width; lsize+=slen; + + Ref<Texture> icon; if (tabs[i].icon.is_valid()) { icon = tabs[i].icon; @@ -262,9 +358,9 @@ void Tabs::_notification(int p_what) { Ref<Texture> rb=tabs[i].right_button; lsize+=get_constant("hseparation"); - lsize+=style->get_margin(MARGIN_LEFT); + //lsize+=style->get_margin(MARGIN_LEFT); lsize+=rb->get_width(); - lsize+=style->get_margin(MARGIN_RIGHT); + //lsize+=style->get_margin(MARGIN_RIGHT); } @@ -276,9 +372,9 @@ void Tabs::_notification(int p_what) { Ref<Texture> rb=tabs[i].close_button; lsize+=get_constant("hseparation"); - lsize+=style->get_margin(MARGIN_LEFT); + //lsize+=style->get_margin(MARGIN_LEFT); lsize+=rb->get_width(); - lsize+=style->get_margin(MARGIN_RIGHT); + //lsize+=style->get_margin(MARGIN_RIGHT); } } break; @@ -289,9 +385,9 @@ void Tabs::_notification(int p_what) { Ref<Texture> rb=tabs[i].close_button; lsize+=get_constant("hseparation"); - lsize+=style->get_margin(MARGIN_LEFT); + //lsize+=style->get_margin(MARGIN_LEFT); lsize+=rb->get_width(); - lsize+=style->get_margin(MARGIN_RIGHT); + //lsize+=style->get_margin(MARGIN_RIGHT); } } @@ -303,9 +399,9 @@ void Tabs::_notification(int p_what) { Ref<Texture> rb=tabs[i].close_button; lsize+=get_constant("hseparation"); - lsize+=style->get_margin(MARGIN_LEFT); + //lsize+=style->get_margin(MARGIN_LEFT); lsize+=rb->get_width(); - lsize+=style->get_margin(MARGIN_RIGHT); + //lsize+=style->get_margin(MARGIN_RIGHT); } } @@ -318,6 +414,16 @@ void Tabs::_notification(int p_what) { } + if (w+lsize > limit) { + max_drawn_tab=i-1; + missing_right=true; + break; + } else { + max_drawn_tab=i; + } + + + Ref<StyleBox> sb; int va; Color col; @@ -404,11 +510,11 @@ void Tabs::_notification(int p_what) { style->draw(ci,cb_rect); } - w+=style->get_margin(MARGIN_LEFT); + //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); + //w+=style->get_margin(MARGIN_RIGHT); tabs[i].cb_rect=cb_rect; } } break; @@ -432,11 +538,11 @@ void Tabs::_notification(int p_what) { style->draw(ci,cb_rect); } - w+=style->get_margin(MARGIN_LEFT); + //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); + //w+=style->get_margin(MARGIN_RIGHT); tabs[i].cb_rect=cb_rect; } } @@ -461,11 +567,11 @@ void Tabs::_notification(int p_what) { style->draw(ci,cb_rect); } - w+=style->get_margin(MARGIN_LEFT); + //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); + //w+=style->get_margin(MARGIN_RIGHT); tabs[i].cb_rect=cb_rect; } } @@ -483,6 +589,25 @@ void Tabs::_notification(int p_what) { } + if (offset>0 || missing_right) { + + int vofs = (get_size().height-incr->get_size().height)/2; + + if (offset>0) + draw_texture(hilite_arrow==0?decr_hl:decr,Point2(limit,vofs)); + else + draw_texture(decr,Point2(limit,vofs),Color(1,1,1,0.5)); + + if (missing_right) + draw_texture(hilite_arrow==1?incr_hl:incr,Point2(limit+decr->get_size().width,vofs)); + else + draw_texture(incr,Point2(limit+decr->get_size().width,vofs),Color(1,1,1,0.5)); + + buttons_visible=true; + } else { + buttons_visible=false; + } + } break; } @@ -583,7 +708,7 @@ void Tabs::add_tab(const String& p_str,const Ref<Texture>& p_icon) { t.text=p_str; t.icon=p_icon; - t.close_button = get_icon("Close","EditorIcons"); + t.close_button = get_icon("close"); tabs.push_back(t); @@ -672,8 +797,11 @@ Tabs::Tabs() { tab_align=ALIGN_CENTER; rb_hover=-1; rb_pressing=false; + hilite_arrow=-1; cb_hover=-1; cb_pressing=false; cb_displaypolicy = SHOW_NEVER; // Default : no close button + offset=0; + max_drawn_tab=0; } diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index 1a8352bc93..efcb291a52 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -65,6 +65,12 @@ private: Rect2 cb_rect; }; + + int offset; + int max_drawn_tab; + int hilite_arrow; + bool buttons_visible; + bool missing_right; Vector<Tab> tabs; int current; Control *_get_tab(int idx) const; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index be6c0d0a8b..70da7e39a4 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,6 +29,7 @@ #include "text_edit.h" #include "os/keyboard.h" +#include "os/input.h" #include "os/os.h" #include "globals.h" @@ -349,6 +350,29 @@ void TextEdit::_update_scrollbars() { updating_scrolls=false; } +void TextEdit::_click_selection_held() { + + if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode!=Selection::MODE_NONE) { + + Point2 mp = Input::get_singleton()->get_mouse_pos()-get_global_pos(); + + int row,col; + _get_mouse_pos(Point2i(mp.x,mp.y), row,col); + + select(selection.selecting_line,selection.selecting_column,row,col); + + cursor_set_line( row ); + cursor_set_column( col ); + update(); + + click_select_held->start(); + + } else { + + click_select_held->stop(); + } +} + void TextEdit::_notification(int p_what) { @@ -1094,16 +1118,16 @@ void TextEdit::backspace_at_cursor() { } -bool TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const { - - int row=p_mouse.y; - row-=cache.style_normal->get_margin(MARGIN_TOP); - row/=get_row_height(); +void TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const { - if (row<0 || row>=get_visible_rows()) - return false; - - row+=cursor.line_ofs; + float rows=p_mouse.y; + rows-=cache.style_normal->get_margin(MARGIN_TOP); + rows/=get_row_height(); + int row=cursor.line_ofs+rows; + + if (row<0) + row=0; + int col=0; if (row>=text.size()) { @@ -1119,7 +1143,6 @@ bool TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) co r_row=row; r_col=col; - return true; } void TextEdit::_input_event(const InputEvent& p_input_event) { @@ -1177,8 +1200,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if (mb.button_index==BUTTON_LEFT) { int row,col; - if (!_get_mouse_pos(Point2i(mb.x,mb.y), row,col)) - return; + _get_mouse_pos(Point2i(mb.x,mb.y), row,col); int prev_col=cursor.column; int prev_line=cursor.line; @@ -1210,27 +1232,30 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { update(); } else { - if (cursor.line<selection.from_line || (cursor.line==selection.from_line && cursor.column<=selection.from_column)) { - selection.from_column=cursor.column; - selection.from_line=cursor.line; - } else if (cursor.line>selection.to_line || (cursor.line==selection.to_line && cursor.column>=selection.to_column)) { - selection.to_column=cursor.column; - selection.to_line=cursor.line; - - } else if (!selection.shiftclick_left) { + if (cursor.line<selection.selecting_line || (cursor.line==selection.selecting_line && cursor.column<selection.selecting_column)) { + if (selection.shiftclick_left) { + SWAP(selection.from_column,selection.to_column); + SWAP(selection.from_line,selection.to_line); + selection.shiftclick_left = !selection.shiftclick_left; + } selection.from_column=cursor.column; selection.from_line=cursor.line; - } else { + } else if (cursor.line>selection.selecting_line || (cursor.line==selection.selecting_line && cursor.column>selection.selecting_column)) { + + if (!selection.shiftclick_left) { + SWAP(selection.from_column,selection.to_column); + SWAP(selection.from_line,selection.to_line); + selection.shiftclick_left = !selection.shiftclick_left; + } selection.to_column=cursor.column; selection.to_line=cursor.line; - } - if (selection.from_line>selection.to_line || (selection.from_line==selection.to_line && selection.from_column>selection.to_column)) { - SWAP(selection.from_column,selection.to_column); - SWAP(selection.from_line,selection.to_line); + } else { + selection.active=false; } + update(); } @@ -1255,6 +1280,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if (!mb.doubleclick && (OS::get_singleton()->get_ticks_msec()-last_dblclk)<600 && cursor.line==prev_line) { //tripleclick select line select(cursor.line,0,cursor.line,text[cursor.line].length()); + selection.selecting_column=0; last_dblclk=0; } else if (mb.doubleclick && text[cursor.line].length()) { @@ -1279,6 +1305,8 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { end+=1; select(cursor.line,beg,cursor.line,end); + + selection.selecting_column=beg; } last_dblclk = OS::get_singleton()->get_ticks_msec(); @@ -1288,8 +1316,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { update(); } } else { + + if (mb.button_index==BUTTON_LEFT) + click_select_held->stop(); - selection.selecting_mode=Selection::MODE_NONE; // notify to show soft keyboard notification(NOTIFICATION_FOCUS_ENTER); } @@ -1301,17 +1331,18 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if (mm.button_mask&BUTTON_MASK_LEFT) { - int row,col; - if (!_get_mouse_pos(Point2i(mm.x,mm.y), row,col)) - return; - - if (selection.selecting_mode==Selection::MODE_POINTER) { + if (selection.selecting_mode!=Selection::MODE_NONE) { + + int row,col; + _get_mouse_pos(Point2i(mm.x,mm.y), row,col); select(selection.selecting_line,selection.selecting_column,row,col); cursor_set_line( row ); cursor_set_column( col ); update(); + + click_select_held->start(); } @@ -1585,7 +1616,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { break; } - selection.selecting_test=false; + selection.selecting_text=false; bool scancode_handled=true; @@ -1608,6 +1639,13 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { else break; } + if(auto_indent){ + // indent once again if previous line will end with ':' + // (i.e. colon precedes current cursor position) + if(cursor.column>0 && text[cursor.line][cursor.column-1]==':') { + ins+="\t"; + } + } _insert_text_at_cursor(ins); _push_current_op(); @@ -1647,8 +1685,60 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { case KEY_BACKSPACE: { if (readonly) break; - backspace_at_cursor(); - + +#ifdef APPLE_STYLE_KEYS + if (k.mod.alt) { +#else + if (k.mod.alt) { + scancode_handled=false; + break; + } else if (k.mod.command) { +#endif + int line=cursor.line; + int column=cursor.column; + + bool prev_char=false; + bool only_whitespace=true; + + while (only_whitespace && line > 0) { + + while (column>0) { + CharType c=text[line][column-1]; + + if (c != '\t' && c != ' ') { + only_whitespace=false; + break; + } + + column--; + } + + if (only_whitespace) { + line--; + column=text[line].length(); + } + } + + while (column>0) { + bool ischar=_is_text_char(text[line][column-1]); + + if (prev_char && !ischar) + break; + + prev_char=ischar; + column--; + + } + + _remove_text(line, column, cursor.line, cursor.column); + + cursor_set_line(line); + cursor_set_column(column); + + } else { + backspace_at_cursor(); + } + } break; case KEY_LEFT: { @@ -1789,10 +1879,63 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if (cursor.line==text.size()-1 && cursor.column==curline_len) break; //nothing to do - int next_line = cursor.column<curline_len?cursor.line:cursor.line+1; - int next_column = cursor.column<curline_len?(cursor.column+1):0; + int next_line=cursor.column<curline_len?cursor.line:cursor.line+1; + int next_column; + +#ifdef APPLE_STYLE_KEYS + if (k.mod.alt) { +#else + if (k.mod.alt) { + scancode_handled=false; + break; + } else if (k.mod.command) { +#endif + int last_line=text.size()-1; + + int line=cursor.line; + int column=cursor.column; + + bool prev_char=false; + bool only_whitespace=true; + + while (only_whitespace && line < last_line) { + + while (column<text[line].length()) { + CharType c=text[line][column]; + + if (c != '\t' && c != ' ') { + only_whitespace=false; + break; + } + + column++; + } + + if (only_whitespace) { + line++; + column=0; + } + } + + while (column<text[line].length()) { + + bool ischar=_is_text_char(text[line][column]); + + if (prev_char && !ischar) + break; + prev_char=ischar; + column++; + } + + next_line=line; + next_column=column; + } else { + next_column=cursor.column<curline_len?(cursor.column+1):0; + } + _remove_text(cursor.line,cursor.column,next_line,next_column); update(); + } break; #ifdef APPLE_STYLE_KEYS case KEY_HOME: { @@ -1903,15 +2046,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { break; } - if (text.size()==1 && text[0].length()==0) - break; - selection.active=true; - selection.from_line=0; - selection.from_column=0; - selection.to_line=text.size()-1; - selection.to_column=text[selection.to_line].length(); - selection.selecting_mode=Selection::MODE_NONE; - update(); + select_all(); } break; case KEY_X: { @@ -2096,12 +2231,6 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } } - - if (!selection.selecting_test) { - - selection.selecting_mode=Selection::MODE_NONE; - } - return; } break; @@ -2113,13 +2242,14 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { void TextEdit::_pre_shift_selection() { - if (!selection.active || selection.selecting_mode!=Selection::MODE_SHIFT) { + if (!selection.active || selection.selecting_mode==Selection::MODE_NONE) { selection.selecting_line=cursor.line; selection.selecting_column=cursor.column; selection.active=true; - selection.selecting_mode=Selection::MODE_SHIFT; } + + selection.selecting_mode=Selection::MODE_SHIFT; } void TextEdit::_post_shift_selection() { @@ -2132,7 +2262,7 @@ void TextEdit::_post_shift_selection() { } - selection.selecting_test=true; + selection.selecting_text=true; } /**** TEXT EDIT CORE API ****/ @@ -2428,7 +2558,7 @@ void TextEdit::adjust_viewport_to_cursor() { } -void TextEdit::cursor_set_column(int p_col) { +void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) { if (p_col<0) p_col=0; @@ -2439,7 +2569,8 @@ void TextEdit::cursor_set_column(int p_col) { cursor.last_fit_x=get_column_x_offset(cursor.column,get_line(cursor.line)); - adjust_viewport_to_cursor(); + if (p_adjust_viewport) + adjust_viewport_to_cursor(); if (!cursor_changed_dirty) { if (is_inside_tree()) @@ -2450,7 +2581,7 @@ void TextEdit::cursor_set_column(int p_col) { } -void TextEdit::cursor_set_line(int p_row) { +void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport) { if (setting_row) return; @@ -2466,8 +2597,8 @@ void TextEdit::cursor_set_line(int p_row) { cursor.line=p_row; cursor.column=get_char_pos_for( cursor.last_fit_x, get_line( cursor.line) ); - - adjust_viewport_to_cursor(); + if (p_adjust_viewport) + adjust_viewport_to_cursor(); setting_row=false; @@ -2774,6 +2905,10 @@ bool TextEdit::is_syntax_coloring_enabled() const { return syntax_coloring; } +void TextEdit::set_auto_indent(bool p_auto_indent) { + auto_indent = p_auto_indent; +} + void TextEdit::cut() { if (!selection.active) @@ -2832,9 +2967,14 @@ void TextEdit::select_all() { selection.active=true; selection.from_line=0; selection.from_column=0; + selection.selecting_line=0; + selection.selecting_column=0; selection.to_line=text.size()-1; selection.to_column=text[selection.to_line].length(); - selection.selecting_mode=Selection::MODE_NONE; + selection.selecting_mode=Selection::MODE_SHIFT; + selection.shiftclick_left=true; + cursor_set_line( selection.to_line, false ); + cursor_set_column( selection.to_column, false ); update(); } @@ -2873,12 +3013,20 @@ void TextEdit::select(int p_from_line,int p_from_column,int p_to_line,int p_to_c } else if (selection.from_column>selection.to_column) { + selection.shiftclick_left = false; SWAP( selection.from_column, selection.to_column ); + } else { + + selection.shiftclick_left = true; } } else if (selection.from_line>selection.to_line) { + selection.shiftclick_left = false; SWAP( selection.from_line, selection.to_line ); SWAP( selection.from_column, selection.to_column ); + } else { + + selection.shiftclick_left = true; } @@ -3502,10 +3650,8 @@ String TextEdit::get_tooltip(const Point2& p_pos) const { if (!tooltip_obj) return Control::get_tooltip(p_pos); int row,col; - if (!_get_mouse_pos(p_pos, row,col)) { - return Control::get_tooltip(p_pos); - } - + _get_mouse_pos(p_pos, row, col); + String s = text[row]; if (s.length()==0) return Control::get_tooltip(p_pos); @@ -3580,6 +3726,7 @@ void TextEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("_cursor_changed_emit"),&TextEdit::_cursor_changed_emit); ObjectTypeDB::bind_method(_MD("_text_changed_emit"),&TextEdit::_text_changed_emit); ObjectTypeDB::bind_method(_MD("_push_current_op"),&TextEdit::_push_current_op); + ObjectTypeDB::bind_method(_MD("_click_selection_held"),&TextEdit::_click_selection_held); BIND_CONSTANT( SEARCH_MATCH_CASE ); BIND_CONSTANT( SEARCH_WHOLE_WORDS ); @@ -3595,10 +3742,10 @@ void TextEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_line_count"),&TextEdit::get_line_count); ObjectTypeDB::bind_method(_MD("get_text"),&TextEdit::get_text); - ObjectTypeDB::bind_method(_MD("get_line"),&TextEdit::get_line); + ObjectTypeDB::bind_method(_MD("get_line","line"),&TextEdit::get_line); - ObjectTypeDB::bind_method(_MD("cursor_set_column","column"),&TextEdit::cursor_set_column); - ObjectTypeDB::bind_method(_MD("cursor_set_line","line"),&TextEdit::cursor_set_line); + ObjectTypeDB::bind_method(_MD("cursor_set_column","column","adjust_viewport"),&TextEdit::cursor_set_column,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("cursor_set_line","line","adjust_viewport"),&TextEdit::cursor_set_line,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("cursor_get_column"),&TextEdit::cursor_get_column); ObjectTypeDB::bind_method(_MD("cursor_get_line"),&TextEdit::cursor_get_line); @@ -3684,7 +3831,7 @@ TextEdit::TextEdit() { selection.selecting_mode=Selection::MODE_NONE; selection.selecting_line=0; selection.selecting_column=0; - selection.selecting_test=false; + selection.selecting_text=false; selection.active=false; syntax_coloring=false; @@ -3694,6 +3841,11 @@ TextEdit::TextEdit() { idle_detect->set_one_shot(true); idle_detect->set_wait_time(GLOBAL_DEF("display/text_edit_idle_detect_sec",3)); idle_detect->connect("timeout", this,"_push_current_op"); + + click_select_held = memnew( Timer ); + add_child(click_select_held); + click_select_held->set_wait_time(0.05); + click_select_held->connect("timeout", this,"_click_selection_held"); #if 0 syntax_coloring=true; @@ -3730,7 +3882,7 @@ TextEdit::TextEdit() { next_operation_is_complex=false; auto_brace_completion_enabled=false; brace_matching_enabled=false; - + auto_indent=false; } TextEdit::~TextEdit() diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 9ffe8a5bae..2ca5ab054a 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -55,7 +55,7 @@ class TextEdit : public Control { Mode selecting_mode; int selecting_line,selecting_column; - bool selecting_test; + bool selecting_text; bool active; @@ -213,11 +213,13 @@ class TextEdit : public Control { bool auto_brace_completion_enabled; bool brace_matching_enabled; + bool auto_indent; bool cut_copy_line; uint64_t last_dblclk; Timer *idle_detect; + Timer *click_select_held; HScrollBar *h_scroll; VScrollBar *v_scroll; bool updating_scrolls; @@ -239,6 +241,7 @@ class TextEdit : public Control { void adjust_viewport_to_cursor(); void _scroll_moved(double); void _update_scrollbars(); + void _click_selection_held(); void _pre_shift_selection(); void _post_shift_selection(); @@ -270,7 +273,7 @@ class TextEdit : public Control { void _confirm_completion(); void _update_completion_candidates(); - bool _get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const; + void _get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const; protected: @@ -323,9 +326,10 @@ public: brace_matching_enabled=p_enabled; update(); } + void set_auto_indent(bool p_auto_indent); - void cursor_set_column(int p_col); - void cursor_set_line(int p_row); + void cursor_set_column(int p_col, bool p_adjust_viewport=true); + void cursor_set_line(int p_row, bool p_adjust_viewport=true); int cursor_get_column() const; int cursor_get_line() const; diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 5b2caecb5b..c885b2d73e 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -42,22 +42,22 @@ Size2 TextureButton::get_minimum_size() const { else rscale= hover->get_size(); } else - rscale= pressed->get_size()*scale; + rscale=pressed->get_size(); } else rscale= normal->get_size(); - return rscale*scale; + return rscale*scale.abs(); } bool TextureButton::has_point(const Point2& p_point) const { - if (scale[0] <= 0 || scale[1] <= 0) { + if (scale[0] == 0 || scale[1] == 0) { return false; } - Point2 ppos = p_point/scale; + Point2 ppos = p_point/scale.abs(); if (click_mask.is_valid()) { @@ -145,7 +145,7 @@ void TextureButton::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_disabled_texture","texture:Texture"),&TextureButton::set_disabled_texture); ObjectTypeDB::bind_method(_MD("set_focused_texture","texture:Texture"),&TextureButton::set_focused_texture); ObjectTypeDB::bind_method(_MD("set_click_mask","mask:BitMap"),&TextureButton::set_click_mask); - ObjectTypeDB::bind_method(_MD("set_scale","scale"),&TextureButton::set_scale); + ObjectTypeDB::bind_method(_MD("set_texture_scale","scale"),&TextureButton::set_texture_scale); ObjectTypeDB::bind_method(_MD("set_modulate","color"),&TextureButton::set_modulate); ObjectTypeDB::bind_method(_MD("get_normal_texture:Texture"),&TextureButton::get_normal_texture); @@ -154,7 +154,7 @@ void TextureButton::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_disabled_texture:Texture"),&TextureButton::get_disabled_texture); ObjectTypeDB::bind_method(_MD("get_focused_texture:Texture"),&TextureButton::get_focused_texture); ObjectTypeDB::bind_method(_MD("get_click_mask:BitMap"),&TextureButton::get_click_mask); - ObjectTypeDB::bind_method(_MD("get_scale"),&TextureButton::get_scale); + ObjectTypeDB::bind_method(_MD("get_texture_scale"),&TextureButton::get_texture_scale); ObjectTypeDB::bind_method(_MD("get_modulate"),&TextureButton::get_modulate); ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"textures/normal",PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_normal_texture"), _SCS("get_normal_texture")); @@ -163,7 +163,7 @@ void TextureButton::_bind_methods() { ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"textures/disabled",PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_disabled_texture"), _SCS("get_disabled_texture")); ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"textures/focused",PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_focused_texture"), _SCS("get_focused_texture")); ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT,"textures/click_mask",PROPERTY_HINT_RESOURCE_TYPE,"BitMap"), _SCS("set_click_mask"), _SCS("get_click_mask")) ; - ADD_PROPERTYNO(PropertyInfo(Variant::VECTOR2,"params/scale",PROPERTY_HINT_RANGE,"0.01,1024,0.01"), _SCS("set_scale"), _SCS("get_scale")); + ADD_PROPERTYNO(PropertyInfo(Variant::VECTOR2,"params/scale",PROPERTY_HINT_RANGE,"0.01,1024,0.01"), _SCS("set_texture_scale"), _SCS("get_texture_scale")); ADD_PROPERTYNO(PropertyInfo(Variant::COLOR,"params/modulate"), _SCS("set_modulate"), _SCS("get_modulate")); } @@ -232,14 +232,14 @@ void TextureButton::set_focused_texture(const Ref<Texture>& p_focused) { focused = p_focused; }; -void TextureButton::set_scale(Size2 p_scale) { +void TextureButton::set_texture_scale(Size2 p_scale) { scale=p_scale; minimum_size_changed(); update(); } -Size2 TextureButton::get_scale() const{ +Size2 TextureButton::get_texture_scale() const{ return scale; } diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h index 01924c1c15..0556df8061 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -68,8 +68,8 @@ public: Ref<Texture> get_focused_texture() const; Ref<BitMap> get_click_mask() const; - void set_scale(Size2 p_scale); - Size2 get_scale() const; + void set_texture_scale(Size2 p_scale); + Size2 get_texture_scale() const; void set_modulate(const Color& p_modulate); Color get_modulate() const; diff --git a/scene/gui/texture_frame.cpp b/scene/gui/texture_frame.cpp index 5a6bc86638..73fecf591a 100644 --- a/scene/gui/texture_frame.cpp +++ b/scene/gui/texture_frame.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/texture_frame.h b/scene/gui/texture_frame.h index 0ccbf5a591..f6fe6ae89d 100644 --- a/scene/gui/texture_frame.h +++ b/scene/gui/texture_frame.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp index 0d549108fa..e05d35a81d 100644 --- a/scene/gui/texture_progress.cpp +++ b/scene/gui/texture_progress.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -233,11 +233,7 @@ float TextureProgress::get_radial_initial_angle() void TextureProgress::set_fill_degrees(float p_angle) { - while(p_angle>360) - p_angle-=360; - while (p_angle<0) - p_angle+=360; - rad_max_degrees=p_angle; + rad_max_degrees=CLAMP(p_angle,0,360); update(); } @@ -302,4 +298,5 @@ TextureProgress::TextureProgress() { mode=FILL_LEFT_TO_RIGHT; rad_center_off=Point2(); + rad_max_degrees=360; } diff --git a/scene/gui/texture_progress.h b/scene/gui/texture_progress.h index 7187fd5f07..a4bbd71e94 100644 --- a/scene/gui/texture_progress.h +++ b/scene/gui/texture_progress.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/tool_button.cpp b/scene/gui/tool_button.cpp index d5bcb73476..fd27800384 100644 --- a/scene/gui/tool_button.cpp +++ b/scene/gui/tool_button.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/tool_button.h b/scene/gui/tool_button.h index 648d776b51..f48d7d413c 100644 --- a/scene/gui/tool_button.h +++ b/scene/gui/tool_button.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 5df6f2ced9..8d28180490 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -672,7 +672,7 @@ void TreeItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("clear_custom_bg_color","column"),&TreeItem::clear_custom_bg_color); ObjectTypeDB::bind_method(_MD("get_custom_bg_color","column"),&TreeItem::get_custom_bg_color); - ObjectTypeDB::bind_method(_MD("add_button","column","button:Texture"),&TreeItem::add_button); + ObjectTypeDB::bind_method(_MD("add_button","column","button:Texture","button_idx"),&TreeItem::add_button); ObjectTypeDB::bind_method(_MD("get_button_count","column"),&TreeItem::get_button_count); ObjectTypeDB::bind_method(_MD("get_button:Texture","column","button_idx"),&TreeItem::get_button); ObjectTypeDB::bind_method(_MD("erase_button","column","button_idx"),&TreeItem::erase_button); @@ -962,7 +962,9 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& Point2i guide_space=Point2i( cache.guide_width , height ); - if (p_item->childs) { //has childs, draw the guide box + + + if (!hide_folding && p_item->childs) { //has childs, draw the guide box Ref<Texture> arrow; @@ -986,7 +988,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& int font_ascent=font->get_ascent(); - int ofs = p_pos.x + cache.item_margin; + int ofs = p_pos.x + (hide_folding?cache.hseparation:cache.item_margin); for (int i=0;i<columns.size();i++) { int w = get_column_width(i); @@ -1062,7 +1064,10 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& if (p_item->cells[i].custom_bg_color) { - VisualServer::get_singleton()->canvas_item_add_rect(ci,cell_rect,p_item->cells[i].bg_color); + Rect2 r=cell_rect; + r.pos.x-=cache.hseparation; + r.size.x+=cache.hseparation; + VisualServer::get_singleton()->canvas_item_add_rect(ci,r,p_item->cells[i].bg_color); } Color col=p_item->cells[i].custom_color?p_item->cells[i].color:get_color( p_item->cells[i].selected?"font_color_selected":"font_color"); @@ -1364,7 +1369,40 @@ Rect2 Tree::search_item_rect(TreeItem *p_from, TreeItem *p_item) { } +void Tree::_range_click_timeout() { + + if (range_item_last && !range_drag_enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + + Point2 pos = (Input::get_singleton()->get_mouse_pos()-get_global_pos())-cache.bg->get_offset(); + if (show_column_titles) { + pos.y-=_get_title_button_height(); + + if (pos.y<0) { + range_click_timer->stop(); + return; + } + } + + click_handled=false; + InputModifierState mod = {}; // should be irrelevant.. + + blocked++; + propagate_mouse_event(pos+cache.offset, 0, 0, false, root, BUTTON_LEFT, mod); + blocked--; + + if (range_click_timer->is_one_shot()) { + range_click_timer->set_wait_time(0.05); + range_click_timer->set_one_shot(false); + range_click_timer->start(); + } + + if (!click_handled) + range_click_timer->stop(); + } else { + range_click_timer->stop(); + } +} int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_doubleclick,TreeItem *p_item,int p_button,const InputModifierState& p_mod) { @@ -1376,7 +1414,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ if (!skip && p_pos.y<item_h) { // check event! - if (p_pos.x >=x_ofs && p_pos.x < (x_ofs+cache.item_margin) ) { + if (!hide_folding && (p_pos.x >=x_ofs && p_pos.x < (x_ofs+cache.item_margin) )) { if (p_item->childs) @@ -1559,9 +1597,25 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ bool up=p_pos.y < (item_h /2); if (p_button==BUTTON_LEFT) { + + if (range_click_timer->get_time_left() == 0) { + + range_item_last=p_item; + range_up_last=up; + + range_click_timer->set_wait_time(0.6); + range_click_timer->set_one_shot(true); + range_click_timer->start(); + + } else if (up != range_up_last) { + + return -1; // break. avoid changing direction on mouse held + } + p_item->set_range( col, c.val + (up?1.0:-1.0) * c.step ); item_edited(col,p_item); + } else if (p_button==BUTTON_RIGHT) { p_item->set_range( col, (up?c.max:c.min) ); @@ -1667,6 +1721,7 @@ void Tree::text_editor_enter(String p_text) { text_editor->hide(); + value_editor->hide(); if (!popup_edited_item) return; @@ -2019,6 +2074,8 @@ void Tree::_input_event(InputEvent p_event) { update_cache(); const InputEventMouseMotion& b=p_event.mouse_motion; + range_click_timer->stop(); + Ref<StyleBox> bg = cache.bg; Point2 pos = Point2(b.x,b.y) - bg->get_offset(); @@ -2026,7 +2083,6 @@ void Tree::_input_event(InputEvent p_event) { Cache::ClickType old_hover = cache.hover_type; int old_index = cache.hover_index; - cache.hover_type=Cache::CLICK_NONE; cache.hover_index=0; if (show_column_titles) { @@ -2072,8 +2128,7 @@ void Tree::_input_event(InputEvent p_event) { float diff_y = -b.relative_y; diff_y=Math::pow(ABS(diff_y),1.8)*SGN(diff_y); diff_y*=0.1; - range_drag_base=CLAMP(range_drag_base + c.step * diff_y, c.min, c.max); - + range_drag_base=CLAMP(range_drag_base + c.step * diff_y, c.min, c.max); popup_edited_item->set_range(popup_edited_item_col,range_drag_base); item_edited(popup_edited_item_col,popup_edited_item); @@ -2103,6 +2158,8 @@ void Tree::_input_event(InputEvent p_event) { if (b.button_index==BUTTON_LEFT) { + range_click_timer->stop(); + if (pressing_for_editor) { if (range_drag_enabled) { @@ -2110,18 +2167,9 @@ void Tree::_input_event(InputEvent p_event) { range_drag_enabled=false; Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); warp_mouse(range_drag_capture_pos); - } else { - text_editor->set_pos(pressing_item_rect.pos); - text_editor->set_size(pressing_item_rect.size); - - text_editor->clear(); - text_editor->set_text( pressing_for_editor_text ); - text_editor->select_all(); - - text_editor->show_modal(); - text_editor->grab_focus(); + } else + edit_selected(); - } pressing_for_editor=false; } @@ -2223,10 +2271,13 @@ void Tree::_input_event(InputEvent p_event) { } break; case BUTTON_WHEEL_UP: { + + range_click_timer->stop(); v_scroll->set_val( v_scroll->get_val()-v_scroll->get_page()/8 ); } break; case BUTTON_WHEEL_DOWN: { + range_click_timer->stop(); v_scroll->set_val( v_scroll->get_val()+v_scroll->get_page()/8 ); } break; } @@ -2266,9 +2317,12 @@ bool Tree::edit_selected() { TreeItem::Cell &c = s->cells[col]; + if (c.mode==TreeItem::CELL_MODE_CHECK) { - - if (c.mode==TreeItem::CELL_MODE_CUSTOM) { + s->set_checked(col, !c.checked); + item_edited(col,s); + return true; + } else if (c.mode==TreeItem::CELL_MODE_CUSTOM) { edited_item=s; edited_col=col; @@ -3114,9 +3168,20 @@ bool Tree::can_cursor_exit_tree() const { return cursor_can_exit_tree; } +void Tree::set_hide_folding(bool p_hide) { + hide_folding=p_hide; + update(); +} + +bool Tree::is_folding_hidden() const { + + return hide_folding; +} + void Tree::_bind_methods() { + ObjectTypeDB::bind_method(_MD("_range_click_timeout"),&Tree::_range_click_timeout); ObjectTypeDB::bind_method(_MD("_input_event"),&Tree::_input_event); ObjectTypeDB::bind_method(_MD("_popup_select"),&Tree::popup_select); ObjectTypeDB::bind_method(_MD("_text_editor_enter"),&Tree::text_editor_enter); @@ -3127,11 +3192,11 @@ void Tree::_bind_methods() { ObjectTypeDB::bind_method(_MD("create_item:TreeItem","parent:TreeItem"),&Tree::_create_item,DEFVAL((Object*)NULL)); ObjectTypeDB::bind_method(_MD("get_root:TreeItem"),&Tree::get_root); - ObjectTypeDB::bind_method(_MD("set_column_min_width"),&Tree::set_column_min_width); - ObjectTypeDB::bind_method(_MD("set_column_expand"),&Tree::set_column_expand); - ObjectTypeDB::bind_method(_MD("get_column_width"),&Tree::get_column_width); + ObjectTypeDB::bind_method(_MD("set_column_min_width","column","min_width"),&Tree::set_column_min_width); + ObjectTypeDB::bind_method(_MD("set_column_expand","column","expand"),&Tree::set_column_expand); + ObjectTypeDB::bind_method(_MD("get_column_width","column"),&Tree::get_column_width); - ObjectTypeDB::bind_method(_MD("set_hide_root"),&Tree::set_hide_root); + ObjectTypeDB::bind_method(_MD("set_hide_root","enable"),&Tree::set_hide_root); ObjectTypeDB::bind_method(_MD("get_next_selected:TreeItem","from:TreeItem"),&Tree::_get_next_selected); ObjectTypeDB::bind_method(_MD("get_selected:TreeItem"),&Tree::get_selected); ObjectTypeDB::bind_method(_MD("get_selected_column"),&Tree::get_selected_column); @@ -3155,6 +3220,9 @@ void Tree::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_column_title","column"),&Tree::get_column_title); ObjectTypeDB::bind_method(_MD("get_scroll"),&Tree::get_scroll); + ObjectTypeDB::bind_method(_MD("set_hide_folding","hide"),&Tree::set_hide_folding); + ObjectTypeDB::bind_method(_MD("is_folding_hidden"),&Tree::is_folding_hidden); + ADD_SIGNAL( MethodInfo("item_selected")); ADD_SIGNAL( MethodInfo("cell_selected")); @@ -3208,6 +3276,10 @@ Tree::Tree() { add_child(h_scroll); add_child(v_scroll); + range_click_timer = memnew( Timer ); + range_click_timer->connect("timeout",this,"_range_click_timeout"); + add_child(range_click_timer); + h_scroll->connect("value_changed", this,"_scroll_moved"); v_scroll->connect("value_changed", this,"_scroll_moved"); text_editor->connect("text_entered", this,"_text_editor_enter"); @@ -3242,6 +3314,8 @@ Tree::Tree() { pressing_for_editor=false; range_drag_enabled=false; + hide_folding=false; + } diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 3fbd7c95d9..54e6a9c6b9 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -127,7 +127,7 @@ friend class Tree; - TreeItem(Tree *p_tree); + TreeItem(Tree *p_tree); void _changed_notify(int p_cell); @@ -228,6 +228,7 @@ public: void set_tooltip(int p_column, const String& p_tooltip); String get_tooltip(int p_column) const; + void clear_children(); void move_to_top(); @@ -300,6 +301,11 @@ friend class TreeItem; Vector<ColumnInfo> columns; + Timer *range_click_timer; + TreeItem *range_item_last; + bool range_up_last; + void _range_click_timeout(); + int compute_item_height(TreeItem *p_item) const; int get_item_height(TreeItem *p_item) const; // void draw_item_text(String p_text,const Ref<Texture>& p_icon,int p_icon_max_w,bool p_tool,Rect2i p_rect,const Color& p_color); @@ -410,6 +416,8 @@ friend class TreeItem; bool drag_touching_deaccel; bool click_handled; + bool hide_folding; + protected: static void _bind_methods(); @@ -467,6 +475,11 @@ public: VScrollBar *get_vscroll_bar() { return v_scroll; } + void set_hide_folding(bool p_hide); + bool is_folding_hidden() const; + + + Tree(); ~Tree(); diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp index f50552b32c..517cd414c5 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_player.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "video_player.h" - +#include "os/os.h" int VideoPlayer::InternalStream::get_channel_count() const { @@ -117,8 +117,9 @@ void VideoPlayer::_notification(int p_notification) { case NOTIFICATION_ENTER_TREE: { //set_idle_process(false); //don't annoy - if (stream.is_valid() && autoplay && !get_tree()->is_editor_hint()) + if (stream.is_valid() && autoplay && !get_tree()->is_editor_hint()) { play(); + } } break; case NOTIFICATION_PROCESS: { @@ -130,7 +131,7 @@ void VideoPlayer::_notification(int p_notification) { if (!playback->is_playing()) return; - double audio_time = AudioServer::get_singleton()->get_mix_time(); + double audio_time = OS::get_singleton()->get_ticks_usec()/1000000.0; //AudioServer::get_singleton()->get_mix_time(); double delta = last_audio_time==0?0:audio_time-last_audio_time; last_audio_time=audio_time; @@ -196,10 +197,10 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) { stream=p_stream; if (stream.is_valid()) { - stream->set_audio_track(audio_track); - playback=stream->instance_playback(); + stream->set_audio_track(audio_track); + playback=stream->instance_playback(); } else { - playback=Ref<VideoStreamPlayback>(); + playback=Ref<VideoStreamPlayback>(); } if (!playback.is_null()) { @@ -249,6 +250,8 @@ void VideoPlayer::stop() { return; playback->stop(); + AudioServer::get_singleton()->stream_set_active(stream_rid,false); + resampler.clear(); set_process(false); last_audio_time=0; }; @@ -268,6 +271,7 @@ void VideoPlayer::set_paused(bool p_paused) { playback->set_paused(p_paused); set_process(!p_paused); }; + last_audio_time = 0; }; bool VideoPlayer::is_paused() const { @@ -336,6 +340,13 @@ float VideoPlayer::get_stream_pos() const { return playback->get_pos(); }; +Ref<Texture> VideoPlayer::get_video_texture() { + + if (playback.is_valid()) + return playback->get_texture(); + + return Ref<Texture> (); +} void VideoPlayer::set_autoplay(bool p_enable) { @@ -382,13 +393,15 @@ void VideoPlayer::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_buffering_msec","msec"),&VideoPlayer::set_buffering_msec); ObjectTypeDB::bind_method(_MD("get_buffering_msec"),&VideoPlayer::get_buffering_msec); + ObjectTypeDB::bind_method(_MD("get_video_texutre:Texture"), &VideoPlayer::get_video_texture ); + + ADD_PROPERTY( PropertyInfo(Variant::INT, "stream/audio_track",PROPERTY_HINT_RANGE,"0,128,1"), _SCS("set_audio_track"), _SCS("get_audio_track") ); ADD_PROPERTY( PropertyInfo(Variant::OBJECT, "stream/stream", PROPERTY_HINT_RESOURCE_TYPE,"VideoStream"), _SCS("set_stream"), _SCS("get_stream") ); // ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/loop"), _SCS("set_loop"), _SCS("has_loop") ); ADD_PROPERTY( PropertyInfo(Variant::REAL, "stream/volume_db", PROPERTY_HINT_RANGE,"-80,24,0.01"), _SCS("set_volume_db"), _SCS("get_volume_db") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/autoplay"), _SCS("set_autoplay"), _SCS("has_autoplay") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/paused"), _SCS("set_paused"), _SCS("is_paused") ); - ADD_PROPERTY( PropertyInfo(Variant::INT, "stream/audio_track",PROPERTY_HINT_RANGE,"0,128,1"), _SCS("set_audio_track"), _SCS("get_audio_track") ); - ADD_PROPERTY( PropertyInfo( Variant::BOOL, "expand" ), _SCS("set_expand"),_SCS("has_expand") ); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "expand" ), _SCS("set_expand"),_SCS("has_expand") ); } diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h index c485e3d6b6..9ce1ba78f4 100644 --- a/scene/gui/video_player.h +++ b/scene/gui/video_player.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -88,6 +88,8 @@ public: bool has_expand() const; + Ref<Texture> get_video_texture(); + void set_stream(const Ref<VideoStream> &p_stream); Ref<VideoStream> get_stream() const; @@ -110,8 +112,8 @@ public: void set_autoplay(bool p_vol); bool has_autoplay() const; - void set_audio_track(int p_track); - int get_audio_track() const; + void set_audio_track(int p_track); + int get_audio_track() const; void set_buffering_msec(int p_msec); int get_buffering_msec() const; |