diff options
32 files changed, 853 insertions, 60 deletions
diff --git a/core/globals.cpp b/core/globals.cpp index 731c5b7dff..d252d4e280 100644 --- a/core/globals.cpp +++ b/core/globals.cpp @@ -1477,7 +1477,6 @@ Globals::Globals() { custom_prop_info["render/mipmap_policy"]=PropertyInfo(Variant::INT,"render/mipmap_policy",PROPERTY_HINT_ENUM,"Allow,Allow For Po2,Disallow"); custom_prop_info["render/thread_model"]=PropertyInfo(Variant::INT,"render/thread_model",PROPERTY_HINT_ENUM,"Single-Unsafe,Single-Safe,Multi-Threaded"); custom_prop_info["physics_2d/thread_model"]=PropertyInfo(Variant::INT,"physics_2d/thread_model",PROPERTY_HINT_ENUM,"Single-Unsafe,Single-Safe,Multi-Threaded"); - set("display/emulate_touchscreen",false); using_datapack=false; } diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp index c291714573..a64b3d2715 100644 --- a/core/object_type_db.cpp +++ b/core/object_type_db.cpp @@ -746,6 +746,25 @@ bool ObjectTypeDB::has_method(StringName p_type,StringName p_method,bool p_no_in } +bool ObjectTypeDB::get_setter_and_type_for_property(const StringName& p_class, const StringName& p_prop, StringName& r_class, StringName& r_setter) { + + TypeInfo *type=types.getptr(p_class); + TypeInfo *check=type; + while(check) { + + if (check->property_setget.has(p_prop)) { + r_class=check->name; + r_setter=check->property_setget[p_prop].setter; + return true; + } + + check=check->inherits_ptr; + } + + return false; + +} + #ifdef DEBUG_METHODS_ENABLED MethodBind* ObjectTypeDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , const MethodDefinition &method_name, const Variant **p_defs, int p_defcount) { StringName mdname=method_name.name; diff --git a/core/object_type_db.h b/core/object_type_db.h index caa5baddd5..bfa0f921e5 100644 --- a/core/object_type_db.h +++ b/core/object_type_db.h @@ -475,7 +475,9 @@ public: static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false); static int get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success=NULL); static StringName get_category(const StringName& p_node); - + + static bool get_setter_and_type_for_property(const StringName& p_class, const StringName& p_prop, StringName& r_class, StringName& r_setter); + static void set_type_enabled(StringName p_type,bool p_enable); static bool is_type_enabled(StringName p_type); diff --git a/core/os/input.cpp b/core/os/input.cpp index 2b939ede46..cf2938f5cd 100644 --- a/core/os/input.cpp +++ b/core/os/input.cpp @@ -271,6 +271,38 @@ void InputDefault::parse_input_event(const InputEvent& p_event) { mouse_button_mask|=(1<<p_event.mouse_button.button_index); else mouse_button_mask&=~(1<<p_event.mouse_button.button_index); + + if (main_loop && emulate_touch && p_event.mouse_button.button_index==1) { + InputEventScreenTouch touch_event; + touch_event.index=0; + touch_event.pressed=p_event.mouse_button.pressed; + touch_event.x=p_event.mouse_button.x; + touch_event.y=p_event.mouse_button.y; + InputEvent ev; + ev.type=InputEvent::SCREEN_TOUCH; + ev.screen_touch=touch_event; + main_loop->input_event(ev); + } + } break; + case InputEvent::MOUSE_MOTION: { + + if (main_loop && emulate_touch && p_event.mouse_motion.button_mask&1) { + InputEventScreenDrag drag_event; + drag_event.index=0; + drag_event.x=p_event.mouse_motion.x; + drag_event.y=p_event.mouse_motion.y; + drag_event.relative_x=p_event.mouse_motion.relative_x; + drag_event.relative_y=p_event.mouse_motion.relative_y; + drag_event.speed_x=p_event.mouse_motion.speed_x; + drag_event.speed_y=p_event.mouse_motion.speed_y; + + InputEvent ev; + ev.type=InputEvent::SCREEN_DRAG; + ev.screen_drag=drag_event; + + main_loop->input_event(ev); + } + } break; case InputEvent::JOYSTICK_BUTTON: { @@ -362,8 +394,19 @@ void InputDefault::action_release(const StringName& p_action){ } } +void InputDefault::set_emulate_touch(bool p_emulate) { + + emulate_touch=p_emulate; +} + +bool InputDefault::is_emulating_touchscreen() const { + + return emulate_touch; +} + InputDefault::InputDefault() { mouse_button_mask=0; + emulate_touch=false; main_loop=NULL; } diff --git a/core/os/input.h b/core/os/input.h index ce14c2166e..5c69ced825 100644 --- a/core/os/input.h +++ b/core/os/input.h @@ -78,6 +78,8 @@ public: void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const; + virtual bool is_emulating_touchscreen() const=0; + Input(); }; @@ -99,6 +101,8 @@ class InputDefault : public Input { Vector2 mouse_pos; MainLoop *main_loop; + bool emulate_touch; + struct SpeedTrack { uint64_t last_tick; @@ -147,6 +151,9 @@ public: void iteration(float p_step); + void set_emulate_touch(bool p_emulate); + virtual bool is_emulating_touchscreen() const; + InputDefault(); }; diff --git a/core/os/os.cpp b/core/os/os.cpp index efcd492230..2db926e556 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -31,7 +31,7 @@ #include <stdarg.h> #include "dir_access.h" #include "globals.h" - +#include "input.h" OS* OS::singleton=NULL; @@ -363,7 +363,7 @@ Error OS::set_cwd(const String& p_cwd) { bool OS::has_touchscreen_ui_hint() const { //return false; - return GLOBAL_DEF("display/emulate_touchscreen",false); + return Input::get_singleton() && Input::get_singleton()->is_emulating_touchscreen(); } int OS::get_free_static_memory() const { diff --git a/core/ustring.cpp b/core/ustring.cpp index 3cfc1e4a3c..ff7c8984fa 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -3048,6 +3048,37 @@ bool String::is_valid_identifier() const { //kind of poor should be rewritten properly +String String::world_wrap(int p_chars_per_line) const { + + int from=0; + int last_space=0; + String ret; + for(int i=0;i<length();i++) { + if (i-from>=p_chars_per_line) { + if (last_space==-1) { + ret+=substr(from,i-from+1)+"\n"; + } else { + ret+=substr(from,last_space-from)+"\n"; + i=last_space; //rewind + } + from=i+1; + last_space=-1; + } else if (operator[](i)==' ' || operator[](i)=='\t') { + last_space=i; + } else if (operator[](i)=='\n') { + ret+=substr(from,i-from); + from=i+1; + last_space=-1; + } + } + + if (from<length()) { + ret+=substr(from,length()); + } + + return ret; +} + String String::c_unescape() const { String escaped=*this; diff --git a/core/ustring.h b/core/ustring.h index 1000c1cc8a..fa25a07eb0 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -209,6 +209,7 @@ public: String xml_unescape() const; String c_escape() const; String c_unescape() const; + String world_wrap(int p_chars_per_line) const; String percent_encode() const; String percent_decode() const; diff --git a/main/main.cpp b/main/main.cpp index 19ee1c115f..805668cadd 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -75,7 +75,7 @@ #include "core/io/file_access_zip.h" #include "translation.h" #include "version.h" - +#include "os/input.h" #include "performance.h" static Globals *globals=NULL; @@ -847,6 +847,14 @@ Error Main::setup2() { GLOBAL_DEF("application/icon",String()); Globals::get_singleton()->set_custom_property_info("application/icon",PropertyInfo(Variant::STRING,"application/icon",PROPERTY_HINT_FILE,"*.png,*.webp")); + if (bool(GLOBAL_DEF("display/emulate_touchscreen",false))) { + if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton()) { + //only if no touchscreen ui hint, set emulation + InputDefault *id = Input::get_singleton()->cast_to<InputDefault>(); + if (id) + id->set_emulate_touch(true); + } + } MAIN_PRINT("Main: Load Remaps"); path_remap->load_remaps(); diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index f7aaaf7ee5..283b50f966 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2625,14 +2625,14 @@ void GDParser::_parse_class(ClassNode *p_class) { Node *subexpr=NULL; - subexpr = _parse_and_reduce_expression(p_class,false); + subexpr = _parse_and_reduce_expression(p_class,false,autoexport); if (!subexpr) return; member.expression=subexpr; if (autoexport) { - if (subexpr->type==Node::TYPE_ARRAY) { + if (1)/*(subexpr->type==Node::TYPE_ARRAY) { member._export.type=Variant::ARRAY; @@ -2640,7 +2640,7 @@ void GDParser::_parse_class(ClassNode *p_class) { member._export.type=Variant::DICTIONARY; - } else { + } else*/ { if (subexpr->type!=Node::TYPE_CONSTANT) { diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index b34d1ba7c8..16632c6627 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -504,6 +504,23 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) { mouse_mode=p_mode; if (mouse_mode==MOUSE_MODE_CAPTURED) { + + while(true) { + //flush pending motion events + + if (XPending(x11_display) > 0) { + XEvent event; + XPeekEvent(x11_display, &event); + if (event.type==MotionNotify) { + XNextEvent(x11_display,&event); + } else { + break; + } + } else { + break; + } + } + if (XGrabPointer(x11_display, x11_window, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, @@ -518,6 +535,8 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) { 0,0,0,0, (int)center.x, (int)center.y); input->set_mouse_pos(center); + } else { + do_mouse_warp=false; } } @@ -1131,7 +1150,7 @@ void OS_X11::process_xevents() { //printf("checking events %i\n", XPending(x11_display)); - bool do_mouse_warp=false; + do_mouse_warp=false; while (XPending(x11_display) > 0) { XEvent event; @@ -1244,8 +1263,38 @@ void OS_X11::process_xevents() { } break; case MotionNotify: { - + + // FUCK YOU X11 API YOU SERIOUSLY GROSS ME OUT + // YOU ARE AS GROSS AS LOOKING AT A PUTRID PILE + // OF POOP STICKING OUT OF A CLOGGED TOILET + // HOW THE FUCK I AM SUPPOSED TO KNOW WHICH ONE + // OF THE MOTION NOTIFY EVENTS IS THE ONE GENERATED + // BY WARPING THE MOUSE POINTER? + // YOU ARE FORCING ME TO FILTER ONE BY ONE TO FIND IT + // PLEASE DO ME A FAVOR AND DIE DROWNED IN A FECAL + // MOUNTAIN BECAUSE THAT'S WHERE YOU BELONG. + + while(true) { + if (mouse_mode==MOUSE_MODE_CAPTURED && event.xmotion.x==current_videomode.width/2 && event.xmotion.y==current_videomode.height/2) { + //this is likely the warp event since it was warped here + center=Vector2(event.xmotion.x,event.xmotion.y); + break; + } + + if (XPending(x11_display) > 0) { + XEvent tevent; + XPeekEvent(x11_display, &tevent); + if (tevent.type==MotionNotify) { + XNextEvent(x11_display,&event); + } else { + break; + } + } else { + break; + } + } + last_timestamp=event.xmotion.time; // Motion is also simple. diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 261a54dd25..12f0aec611 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -114,6 +114,7 @@ class OS_X11 : public OS_Unix { bool minimized; int dpad_last[2]; + bool do_mouse_warp; const char *cursor_theme; int cursor_size; diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index c521952f9b..6705cebf37 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -322,8 +322,8 @@ void Sprite::_bind_methods() { ADD_PROPERTYNZ( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset")); ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "flip_h"), _SCS("set_flip_h"),_SCS("is_flipped_h")); ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "flip_v"), _SCS("set_flip_v"),_SCS("is_flipped_v")); - ADD_PROPERTYNO( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes")); - ADD_PROPERTYNO( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes")); + ADD_PROPERTYNO( PropertyInfo( Variant::INT, "vframes",PROPERTY_HINT_RANGE,"1,16384,1"), _SCS("set_vframes"),_SCS("get_vframes")); + ADD_PROPERTYNO( PropertyInfo( Variant::INT, "hframes",PROPERTY_HINT_RANGE,"1,16384,1"), _SCS("set_hframes"),_SCS("get_hframes")); ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame")); ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate")); ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region")); diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index e9da95f3fb..c7d1249a07 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -578,8 +578,8 @@ void Sprite3D::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_hframes"),&Sprite3D::get_hframes); ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_texture"),_SCS("get_texture")); - ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes")); - ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes",PROPERTY_HINT_RANGE,"1,16384,1"), _SCS("set_vframes"),_SCS("get_vframes")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes",PROPERTY_HINT_RANGE,"1,16384,1"), _SCS("set_hframes"),_SCS("get_hframes")); ADD_PROPERTY( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame")); ADD_PROPERTY( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region")); ADD_PROPERTY( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect")); diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 41e775bbff..2478e3204c 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "spin_box.h" - +#include "os/input.h" Size2 SpinBox::get_minimum_size() const { @@ -62,6 +62,13 @@ LineEdit *SpinBox::get_line_edit() { } +void SpinBox::_line_edit_input(const InputEvent& p_event) { + + + +} + + void SpinBox::_input_event(const InputEvent& p_event) { if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed) { @@ -94,6 +101,48 @@ void SpinBox::_input_event(const InputEvent& p_event) { } break; } } + + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index==1) { + + //set_default_cursor_shape(CURSOR_VSIZE); + Vector2 cpos = Vector2(p_event.mouse_button.x,p_event.mouse_button.y); + drag.mouse_pos=cpos; + } + + 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); + if (drag.enabled) { + drag.enabled=false; + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); + warp_mouse(drag.capture_pos); + } + } + + if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_button.button_mask&1) { + + Vector2 cpos = Vector2(p_event.mouse_motion.x,p_event.mouse_motion.y); + if (drag.enabled) { + + float diff_y = drag.mouse_pos.y - cpos.y; + diff_y=pow(ABS(diff_y),1.8)*SGN(diff_y); + diff_y*=0.1; + + drag.mouse_pos=cpos; + drag.base_val=CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max()); + + set_val( drag.base_val); + + } else if (drag.mouse_pos.distance_to(cpos)>2) { + + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); + drag.enabled=true; + drag.base_val=get_val(); + drag.mouse_pos=cpos; + drag.capture_pos=cpos; + + } + } } @@ -177,6 +226,7 @@ void SpinBox::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_editable"),&SpinBox::is_editable); 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); ADD_PROPERTY(PropertyInfo(Variant::BOOL,"editable"),_SCS("set_editable"),_SCS("is_editable")); @@ -196,4 +246,6 @@ SpinBox::SpinBox() { //connect("value_changed",this,"_value_changed"); line_edit->connect("text_entered",this,"_text_entered",Vector<Variant>(),CONNECT_DEFERRED); 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; } diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 6ebe14631e..4c8cb8432a 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -44,6 +44,18 @@ class SpinBox : public Range { String prefix; String suffix; + void _line_edit_input(const InputEvent& p_event); + + + struct Drag { + float base_val; + bool enabled; + Vector2 from; + Vector2 mouse_pos; + Vector2 capture_pos; + } drag; + + void _line_edit_focus_exit(); protected: diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 4feb03feef..252414cb3e 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -31,7 +31,7 @@ #include "os/os.h" #include "os/keyboard.h" #include "globals.h" - +#include "os/input.h" @@ -70,6 +70,7 @@ Size2 TreeItem::Cell::get_icon_size() const { else return icon_region.size; } + void TreeItem::Cell::draw_icon(const RID& p_where, const Point2& p_pos, const Size2& p_size) const{ if (icon.is_null()) @@ -728,14 +729,20 @@ TreeItem::~TreeItem() { tree->root=0; } - if (tree && tree->popup_edited_item==this) + if (tree && tree->popup_edited_item==this) { tree->popup_edited_item=NULL; + tree->pressing_for_editor=false; + + } if (tree && tree->selected_item==this) tree->selected_item=NULL; - if (tree && tree->edited_item==this) + if (tree && tree->edited_item==this) { tree->edited_item=NULL; + tree->pressing_for_editor=false; + } + } @@ -1292,7 +1299,7 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col } else if (select_mode==SELECT_SINGLE || select_mode==SELECT_MULTI) { - if (&selected_cell==&c) { + if (!r_in_range && &selected_cell==&c) { if (!selected_cell.selected) { @@ -1301,6 +1308,7 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col selected_item=p_selected; selected_col=i; + emit_signal("cell_selected"); if (select_mode==SELECT_MULTI) emit_signal("multi_selected",p_current,i,true); @@ -1317,6 +1325,7 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col if (r_in_range && *r_in_range) { + if (!c.selected && c.selectable) { c.selected=true; emit_signal("multi_selected",p_current,i,true); @@ -1467,7 +1476,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ if (select_mode==SELECT_MULTI && p_mod.shift && selected_item && selected_item!=p_item) { bool inrange=false; - print_line("SELECT MULTI AND SHIFT AND ALL"); + select_single_item( p_item, root, col,selected_item,&inrange ); } else { select_single_item( p_item, root, col ); @@ -1490,7 +1499,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ /* editing */ - bool bring_up_editor=c.selected && already_selected; + bool bring_up_editor=c.selected;// && already_selected; bool bring_up_value_editor=false; String editor_text=c.text; @@ -1605,31 +1614,14 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ return -1; - click_handled=true; + + click_handled=true; popup_edited_item=p_item; popup_edited_item_col=col; - text_editor->set_pos(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs)-cache.offset ); - text_editor->set_size( Size2(col_width,item_h)); - text_editor->clear(); - text_editor->set_text( editor_text ); - text_editor->select_all(); - - if (bring_up_value_editor) { - value_editor->set_pos(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs)-cache.offset+Point2i(0,text_editor->get_size().height) ); - value_editor->set_size( Size2(col_width,1)); - value_editor->show_modal(); - updating_value_editor=true; - value_editor->set_min( c.min ); - value_editor->set_max( c.max ); - value_editor->set_step( c.step ); - value_editor->set_val( c.val ); - value_editor->set_exp_unit_value( c.expr ); - updating_value_editor=false; - } - - text_editor->show_modal(); - text_editor->grab_focus(); + pressing_item_rect=Rect2(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs)-cache.offset,Size2(col_width,item_h)); + pressing_for_editor_text=editor_text; + pressing_for_editor=true; return -1; //select } else { @@ -2062,6 +2054,33 @@ void Tree::_input_event(InputEvent p_event) { update(); } + if (pressing_for_editor && popup_edited_item && popup_edited_item->get_cell_mode(popup_edited_item_col)==TreeItem::CELL_MODE_RANGE) { + //range drag + + if (!range_drag_enabled) { + + Vector2 cpos = Vector2(b.x,b.y); + if (cpos.distance_to(pressing_pos)>2) { + range_drag_enabled=true; + range_drag_capture_pos=cpos; + range_drag_base=popup_edited_item->get_range(popup_edited_item_col); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); + } + } else { + + TreeItem::Cell &c=popup_edited_item->cells[popup_edited_item_col]; + float diff_y = -b.relative_y; + diff_y=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); + + popup_edited_item->set_range(popup_edited_item_col,range_drag_base); + item_edited(popup_edited_item_col,popup_edited_item); + + } + + } + if (drag_touching && ! drag_touching_deaccel) { @@ -2084,6 +2103,31 @@ void Tree::_input_event(InputEvent p_event) { if (b.button_index==BUTTON_LEFT) { + if (pressing_for_editor) { + + if (range_drag_enabled) { + + 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(); + + } + pressing_for_editor=false; + + } + + + if (cache.click_type==Cache::CLICK_BUTTON) { emit_signal("button_pressed",cache.click_item,cache.click_column,cache.click_id); @@ -2145,11 +2189,15 @@ void Tree::_input_event(InputEvent p_event) { break; click_handled=false; + pressing_for_editor=false; blocked++; bool handled = propagate_mouse_event(pos+cache.offset,0,0,b.doubleclick,root,b.button_index,b.mod); blocked--; + if (pressing_for_editor) { + pressing_pos=Point2(b.x,b.y); + } if (drag_touching) { @@ -2615,6 +2663,8 @@ void Tree::clear() { selected_item=NULL; edited_item=NULL; popup_edited_item=NULL; + selected_item=NULL; + pressing_for_editor=false; update(); }; @@ -3189,6 +3239,8 @@ Tree::Tree() { drag_speed=0; drag_touching=false; drag_touching_deaccel=false; + pressing_for_editor=false; + range_drag_enabled=false; } diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 8ddddd0630..3fbd7c95d9 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -258,7 +258,18 @@ friend class TreeItem; TreeItem *popup_edited_item; TreeItem *selected_item; TreeItem *edited_item; + + int pressed_button; + bool pressing_for_editor; + String pressing_for_editor_text; + Vector2 pressing_pos; + Rect2 pressing_item_rect; + + float range_drag_base; + bool range_drag_enabled; + Vector2 range_drag_capture_pos; + //TreeItem *cursor_item; //int cursor_column; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 3ee4da5974..5a99538a5f 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -297,7 +297,7 @@ void make_default_theme() { t->set_color("font_color_hover","MenuButton", control_font_color_hover ); t->set_color("font_color_disabled","MenuButton", Color(1,1,1,0.3) ); - t->set_constant("hseparation","MenuButton", 0 ); + t->set_constant("hseparation","MenuButton", 3 ); // CheckBox diff --git a/tools/editor/array_property_edit.cpp b/tools/editor/array_property_edit.cpp new file mode 100644 index 0000000000..9cd443270b --- /dev/null +++ b/tools/editor/array_property_edit.cpp @@ -0,0 +1,231 @@ +#include "array_property_edit.h" + +#include "editor_node.h" + +#define ITEMS_PER_PAGE 100 + +Variant ArrayPropertyEdit::get_array() const{ + + Object*o = ObjectDB::get_instance(obj); + if (!o) + return Array(); + Variant arr=o->get(property); + if (!arr.is_array()) { + Variant::CallError ce; + arr=Variant::construct(default_type,NULL,0,ce); + } + return arr; +} + +void ArrayPropertyEdit::_notif_change() { + _change_notify(); +} +void ArrayPropertyEdit::_notif_changev(const String& p_v) { + + _change_notify(p_v.utf8().get_data()); +} + +void ArrayPropertyEdit::_set_size(int p_size) { + + Variant arr = get_array(); + arr.call("resize",p_size); + Object*o = ObjectDB::get_instance(obj); + if (!o) + return; + + o->set(property,arr); + +} + +void ArrayPropertyEdit::_set_value(int p_idx,const Variant& p_value) { + + Variant arr = get_array(); + arr.set(p_idx,p_value); + Object*o = ObjectDB::get_instance(obj); + if (!o) + return; + + o->set(property,arr); +} + +bool ArrayPropertyEdit::_set(const StringName& p_name, const Variant& p_value){ + + String pn=p_name; + + if (pn.begins_with("array/")) { + + if (pn=="array/size") { + + Variant arr = get_array(); + int size = arr.call("size"); + + int newsize=p_value; + if (newsize==size) + return true; + + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Resize Array"); + ur->add_do_method(this,"_set_size",newsize); + ur->add_undo_method(this,"_set_size",size); + if (newsize<size) { + for(int i=newsize;i<size;i++) { + ur->add_undo_method(this,"_set_value",i,arr.get(i)); + + } + } + ur->add_do_method(this,"_notif_change"); + ur->add_undo_method(this,"_notif_change"); + ur->commit_action(); + return true; + } + if (pn=="array/page") { + page=p_value; + _change_notify(); + return true; + } + } else if (pn.begins_with("indices")) { + + if (pn.find("_")!=-1) { + //type + int idx=pn.get_slicec('/',1).get_slicec('_',0).to_int(); + + int type = p_value; + + Variant arr = get_array(); + + Variant value = arr.get(idx); + if (value.get_type()!=type && type>=0 && type<Variant::VARIANT_MAX) { + Variant::CallError ce; + Variant new_value=Variant::construct(Variant::Type(type),NULL,0,ce); + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + + ur->create_action("Change Array Value Type"); + ur->add_do_method(this,"_set_value",idx,new_value); + ur->add_undo_method(this,"_set_value",idx,value); + ur->add_do_method(this,"_notif_change"); + ur->add_undo_method(this,"_notif_change"); + ur->commit_action(); + + } + return true; + + } else { + int idx=pn.get_slicec('/',1).to_int(); + Variant arr = get_array(); + + Variant value = arr.get(idx); + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + + ur->create_action("Change Array Value"); + ur->add_do_method(this,"_set_value",idx,p_value); + ur->add_undo_method(this,"_set_value",idx,value); + ur->add_do_method(this,"_notif_changev",p_name); + ur->add_undo_method(this,"_notif_changev",p_name); + ur->commit_action(); + return true; + } + } + + return false; +} + +bool ArrayPropertyEdit::_get(const StringName& p_name,Variant &r_ret) const { + + Variant arr = get_array(); + //int size = arr.call("size"); + + String pn=p_name; + if (pn.begins_with("array/")) { + + if (pn=="array/size") { + r_ret=arr.call("size"); + return true; + } + if (pn=="array/page") { + r_ret=page; + return true; + } + } else if (pn.begins_with("indices")) { + + if (pn.find("_")!=-1) { + //type + int idx=pn.get_slicec('/',1).get_slicec('_',0).to_int(); + bool valid; + r_ret=arr.get(idx,&valid); + if (valid) + r_ret=r_ret.get_type(); + return valid; + + } else { + int idx=pn.get_slicec('/',1).to_int(); + bool valid; + r_ret=arr.get(idx,&valid); + return valid; + } + } + + return false; +} + +void ArrayPropertyEdit::_get_property_list( List<PropertyInfo> *p_list) const{ + + Variant arr = get_array(); + int size = arr.call("size"); + + p_list->push_back( PropertyInfo(Variant::INT,"array/size",PROPERTY_HINT_RANGE,"0,100000,1") ); + int pages = size/ITEMS_PER_PAGE; + if (pages>0) + p_list->push_back( PropertyInfo(Variant::INT,"array/page",PROPERTY_HINT_RANGE,"0,"+itos(pages)+",1") ); + + int offset=page*ITEMS_PER_PAGE; + + int items=MIN(size-offset,ITEMS_PER_PAGE); + + + for(int i=0;i<items;i++) { + + Variant v=arr.get(i+offset); + if (arr.get_type()==Variant::ARRAY) { + p_list->push_back(PropertyInfo(Variant::INT,"indices/"+itos(i+offset)+"_type",PROPERTY_HINT_ENUM,vtypes)); + } + if (arr.get_type()!=Variant::ARRAY || v.get_type()!=Variant::NIL) { + PropertyInfo pi(v.get_type(),"indices/"+itos(i+offset)); + if (v.get_type()==Variant::OBJECT) { + pi.hint=PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string="Resource"; + } + p_list->push_back(pi); + } + } + +} + +void ArrayPropertyEdit::edit(Object* p_obj,const StringName& p_prop,Variant::Type p_deftype) { + + page=0; + property=p_prop; + obj=p_obj->get_instance_ID(); + default_type=p_deftype; + +} + +void ArrayPropertyEdit::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("_set_size"),&ArrayPropertyEdit::_set_size); + ObjectTypeDB::bind_method(_MD("_set_value"),&ArrayPropertyEdit::_set_value); + ObjectTypeDB::bind_method(_MD("_notif_change"),&ArrayPropertyEdit::_notif_change); + ObjectTypeDB::bind_method(_MD("_notif_changev"),&ArrayPropertyEdit::_notif_changev); +} + +ArrayPropertyEdit::ArrayPropertyEdit() +{ + page=0; + for(int i=0;i<Variant::VARIANT_MAX;i++) { + + if (i>0) + vtypes+=","; + vtypes+=Variant::get_type_name( Variant::Type(i) ); + } + default_type=Variant::NIL; + +} diff --git a/tools/editor/array_property_edit.h b/tools/editor/array_property_edit.h new file mode 100644 index 0000000000..acfb8e68ed --- /dev/null +++ b/tools/editor/array_property_edit.h @@ -0,0 +1,36 @@ +#ifndef ARRAY_PROPERTY_EDIT_H +#define ARRAY_PROPERTY_EDIT_H + +#include "scene/main/node.h" + +class ArrayPropertyEdit : public Reference { + + OBJ_TYPE(ArrayPropertyEdit,Reference); + + int page; + ObjectID obj; + StringName property; + String vtypes; + Variant get_array() const; + Variant::Type default_type; + + void _notif_change(); + void _notif_changev(const String& p_v); + void _set_size(int p_size); + void _set_value(int p_idx,const Variant& p_value); + +protected: + + static void _bind_methods(); + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List<PropertyInfo> *p_list) const; + +public: + + void edit(Object* p_obj, const StringName& p_prop, Variant::Type p_deftype); + + ArrayPropertyEdit(); +}; + +#endif // ARRAY_PROPERTY_EDIT_H diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp index ac68fcb07b..3131bd895c 100644 --- a/tools/editor/editor_data.cpp +++ b/tools/editor/editor_data.cpp @@ -523,7 +523,7 @@ Ref<Script> EditorData::get_scene_root_script(int p_idx) const { if (!edited_scene[p_idx].root) return Ref<Script>(); Ref<Script> s=edited_scene[p_idx].root->get_script(); - if (!s.is_valid()) { + if (!s.is_valid() && edited_scene[p_idx].root->get_child_count()) { Node *n = edited_scene[p_idx].root->get_child(0); while(!s.is_valid() && n && n->get_filename()==String()) { s=n->get_script(); diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 113f7c8306..9b6da314d6 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -93,7 +93,7 @@ #include "plugins/light_occluder_2d_editor_plugin.h" #include "plugins/color_ramp_editor_plugin.h" #include "plugins/collision_shape_2d_editor_plugin.h" - +#include "os/input.h" // end #include "tools/editor/io_plugins/editor_texture_import_plugin.h" #include "tools/editor/io_plugins/editor_scene_import_plugin.h" @@ -1765,6 +1765,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { int idx = editor_data.add_edited_scene(-1); _scene_tab_changed(idx); + editor_data.clear_editor_states(); //_cleanup_scene(); @@ -4163,6 +4164,14 @@ EditorNode::EditorNode() { EditorHelp::generate_doc(); //before any editor classes are crated + if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton()) { + //only if no touchscreen ui hint, set emulation + InputDefault *id = Input::get_singleton()->cast_to<InputDefault>(); + if (id) + id->set_emulate_touch(false); //just disable just in case + } + + singleton=this; last_checked_version=0; changing_scene=false; @@ -4835,6 +4844,7 @@ EditorNode::EditorNode() { property_editor->set_autoclear(true); property_editor->set_show_categories(true); property_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); + property_editor->set_use_doc_hints(true); property_editor->hide_top_label(); diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp index 05b12543d2..344e42c13b 100644 --- a/tools/editor/plugins/animation_player_editor_plugin.cpp +++ b/tools/editor/plugins/animation_player_editor_plugin.cpp @@ -549,6 +549,49 @@ void AnimationPlayerEditor::ensure_visibility() { _animation_edit(); } +Dictionary AnimationPlayerEditor::get_state() const { + + Dictionary d; + + d["visible"]=is_visible(); + if (is_visible() && player) { + d["player"]=EditorNode::get_singleton()->get_edited_scene()->get_path_to(player); + d["animation"]=player->get_current_animation(); + d["editing"]=edit_anim->is_pressed(); + } + + return d; + +} +void AnimationPlayerEditor::set_state(const Dictionary& p_state) { + + if (p_state.has("visible") && p_state["visible"]) { + + Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]); + if (n && n->cast_to<AnimationPlayer>()) { + player=n->cast_to<AnimationPlayer>(); + _update_player(); + show(); + set_process(true); + ensure_visibility(); + EditorNode::get_singleton()->animation_panel_make_visible(true); + + if (p_state.has("animation")) { + String anim = p_state["animation"]; + _select_anim_by_name(anim); + if (p_state.has("editing") && p_state["editing"]) { + + edit_anim->set_pressed(true); + _animation_edit(); + } + } + + } + } + +} + + void AnimationPlayerEditor::_animation_resource_edit() { if (animation->get_item_count()) { diff --git a/tools/editor/plugins/animation_player_editor_plugin.h b/tools/editor/plugins/animation_player_editor_plugin.h index 9f0413088d..5705742565 100644 --- a/tools/editor/plugins/animation_player_editor_plugin.h +++ b/tools/editor/plugins/animation_player_editor_plugin.h @@ -151,6 +151,10 @@ protected: static void _bind_methods(); public: + Dictionary get_state() const; + void set_state(const Dictionary& p_state); + + void ensure_visibility(); void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo=p_undo_redo; } @@ -167,6 +171,9 @@ class AnimationPlayerEditorPlugin : public EditorPlugin { public: + virtual Dictionary get_state() const { return anim_editor->get_state(); } + virtual void set_state(const Dictionary& p_state) { anim_editor->set_state(p_state); } + virtual String get_name() const { return "Anim"; } bool has_main_screen() const { return false; } virtual void edit(Object *p_node); diff --git a/tools/editor/plugins/mesh_editor_plugin.cpp b/tools/editor/plugins/mesh_editor_plugin.cpp index 2c64b2eb6b..13d4c8db5a 100644 --- a/tools/editor/plugins/mesh_editor_plugin.cpp +++ b/tools/editor/plugins/mesh_editor_plugin.cpp @@ -216,6 +216,8 @@ MeshInstanceEditor::MeshInstanceEditor() { SpatialEditor::get_singleton()->add_control_to_menu_panel(options); options->set_text("Mesh"); + options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MeshInstance","EditorIcons")); + options->get_popup()->add_item("Create Trimesh Static Body",MENU_OPTION_CREATE_STATIC_TRIMESH_BODY); options->get_popup()->add_item("Create Convex Static Body",MENU_OPTION_CREATE_STATIC_CONVEX_BODY); options->get_popup()->add_separator(); diff --git a/tools/editor/plugins/multimesh_editor_plugin.cpp b/tools/editor/plugins/multimesh_editor_plugin.cpp index 0df906117e..3c88b1d3a8 100644 --- a/tools/editor/plugins/multimesh_editor_plugin.cpp +++ b/tools/editor/plugins/multimesh_editor_plugin.cpp @@ -330,6 +330,8 @@ MultiMeshEditor::MultiMeshEditor() { options->set_area_as_parent_rect(); options->set_text("MultiMesh"); + options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MultiMeshInstance","EditorIcons")); + options->get_popup()->add_item("Populate Surface"); options->get_popup()->connect("item_pressed", this,"_menu_option"); diff --git a/tools/editor/plugins/particles_2d_editor_plugin.cpp b/tools/editor/plugins/particles_2d_editor_plugin.cpp index fdf534a3a8..dadfa8bfdc 100644 --- a/tools/editor/plugins/particles_2d_editor_plugin.cpp +++ b/tools/editor/plugins/particles_2d_editor_plugin.cpp @@ -146,6 +146,7 @@ void Particles2DEditorPlugin::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { menu->get_popup()->connect("item_pressed",this,"_menu_callback"); + menu->set_icon(menu->get_popup()->get_icon("Particles2D","EditorIcons")); file->connect("file_selected",this,"_file_selected"); } } diff --git a/tools/editor/plugins/particles_editor_plugin.cpp b/tools/editor/plugins/particles_editor_plugin.cpp index f6f01d82ca..5c84d9a86a 100644 --- a/tools/editor/plugins/particles_editor_plugin.cpp +++ b/tools/editor/plugins/particles_editor_plugin.cpp @@ -111,6 +111,7 @@ void ParticlesEditor::_populate() { void ParticlesEditor::_notification(int p_notification) { if (p_notification==NOTIFICATION_ENTER_TREE) { + options->set_icon(options->get_popup()->get_icon("Particles","EditorIcons")); } } diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp index 77663f39c0..8fc6a6931e 100644 --- a/tools/editor/plugins/spatial_editor_plugin.cpp +++ b/tools/editor/plugins/spatial_editor_plugin.cpp @@ -2168,7 +2168,18 @@ void SpatialEditorViewport::set_state(const Dictionary& p_state) { view_menu->get_popup()->set_item_checked( idx, listener ); } - + if (p_state.has("previewing")) { + Node *pv = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["previewing"]); + if (pv && pv->cast_to<Camera>()) { + previewing=pv->cast_to<Camera>(); + previewing->connect("exit_tree",this,"_preview_exited_scene"); + VS::get_singleton()->viewport_attach_camera( viewport->get_viewport(), previewing->get_camera() ); //replace + view_menu->hide(); + surface->update(); + preview_camera->set_pressed(true); + preview_camera->show(); + } + } } Dictionary SpatialEditorViewport::get_state() const { @@ -2181,6 +2192,10 @@ Dictionary SpatialEditorViewport::get_state() const { d["use_environment"]=camera->get_environment().is_valid(); d["use_orthogonal"]=camera->get_projection()==Camera::PROJECTION_ORTHOGONAL; d["listener"]=viewport->is_audio_listener(); + if (previewing) { + d["previewing"]=EditorNode::get_singleton()->get_edited_scene()->get_path_to(previewing); + } + return d; } diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index ae0975c896..0c0c687f83 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -40,6 +40,8 @@ #include "editor_import_export.h" #include "editor_node.h" #include "multi_node_edit.h" +#include "array_property_edit.h" +#include "editor_help.h" void CustomPropertyEditor::_notification(int p_what) { @@ -2270,6 +2272,23 @@ void PropertyEditor::update_tree() { sep->set_selectable(1,false); sep->set_custom_bg_color(0,get_color("prop_category","Editor")); sep->set_custom_bg_color(1,get_color("prop_category","Editor")); + + if (use_doc_hints) { + StringName type=p.name; + if (!class_descr_cache.has(type)) { + + String descr; + DocData *dd=EditorHelp::get_doc_data(); + Map<String,DocData::ClassDoc>::Element *E=dd->class_list.find(type); + if (E) { + descr=E->get().brief_description; + } + class_descr_cache[type]=descr.world_wrap(80); + + } + + sep->set_tooltip(0,"Class: "+p.name+":\n\n"+class_descr_cache[type]); + } //sep->set_custom_color(0,Color(1,1,1)); @@ -2323,6 +2342,42 @@ void PropertyEditor::update_tree() { item->set_tooltip(0, p.name); + if (use_doc_hints) { + StringName setter; + StringName type; + if (ObjectTypeDB::get_setter_and_type_for_property(obj->get_type_name(),p.name,type,setter)) { + + String descr; + bool found=false; + Map<StringName,Map<StringName,String> >::Element *E=descr_cache.find(type); + if (E) { + + Map<StringName,String>::Element *F=E->get().find(setter); + if (F) { + found=true; + descr=F->get(); + } + } + if (!found) { + + DocData *dd=EditorHelp::get_doc_data(); + Map<String,DocData::ClassDoc>::Element *E=dd->class_list.find(type); + if (E) { + for(int i=0;i<E->get().methods.size();i++) { + if (E->get().methods[i].name==setter.operator String()) { + descr=E->get().methods[i].description.strip_edges().world_wrap(80); + } + } + } + + descr_cache[type][setter]=descr; + } + + item->set_tooltip(0, "Property: "+p.name+"\n\n"+descr); + } + } + //EditorHelp::get_doc_data(); + Dictionary d; d["name"]=p.name; d["type"]=(int)p.type; @@ -2405,8 +2460,10 @@ void PropertyEditor::update_tree() { item->set_cell_mode( 1, TreeItem::CELL_MODE_RANGE ); + if (p.hint==PROPERTY_HINT_SPRITE_FRAME) { + item->set_range_config(1,0,99999,1); - if (p.hint==PROPERTY_HINT_RANGE || p.hint==PROPERTY_HINT_EXP_RANGE) { + } else if (p.hint==PROPERTY_HINT_RANGE || p.hint==PROPERTY_HINT_EXP_RANGE) { int c = p.hint_string.get_slice_count(","); float min=0,max=100,step=1; @@ -2507,11 +2564,32 @@ void PropertyEditor::update_tree() { } } break; + case Variant::ARRAY: { + + item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM ); + item->add_button(1,get_icon("EditResource","EditorIcons")); + + + Variant v = obj->get(p.name); + if (v.is_array()) + item->set_text(1,"Array["+itos(v.call("size"))+"]"); + else + item->set_text(1,"Array[]"); + item->set_icon( 0, get_icon("ArrayData","EditorIcons") ); + + + } break; + case Variant::INT_ARRAY: { item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM ); - item->set_editable( 1, !read_only ); - item->set_text(1,"[IntArray]"); + item->add_button(1,get_icon("EditResource","EditorIcons")); + + Variant v = obj->get(p.name); + if (v.is_array()) + item->set_text(1,"IntArray["+itos(v.call("size"))+"]"); + else + item->set_text(1,"IntArray[]"); item->set_icon( 0, get_icon("ArrayInt","EditorIcons") ); @@ -2519,26 +2597,86 @@ void PropertyEditor::update_tree() { case Variant::REAL_ARRAY: { item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM ); - item->set_editable( 1, !read_only ); - item->set_text(1,"[RealArray]"); + item->add_button(1,get_icon("EditResource","EditorIcons")); + + Variant v = obj->get(p.name); + if (v.is_array()) + item->set_text(1,"FloatArray["+itos(v.call("size"))+"]"); + else + item->set_text(1,"FloatArray[]"); item->set_icon( 0, get_icon("ArrayReal","EditorIcons") ); + } break; case Variant::STRING_ARRAY: { item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM ); - item->set_editable( 1, !read_only ); - item->set_text(1,"[StringArray]"); + item->add_button(1,get_icon("EditResource","EditorIcons")); + + Variant v = obj->get(p.name); + if (v.is_array()) + item->set_text(1,"String["+itos(v.call("size"))+"]"); + else + item->set_text(1,"String[]"); item->set_icon( 0, get_icon("ArrayString","EditorIcons") ); + } break; case Variant::RAW_ARRAY: { item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM ); - item->set_editable( 1, !read_only ); - item->set_text(1,"[Raw Data]"); + item->add_button(1,get_icon("EditResource","EditorIcons")); + + Variant v = obj->get(p.name); + if (v.is_array()) + item->set_text(1,"Byte["+itos(v.call("size"))+"]"); + else + item->set_text(1,"Byte[]"); item->set_icon( 0, get_icon("ArrayData","EditorIcons") ); + + } break; + case Variant::VECTOR2_ARRAY: { + + item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM ); + item->add_button(1,get_icon("EditResource","EditorIcons")); + + Variant v = obj->get(p.name); + if (v.is_array()) + item->set_text(1,"Vector2["+itos(v.call("size"))+"]"); + else + item->set_text(1,"Vector2[]"); + item->set_icon( 0, get_icon("Vector2","EditorIcons") ); + + + } break; + case Variant::VECTOR3_ARRAY: { + + item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM ); + item->add_button(1,get_icon("EditResource","EditorIcons")); + + Variant v = obj->get(p.name); + if (v.is_array()) + item->set_text(1,"Vector3["+itos(v.call("size"))+"]"); + else + item->set_text(1,"Vector3[]"); + item->set_icon( 0, get_icon("Vector","EditorIcons") ); + + + } break; + case Variant::COLOR_ARRAY: { + + item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM ); + item->add_button(1,get_icon("EditResource","EditorIcons")); + + Variant v = obj->get(p.name); + if (v.is_array()) + item->set_text(1,"Color["+itos(v.call("size"))+"]"); + else + item->set_text(1,"Color[]"); + item->set_icon( 0, get_icon("Color","EditorIcons") ); + + } break; case Variant::VECTOR2: { @@ -2734,7 +2872,7 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) { } } - if (!undo_redo || obj->cast_to<MultiNodeEdit>()) { //kind of hacky + if (!undo_redo || obj->cast_to<MultiNodeEdit>() || obj->cast_to<ArrayPropertyEdit>()) { //kind of hacky obj->set(p_name,p_value); _changed_callbacks(obj,p_name); @@ -3054,6 +3192,19 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) { emit_signal("resource_selected",r,n); } + } else if (t==Variant::ARRAY || t==Variant::INT_ARRAY || t==Variant::REAL_ARRAY || t==Variant::STRING_ARRAY || t==Variant::VECTOR2_ARRAY || t==Variant::VECTOR3_ARRAY || t==Variant::COLOR_ARRAY || t==Variant::RAW_ARRAY) { + + Variant v = obj->get(n); + + if (v.get_type()!=t) { + Variant::CallError ce; + v=Variant::construct(Variant::Type(t),NULL,0,ce); + } + + Ref<ArrayPropertyEdit> ape = memnew( ArrayPropertyEdit ); + ape->edit(obj,n,Variant::Type(t)); + + EditorNode::get_singleton()->push_item(ape.ptr()); } } } @@ -3239,7 +3390,8 @@ PropertyEditor::PropertyEditor() { read_only=false; show_categories=false; refresh_countdown=0; - + use_doc_hints=false; + } diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index f6e2dfcf50..426c19faf4 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -96,6 +96,7 @@ class CustomPropertyEditor : public Popup { SpinBox *spinbox; HSlider *slider; + Control *easing_draw; Object* owner; @@ -159,10 +160,14 @@ class PropertyEditor : public Control { bool read_only; bool show_categories; float refresh_countdown; + bool use_doc_hints; HashMap<String,String> pending; String selected_property; + Map<StringName,Map<StringName,String> > descr_cache; + Map<StringName,String > class_descr_cache; + CustomPropertyEditor *custom_editor; void _resource_edit_request(); @@ -219,8 +224,9 @@ public: void set_autoclear(bool p_enable); void set_show_categories(bool p_show); - - PropertyEditor(); + void set_use_doc_hints(bool p_enable) { use_doc_hints=p_enable; } + + PropertyEditor(); ~PropertyEditor(); }; |