diff options
Diffstat (limited to 'tools/editor')
120 files changed, 6302 insertions, 618 deletions
diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp index 63ab186a38..d431af6c8d 100644 --- a/tools/editor/animation_editor.cpp +++ b/tools/editor/animation_editor.cpp @@ -44,11 +44,207 @@ */ +class AnimationCurveEdit : public Control { + OBJ_TYPE( AnimationCurveEdit, Control ); +public: + enum Mode { + MODE_DISABLED, + MODE_SINGLE, + MODE_MULTIPLE + }; +private: + + Set<float> multiples; + float transition; + Mode mode; + + void _notification(int p_what) { + + if (p_what==NOTIFICATION_DRAW) { + + + RID ci = get_canvas_item(); + + Size2 s = get_size(); + Rect2 r(Point2(),s); + + //r=r.grow(3); + Ref<StyleBox> sb = get_stylebox("normal","LineEdit"); + sb->draw(ci,r); + r.size-=sb->get_minimum_size(); + r.pos+=sb->get_offset(); + //VisualServer::get_singleton()->canvas_item_add + + Ref<Font> f = get_font("font","Label"); + r=r.grow(-2); + Color color = get_color("font_color","Label"); + + int points = 48; + if (mode==MODE_MULTIPLE) { + + int max_draw = 16; + Color mcolor=color; + mcolor.a*=0.3; + + Set<float>::Element *E=multiples.front(); + for(int j=0;j<16;j++) { + + if (!E) + break; + + float prev=1.0; + float exp=E->get(); + bool flip=false;//hint_text=="attenuation"; + + + for(int i=1;i<=points;i++) { + + float ifl = i/float(points); + float iflp = (i-1)/float(points); + + float h = 1.0-Math::ease(ifl,exp); + + if (flip) { + ifl=1.0-ifl; + iflp=1.0-iflp; + } + + VisualServer::get_singleton()->canvas_item_add_line(ci,r.pos+Point2(iflp*r.size.width,prev*r.size.height),r.pos+Point2(ifl*r.size.width,h*r.size.height),mcolor); + prev=h; + } + + E=E->next(); + } + } + + float exp=transition; + if (mode!=MODE_DISABLED) { + + + float prev=1.0; + + bool flip=false;//hint_text=="attenuation"; + + + for(int i=1;i<=points;i++) { + + float ifl = i/float(points); + float iflp = (i-1)/float(points); + + float h = 1.0-Math::ease(ifl,exp); + + if (flip) { + ifl=1.0-ifl; + iflp=1.0-iflp; + } + + VisualServer::get_singleton()->canvas_item_add_line(ci,r.pos+Point2(iflp*r.size.width,prev*r.size.height),r.pos+Point2(ifl*r.size.width,h*r.size.height),color); + prev=h; + } + } + + String txt=String::num(exp,2); + if (mode==MODE_DISABLED) { + txt="Disabled"; + } else if (mode==MODE_MULTIPLE) { + txt+=" - All Selection"; + } + + f->draw(ci,Point2(10,10+f->get_ascent()),txt,color); + + } + } + + void _input_event(const InputEvent& p_ev) { + if (p_ev.type==InputEvent::MOUSE_MOTION && p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT) { + + if (mode==MODE_DISABLED) + return; + + float rel = p_ev.mouse_motion.relative_x; + if (rel==0) + return; + + bool flip=false; + + if (flip) + rel=-rel; + + float val = transition; + if (val==0) + return; + bool sg = val < 0; + val = Math::absf(val); + + val = Math::log(val)/Math::log(2); + //logspace + val+=rel*0.05; + // + + val = Math::pow(2,val); + if (sg) + val=-val; + + transition=val; + update(); + //emit_signal("variant_changed"); + emit_signal("transition_changed",transition); + } + } + +public: + + static void _bind_methods() { + + // ObjectTypeDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj); + ObjectTypeDB::bind_method("_input_event",&AnimationCurveEdit::_input_event); + ADD_SIGNAL(MethodInfo("transition_changed")); + } + + void set_mode(Mode p_mode) { + + mode=p_mode; + update(); + } + + void clear_multiples() { multiples.clear(); update();} + void set_multiple(float p_transition) { + + multiples.insert(p_transition); + } + + void set_transition(float p_transition) { + transition=p_transition; + update(); + } + + float get_transition() const { + return transition; + } + + void force_transition(float p_value) { + if (mode==MODE_DISABLED) + return; + transition=p_value; + emit_signal("transition_changed",p_value); + update(); + } + + AnimationCurveEdit() { + + transition=1.0; + set_default_cursor_shape(CURSOR_HSPLIT); + mode=MODE_DISABLED; + } + +}; + class AnimationKeyEdit : public Object { OBJ_TYPE(AnimationKeyEdit,Object); public: bool setting; + bool hidden; static void _bind_methods() { @@ -56,12 +252,12 @@ public: ObjectTypeDB::bind_method("_key_ofs_changed",&AnimationKeyEdit::_key_ofs_changed); } - PopupDialog *ke_dialog; + //PopupDialog *ke_dialog; void _update_obj(const Ref<Animation> &p_anim) { if (setting) return; - if (!ke_dialog->is_visible()) + if (hidden) return; if (!(animation==p_anim)) return; @@ -69,7 +265,7 @@ public: } void _key_ofs_changed(const Ref<Animation> &p_anim,float from, float to) { - if (!ke_dialog->is_visible()) + if (hidden) return; if (!(animation==p_anim)) return; @@ -408,8 +604,8 @@ public: } break; } - if (animation->track_get_type(track)!=Animation::TYPE_METHOD) - p_list->push_back( PropertyInfo( Variant::REAL, "easing", PROPERTY_HINT_EXP_EASING)); + //if (animation->track_get_type(track)!=Animation::TYPE_METHOD) + // p_list->push_back( PropertyInfo( Variant::REAL, "easing", PROPERTY_HINT_EXP_EASING)); } UndoRedo *undo_redo; @@ -425,7 +621,7 @@ public: _change_notify(); } - AnimationKeyEdit() { key_ofs=0; track=-1; setting=false; } + AnimationKeyEdit() { hidden=true; key_ofs=0; track=-1; setting=false; } }; @@ -610,6 +806,8 @@ void AnimationKeyEditor::_menu_track(int p_type) { selection=new_selection; track_editor->update(); + _edit_if_single_selection(); + } @@ -689,8 +887,31 @@ void AnimationKeyEditor::_menu_track(int p_type) { optimize_dialog->popup_centered(Size2(250,180)); } break; + case CURVE_SET_LINEAR: { + curve_edit->force_transition(1.0); + } break; + case CURVE_SET_IN: { + + curve_edit->force_transition(4.0); + + } break; + case CURVE_SET_OUT: { + + curve_edit->force_transition(0.25); + } break; + case CURVE_SET_INOUT: { + curve_edit->force_transition(-4); + + } break; + case CURVE_SET_OUTIN: { + + curve_edit->force_transition(-0.25); + } break; + case CURVE_SET_CONSTANT: { + curve_edit->force_transition(0); + } break; } @@ -774,6 +995,7 @@ void AnimationKeyEditor::_track_editor_draw() { h_scroll->hide(); menu_track->set_disabled(true); edit_button->set_disabled(true); + key_editor_tab->hide(); move_up_button->set_disabled(true); move_down_button->set_disabled(true); remove_button->set_disabled(true); @@ -785,6 +1007,8 @@ void AnimationKeyEditor::_track_editor_draw() { move_up_button->set_disabled(false); move_down_button->set_disabled(false); remove_button->set_disabled(false); + if (edit_button->is_pressed()) + key_editor_tab->show(); te_drawing=true; @@ -1000,8 +1224,13 @@ void AnimationKeyEditor::_track_editor_draw() { } } + Color sep_color=color; + color.a*=0.5; + for(int i=0;i<fit;i++) { + //this code sucks, i always forget how it works + int idx = v_scroll->get_val() + i; if (idx>=animation->get_track_count()) break; @@ -1090,6 +1319,7 @@ void AnimationKeyEditor::_track_editor_draw() { float key_hofs = -Math::floor(type_icon[tt]->get_height()/2); int kc=animation->track_get_key_count(idx); + bool first=true; for(int i=0;i<kc;i++) { @@ -1097,8 +1327,16 @@ void AnimationKeyEditor::_track_editor_draw() { float time = animation->track_get_key_time(idx,i); if (time<keys_from) continue; - if (time>keys_to) + if (time>keys_to) { + + if (first && i>0 && animation->track_get_key_value(idx,i)==animation->track_get_key_value(idx,i-1)) { + //draw whole line + te->draw_line(ofs+Vector2(name_limit,y+h/2),ofs+Point2(settings_limit,y+h/2),color); + } + break; + } + float x = key_hofs + name_limit + (time-keys_from)*zoom_scale; Ref<Texture> tex = type_icon[tt]; @@ -1116,7 +1354,22 @@ void AnimationKeyEditor::_track_editor_draw() { if (mouse_over.over==MouseOver::OVER_KEY && mouse_over.track==idx && mouse_over.over_key==i) tex=type_hover; + Variant value = animation->track_get_key_value(idx,i); + if (first && i>0 && value==animation->track_get_key_value(idx,i-1)) { + + te->draw_line(ofs+Vector2(name_limit,y+h/2),ofs+Point2(x,y+h/2),color); + } + + if (i<kc-1 && value==animation->track_get_key_value(idx,i+1)) { + float x_n = key_hofs + name_limit + (animation->track_get_key_time(idx,i+1)-keys_from)*zoom_scale; + + x_n = MIN( x_n, settings_limit); + te->draw_line(ofs+Point2(x_n,y+h/2),ofs+Point2(x,y+h/2),color); + + } + te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor()); + first=false; } } @@ -1226,7 +1479,9 @@ void AnimationKeyEditor::_clear_selection_for_anim(const Ref<Animation>& p_anim) if (!(animation==p_anim)) return; - selection.clear(); + //selection.clear(); + _clear_selection(); + } void AnimationKeyEditor::_select_at_anim(const Ref<Animation>& p_anim,int p_track,float p_pos){ @@ -1244,6 +1499,7 @@ void AnimationKeyEditor::_select_at_anim(const Ref<Animation>& p_anim,int p_trac ki.pos=p_pos; selection.insert(sk,ki); + } @@ -1283,6 +1539,83 @@ PropertyInfo AnimationKeyEditor::_find_hint_for_track(int p_idx) { } +void AnimationKeyEditor::_curve_transition_changed(float p_what) { + + if (selection.size()==0) + return; + if (selection.size()==1) + undo_redo->create_action("Edit Node Curve",true); + else + undo_redo->create_action("Edit Selection Curve",true); + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { + + int track = E->key().track; + int key = E->key().key; + float prev_val = animation->track_get_key_transition(track,key); + undo_redo->add_do_method(animation.ptr(),"track_set_key_transition",track,key,p_what); + undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",track,key,prev_val); + } + + undo_redo->commit_action(); + +} + +void AnimationKeyEditor::_toggle_edit_curves() { + + if (edit_button->is_pressed()) + key_editor_tab->show(); + else + key_editor_tab->hide(); +} + + +bool AnimationKeyEditor::_edit_if_single_selection() { + + if (selection.size()!=1) { + + if (selection.size()==0) { + curve_edit->set_mode(AnimationCurveEdit::MODE_DISABLED); + print_line("disable"); + } else { + + curve_edit->set_mode(AnimationCurveEdit::MODE_MULTIPLE); + curve_edit->set_transition(1.0); + curve_edit->clear_multiples(); + //add all + for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { + + curve_edit->set_multiple(animation->track_get_key_transition(E->key().track,E->key().key)); + } + print_line("multiple"); + + } + return false; + } + curve_edit->set_mode(AnimationCurveEdit::MODE_SINGLE); + print_line("regular"); + + int idx = selection.front()->key().track; + int key = selection.front()->key().key; + { + + key_edit->animation=animation; + key_edit->track=idx; + key_edit->key_ofs=animation->track_get_key_time(idx,key); + key_edit->hint=_find_hint_for_track(idx); + key_edit->notify_change(); + + curve_edit->set_transition(animation->track_get_key_transition(idx,key)); + + /*key_edit_dialog->set_size( Size2( 200,200) ); + key_edit_dialog->set_pos( track_editor->get_global_pos() + ofs + mpos +Point2(-100,20)); + key_edit_dialog->popup();*/ + + } + + return true; + +} void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { @@ -1364,9 +1697,12 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); } + undo_redo->add_do_method(this,"_clear_selection_for_anim",animation); + undo_redo->add_undo_method(this,"_clear_selection_for_anim",animation); undo_redo->commit_action(); - selection.clear(); + //selection.clear(); accept_event(); + _edit_if_single_selection(); } } else if (animation.is_valid() && animation->get_track_count()>0) { @@ -1552,20 +1888,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { } - if (mb.mod.command || edit_button->is_pressed()) { - - key_edit->animation=animation; - key_edit->track=idx; - key_edit->key_ofs=animation->track_get_key_time(idx,key); - key_edit->hint=_find_hint_for_track(idx); - key_edit->notify_change(); - - key_edit_dialog->set_size( Size2( 200,200) ); - key_edit_dialog->set_pos( track_editor->get_global_pos() + ofs + mpos +Point2(-100,20)); - key_edit_dialog->popup(); - - } SelectedKey sk; sk.track=idx; @@ -1577,7 +1900,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { if (!mb.mod.shift && !selection.has(sk)) - selection.clear(); + _clear_selection(); selection.insert(sk,ki); @@ -1588,7 +1911,10 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { selected_track=idx; track_editor->update(); - + if (_edit_if_single_selection() && mb.mod.command) { + edit_button->set_pressed(true); + key_editor_tab->show(); + } } else { //button column int ofsx = size.width - mpos.x; @@ -1824,7 +2150,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { if (from_track>to_track) { if (!click.shift) - selection.clear(); + _clear_selection(); + _edit_if_single_selection(); break; } @@ -1842,12 +2169,13 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { if (from_track > tracks_to || to_track < tracks_from) { if (!click.shift) - selection.clear(); + _clear_selection(); + _edit_if_single_selection(); break; } if (!click.shift) - selection.clear(); + _clear_selection(); int higher_track=0x7FFFFFFF; @@ -1880,6 +2208,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { } + _edit_if_single_selection(); + } break; case ClickOver::CLICK_MOVE_KEYS: { @@ -1891,8 +2221,9 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { if (!click.shift) { KeyInfo ki=selection[click.selk]; - selection.clear(); + _clear_selection(); selection[click.selk]=ki; + _edit_if_single_selection(); } break; @@ -2007,6 +2338,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { } undo_redo->commit_action(); + _edit_if_single_selection(); } break; default: {} @@ -2348,20 +2680,33 @@ void AnimationKeyEditor::_notification(int p_what) { optimize_dialog->connect("confirmed",this,"_animation_optimize"); menu_track->get_popup()->add_child(tpp); - menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions"); - menu_track->get_popup()->add_separator(); + //menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions"); + //menu_track->get_popup()->add_separator(); menu_track->get_popup()->add_item("Optimize Animation",TRACK_MENU_OPTIMIZE); + curve_linear->set_icon(get_icon("CurveLinear","EditorIcons")); + curve_in->set_icon(get_icon("CurveIn","EditorIcons")); + curve_out->set_icon(get_icon("CurveOut","EditorIcons")); + curve_inout->set_icon(get_icon("CurveInOut","EditorIcons")); + curve_outin->set_icon(get_icon("CurveOutIn","EditorIcons")); + curve_constant->set_icon(get_icon("CurveConstant","EditorIcons")); - + curve_linear->connect("pressed",this,"_menu_track",varray(CURVE_SET_LINEAR)); + curve_in->connect("pressed",this,"_menu_track",varray(CURVE_SET_IN)); + curve_out->connect("pressed",this,"_menu_track",varray(CURVE_SET_OUT)); + curve_inout->connect("pressed",this,"_menu_track",varray(CURVE_SET_INOUT)); + curve_outin->connect("pressed",this,"_menu_track",varray(CURVE_SET_OUTIN)); + curve_constant->connect("pressed",this,"_menu_track",varray(CURVE_SET_CONSTANT)); move_up_button->set_icon(get_icon("MoveUp","EditorIcons")); move_down_button->set_icon(get_icon("MoveDown","EditorIcons")); remove_button->set_icon(get_icon("Remove","EditorIcons")); edit_button->set_icon(get_icon("EditKey","EditorIcons")); + edit_button->connect("pressed",this,"_toggle_edit_curves"); loop->set_icon(get_icon("Loop","EditorIcons")); + curve_edit->connect("transition_changed",this,"_curve_transition_changed"); //edit_button->add_color_override("font_color",get_color("font_color","Tree")); //edit_button->add_color_override("font_color_hover",get_color("font_color","Tree")); @@ -2456,6 +2801,17 @@ void AnimationKeyEditor::_update_menu() { updating=false; } +void AnimationKeyEditor::_clear_selection() { + + selection.clear(); + key_edit->animation=Ref<Animation>(); + key_edit->track=0; + key_edit->key_ofs=0; + key_edit->hint=PropertyInfo(); + key_edit->notify_change(); + +} + void AnimationKeyEditor::set_animation(const Ref<Animation>& p_anim) { @@ -2466,11 +2822,12 @@ void AnimationKeyEditor::set_animation(const Ref<Animation>& p_anim) { animation->connect("changed",this,"_update_paths"); timeline_pos=0; - selection.clear(); + _clear_selection(); _update_paths(); _update_menu(); selected_track=-1; + _edit_if_single_selection(); } void AnimationKeyEditor::set_root(Node *p_root) { @@ -2591,6 +2948,7 @@ void AnimationKeyEditor::insert_transform_key(Spatial *p_node,const String& p_su id.value=p_xform; id.type=Animation::TYPE_TRANSFORM; id.query="node '"+p_node->get_name()+"'"; + id.advance=false; //dialog insert @@ -2643,6 +3001,7 @@ void AnimationKeyEditor::insert_node_value_key(Node* p_node, const String& p_pro id.value=p_value; id.type=Animation::TYPE_VALUE; id.query="property '"+p_property+"'"; + id.advance=false; //dialog insert _query_insert(id); @@ -2650,7 +3009,7 @@ void AnimationKeyEditor::insert_node_value_key(Node* p_node, const String& p_pro } -void AnimationKeyEditor::insert_value_key(const String& p_property,const Variant& p_value) { +void AnimationKeyEditor::insert_value_key(const String& p_property,const Variant& p_value,bool p_advance) { ERR_FAIL_COND(!root); //let's build a node path @@ -2696,6 +3055,7 @@ void AnimationKeyEditor::insert_value_key(const String& p_property,const Variant id.value=p_value; id.type=Animation::TYPE_VALUE; id.query="property '"+p_property+"'"; + id.advance=p_advance; //dialog insert _query_insert(id); @@ -2928,20 +3288,39 @@ void AnimationKeyEditor::_insert_delay() { undo_redo->create_action("Anim Insert"); int last_track = animation->get_track_count(); + bool advance=false; while(insert_data.size()) { + if (insert_data.front()->get().advance) + advance=true; last_track=_confirm_insert(insert_data.front()->get(),last_track); insert_data.pop_front(); } undo_redo->commit_action(); + + if (advance) { + float step = animation->get_step(); + if (step==0) + step=1; + + float pos=timeline_pos; + + pos=Math::stepify(pos+step,step); + if (pos>animation->get_length()) + pos=animation->get_length(); + timeline_pos=pos; + track_pos->update(); + emit_signal("timeline_changed",pos); + } insert_queue=false; } void AnimationKeyEditor::_step_changed(float p_len) { updating=true; - animation->set_step(p_len); + if (!animation.is_null()) + animation->set_step(p_len); updating=false; } @@ -3122,12 +3501,15 @@ void AnimationKeyEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_animation"),&AnimationKeyEditor::set_animation); ObjectTypeDB::bind_method(_MD("_animation_optimize"),&AnimationKeyEditor::_animation_optimize); + ObjectTypeDB::bind_method(_MD("_curve_transition_changed"),&AnimationKeyEditor::_curve_transition_changed); + ObjectTypeDB::bind_method(_MD("_toggle_edit_curves"),&AnimationKeyEditor::_toggle_edit_curves); ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) ); ADD_SIGNAL( MethodInfo("keying_changed" ) ); ADD_SIGNAL( MethodInfo("timeline_changed", PropertyInfo(Variant::REAL,"pos") ) ); ADD_SIGNAL( MethodInfo("animation_len_changed", PropertyInfo(Variant::REAL,"len") ) ); + ADD_SIGNAL( MethodInfo("key_edited", PropertyInfo(Variant::INT,"track"), PropertyInfo(Variant::INT,"key") ) ); } @@ -3219,12 +3601,6 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h hb->add_child( memnew( VSeparator ) ); - edit_button = memnew( ToolButton ); - edit_button->set_toggle_mode(true); - edit_button->set_focus_mode(FOCUS_NONE); - edit_button->set_disabled(true); - hb->add_child(edit_button); - edit_button->set_tooltip("Enable editing of individual keys by clicking them."); move_up_button = memnew( ToolButton ); hb->add_child(move_up_button); @@ -3247,6 +3623,15 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h remove_button->set_disabled(true); remove_button->set_tooltip("Remove selected track."); + hb->add_child(memnew( VSeparator )); + + edit_button = memnew( ToolButton ); + edit_button->set_toggle_mode(true); + edit_button->set_focus_mode(FOCUS_NONE); + edit_button->set_disabled(true); + + hb->add_child(edit_button); + edit_button->set_tooltip("Enable editing of individual keys by clicking them."); optimize_dialog = memnew( ConfirmationDialog ); add_child(optimize_dialog); @@ -3297,7 +3682,7 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h // menu->get_popup()->connect("item_pressed",this,"_menu_callback"); ec = memnew (Control); - ec->set_custom_minimum_size(Size2(0,50)); + ec->set_custom_minimum_size(Size2(0,150)); add_child(ec); ec->set_v_size_flags(SIZE_EXPAND_FILL); @@ -3313,6 +3698,7 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h track_editor->set_focus_mode(Control::FOCUS_ALL); track_editor->set_h_size_flags(SIZE_EXPAND_FILL); + track_pos = memnew( Control ); track_pos->set_area_as_parent_rect(); track_pos->set_ignore_mouse(true); @@ -3325,6 +3711,56 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h v_scroll->connect("value_changed",this,"_scroll_changed"); v_scroll->set_val(0); + key_editor_tab = memnew(TabContainer); + hb->add_child(key_editor_tab); + key_editor_tab->set_custom_minimum_size(Size2(200,0)); + + key_editor = memnew( PropertyEditor ); + key_editor->set_area_as_parent_rect(); + key_editor->hide_top_label(); + key_editor->set_name("Key"); + key_editor_tab->add_child(key_editor); + + key_edit = memnew( AnimationKeyEdit ); + key_edit->undo_redo=undo_redo; + //key_edit->ke_dialog=key_edit_dialog; + key_editor->edit(key_edit); + type_menu = memnew( PopupMenu ); + add_child(type_menu); + for(int i=0;i<Variant::VARIANT_MAX;i++) + type_menu->add_item(Variant::get_type_name(Variant::Type(i)),i); + type_menu->connect("item_pressed",this,"_create_value_item"); + + VBoxContainer *curve_vb = memnew( VBoxContainer ); + curve_vb->set_name("Transition"); + HBoxContainer *curve_hb = memnew( HBoxContainer ); + curve_vb->add_child(curve_hb); + + curve_linear = memnew( ToolButton ); + curve_linear->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_linear); + curve_in = memnew( ToolButton ); + curve_in->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_in); + curve_out = memnew( ToolButton ); + curve_out->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_out); + curve_inout = memnew( ToolButton ); + curve_inout->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_inout); + curve_outin = memnew( ToolButton ); + curve_outin->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_outin); + curve_constant = memnew( ToolButton ); + curve_constant->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_constant); + + + curve_edit = memnew( AnimationCurveEdit ); + curve_vb->add_child(curve_edit); + curve_edit->set_v_size_flags(SIZE_EXPAND_FILL); + key_editor_tab->add_child(curve_vb); + h_scroll = memnew( HScrollBar ); h_scroll->connect("value_changed",this,"_scroll_changed"); add_child(h_scroll); @@ -3340,7 +3776,7 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h add_child(track_menu); track_menu->connect("item_pressed",this,"_track_menu_selected"); - + key_editor_tab->hide(); last_idx =1; @@ -3359,24 +3795,6 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h timeline_pos=0; - key_edit_dialog = memnew( PopupDialog ); - key_editor = memnew( PropertyEditor ); - add_child(key_edit_dialog); - key_editor->set_area_as_parent_rect(); - key_editor->hide_top_label(); - for(int i=0;i<4;i++) - key_editor->set_margin(Margin(i),5); - key_edit_dialog->add_child(key_editor); - - key_edit = memnew( AnimationKeyEdit ); - key_edit->undo_redo=undo_redo; - key_edit->ke_dialog=key_edit_dialog; - key_editor->edit(key_edit); - type_menu = memnew( PopupMenu ); - add_child(type_menu); - for(int i=0;i<Variant::VARIANT_MAX;i++) - type_menu->add_item(Variant::get_type_name(Variant::Type(i)),i); - type_menu->connect("item_pressed",this,"_create_value_item"); keying=false; insert_frame=0; insert_query=false; diff --git a/tools/editor/animation_editor.h b/tools/editor/animation_editor.h index 885d46cf6c..35053fb6a3 100644 --- a/tools/editor/animation_editor.h +++ b/tools/editor/animation_editor.h @@ -37,6 +37,7 @@ #include "scene/gui/scroll_bar.h" #include "scene/gui/tool_button.h" #include "scene/gui/file_dialog.h" +#include "scene/gui/tab_container.h" #include "scene/resources/animation.h" #include "scene/animation/animation_cache.h" @@ -46,6 +47,7 @@ class AnimationKeyEdit; +class AnimationCurveEdit; class AnimationKeyEditor : public VBoxContainer { @@ -86,7 +88,13 @@ class AnimationKeyEditor : public VBoxContainer { TRACK_MENU_SET_ALL_TRANS_OUTIN, TRACK_MENU_NEXT_STEP, TRACK_MENU_PREV_STEP, - TRACK_MENU_OPTIMIZE + TRACK_MENU_OPTIMIZE, + CURVE_SET_LINEAR, + CURVE_SET_IN, + CURVE_SET_OUT, + CURVE_SET_INOUT, + CURVE_SET_OUTIN, + CURVE_SET_CONSTANT }; struct MouseOver { @@ -169,6 +177,14 @@ class AnimationKeyEditor : public VBoxContainer { ToolButton *move_down_button; ToolButton *remove_button; + ToolButton *curve_linear; + ToolButton *curve_in; + ToolButton *curve_out; + ToolButton *curve_inout; + ToolButton *curve_outin; + ToolButton *curve_constant; + + ConfirmationDialog *optimize_dialog; SpinBox *optimize_linear_error; SpinBox *optimize_angular_error; @@ -183,11 +199,11 @@ class AnimationKeyEditor : public VBoxContainer { Control *track_editor; Control *track_pos; + TabContainer *key_editor_tab; ConfirmationDialog *scale_dialog; SpinBox *scale; - PopupDialog *key_edit_dialog; PropertyEditor *key_editor; Ref<Animation> animation; @@ -203,6 +219,7 @@ class AnimationKeyEditor : public VBoxContainer { AnimationKeyEdit *key_edit; + AnimationCurveEdit *curve_edit; bool inserting; @@ -220,6 +237,7 @@ class AnimationKeyEditor : public VBoxContainer { int track_idx; Variant value; String query; + bool advance; };/* insert_data;*/ bool insert_query; @@ -254,7 +272,7 @@ class AnimationKeyEditor : public VBoxContainer { void _scale(); - + void _clear_selection(); //void _browse_path(); @@ -270,12 +288,15 @@ class AnimationKeyEditor : public VBoxContainer { void _clear_selection_for_anim(const Ref<Animation>& p_anim); void _select_at_anim(const Ref<Animation>& p_anim,int p_track,float p_pos); + void _curve_transition_changed(float p_what); PropertyInfo _find_hint_for_track(int p_idx); void _create_value_item(int p_type); void _pane_drag(const Point2& p_delta); + bool _edit_if_single_selection(); + void _toggle_edit_curves(); void _animation_len_update(); void _root_removed(); @@ -296,7 +317,7 @@ public: void set_anim_pos(float p_pos); void insert_node_value_key(Node* p_node, const String& p_property,const Variant& p_value,bool p_only_if_exists=false); - void insert_value_key(const String& p_property,const Variant& p_value); + void insert_value_key(const String& p_property, const Variant& p_value, bool p_advance); void insert_transform_key(Spatial *p_node,const String& p_sub,const Transform& p_xform); AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_history, EditorSelection *p_selection); diff --git a/tools/editor/create_dialog.cpp b/tools/editor/create_dialog.cpp index f5bef2580d..c0f35a4ac2 100644 --- a/tools/editor/create_dialog.cpp +++ b/tools/editor/create_dialog.cpp @@ -230,6 +230,11 @@ void CreateDialog::_notification(int p_what) { connect("confirmed",this,"_confirmed"); _update_search(); } + if (p_what==NOTIFICATION_EXIT_TREE) { + + disconnect("confirmed",this,"_confirmed"); + + } if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp index a635034aca..c4808d0cad 100644 --- a/tools/editor/editor_data.cpp +++ b/tools/editor/editor_data.cpp @@ -424,9 +424,182 @@ void EditorData::remove_custom_type(const String& p_type){ } +int EditorData::add_edited_scene(int p_at_pos) { + + if (p_at_pos<0) + p_at_pos=edited_scene.size(); + EditedScene es; + es.root=NULL; + es.history_current=-1; + es.version=0; + + if (p_at_pos==edited_scene.size()) + edited_scene.push_back(es); + else + edited_scene.insert(p_at_pos,es); + + if (current_edited_scene<0) + current_edited_scene=0; + return p_at_pos; +} + +void EditorData::move_edited_scene_index(int p_idx,int p_to_idx){ + + ERR_FAIL_INDEX(p_idx,edited_scene.size()); + ERR_FAIL_INDEX(p_to_idx,edited_scene.size()); + SWAP(edited_scene[p_idx],edited_scene[p_to_idx]); +} +void EditorData::remove_scene(int p_idx){ + ERR_FAIL_INDEX(p_idx,edited_scene.size()); + if (edited_scene[p_idx].root) + memdelete(edited_scene[p_idx].root); + + if (current_edited_scene>p_idx) + current_edited_scene--; + else if (current_edited_scene==p_idx && current_edited_scene>0) { + current_edited_scene--; + } + + edited_scene.remove(p_idx); + +} +int EditorData::get_edited_scene() const { + + return current_edited_scene; +} +void EditorData::set_edited_scene(int p_idx){ + + ERR_FAIL_INDEX(p_idx,edited_scene.size()); + current_edited_scene=p_idx; + //swap +} +Node* EditorData::get_edited_scene_root(){ + + ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),NULL); + + return edited_scene[current_edited_scene].root; +} +void EditorData::set_edited_scene_root(Node* p_root) { + + ERR_FAIL_INDEX(current_edited_scene,edited_scene.size()); + edited_scene[current_edited_scene].root=p_root; +} + +int EditorData::get_edited_scene_count() const { + + return edited_scene.size(); +} + +void EditorData::set_edited_scene_version(uint64_t version) { + ERR_FAIL_INDEX(current_edited_scene,edited_scene.size()); + edited_scene[current_edited_scene].version=version; + +} + +uint64_t EditorData::get_edited_scene_version() const{ + + ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),0); + return edited_scene[current_edited_scene].version; + +} +uint64_t EditorData::get_scene_version(int p_idx) const{ + ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),false); + return edited_scene[p_idx].version; +} + +String EditorData::get_scene_title(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),String()); + if (!edited_scene[p_idx].root) + return "[empty]"; + if (edited_scene[p_idx].root->get_filename()=="") + return "[unsaved]"; + return edited_scene[p_idx].root->get_filename().get_file(); +} + + +String EditorData::get_scene_path(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),String()); + + if (!edited_scene[p_idx].root) + return ""; + return edited_scene[p_idx].root->get_filename(); + +} + +void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history, const Dictionary& p_custom) { + + ERR_FAIL_INDEX(current_edited_scene,edited_scene.size()); + + EditedScene &es=edited_scene[current_edited_scene]; + es.selection = p_selection->get_selected_node_list(); + es.history_current=p_history->current; + es.history_stored=p_history->history; + es.editor_states=get_editor_states(); + es.custom_state=p_custom; + +} + +Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history) { + ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),Dictionary()); + + EditedScene &es=edited_scene[current_edited_scene]; + + p_history->current=es.history_current; + p_history->history=es.history_stored; + + + p_selection->clear(); + for(List<Node*>::Element *E=es.selection.front();E;E=E->next()) { + p_selection->add_node(E->get()); + } + set_editor_states(es.editor_states); + + return es.custom_state; +} + + +void EditorData::set_edited_scene_import_metadata(Ref<ResourceImportMetadata> p_mdata) { + + ERR_FAIL_INDEX(current_edited_scene,edited_scene.size()); + edited_scene[current_edited_scene].medatata=p_mdata; + +} + +Ref<ResourceImportMetadata> EditorData::get_edited_scene_import_metadata() const{ + + ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),Ref<ResourceImportMetadata>()); + return edited_scene[current_edited_scene].medatata; +} + +void EditorData::clear_edited_scenes() { + + for(int i=0;i<edited_scene.size();i++) { + if (edited_scene[i].root) { + memdelete( edited_scene[i].root ); + } + } + edited_scene.clear(); +} + + + +void EditorData::set_plugin_window_layout(Ref<ConfigFile> p_layout) { + for(int i=0;i<editor_plugins.size();i++) { + editor_plugins[i]->set_window_layout(p_layout); + } +} + +void EditorData::get_plugin_window_layout(Ref<ConfigFile> p_layout) { + for(int i=0;i<editor_plugins.size();i++) { + editor_plugins[i]->get_window_layout(p_layout); + } +} EditorData::EditorData() { + current_edited_scene=-1; + // load_imported_scenes_from_globals(); } diff --git a/tools/editor/editor_data.h b/tools/editor/editor_data.h index 42abb317d1..e3fdd52d01 100644 --- a/tools/editor/editor_data.h +++ b/tools/editor/editor_data.h @@ -55,6 +55,7 @@ class EditorHistory { Vector<Obj> path; int level; }; +friend class EditorData; Vector<History> history; int current; @@ -91,6 +92,8 @@ public: EditorHistory(); }; +class EditorSelection; + class EditorData { public: @@ -117,6 +120,21 @@ private: void _cleanup_history(); + struct EditedScene { + Node* root; + Dictionary editor_states; + Ref<ResourceImportMetadata> medatata; + List<Node*> selection; + Vector<EditorHistory::History> history_stored; + int history_current; + Dictionary custom_state; + uint64_t version; + + + }; + + Vector<EditedScene> edited_scene; + int current_edited_scene; public: @@ -146,6 +164,32 @@ public: void remove_custom_type(const String& p_type); const Map<String,Vector<CustomType> >& get_custom_types() const { return custom_types; } + + int add_edited_scene(int p_at_pos); + void move_edited_scene_index(int p_idx,int p_to_idx); + void remove_scene(int p_idx); + void set_edited_scene(int p_idx); + void set_edited_scene_root(Node* p_root); + void set_edited_scene_import_metadata(Ref<ResourceImportMetadata> p_mdata); + Ref<ResourceImportMetadata> get_edited_scene_import_metadata() const; + int get_edited_scene() const; + Node* get_edited_scene_root(); + int get_edited_scene_count() const; + String get_scene_title(int p_idx) const; + String get_scene_path(int p_idx) const; + void set_edited_scene_version(uint64_t version); + uint64_t get_edited_scene_version() const; + uint64_t get_scene_version(int p_idx) const; + void clear_edited_scenes(); + + + void set_plugin_window_layout(Ref<ConfigFile> p_layout); + void get_plugin_window_layout(Ref<ConfigFile> p_layout); + + void save_edited_scene_state(EditorSelection *p_selection,EditorHistory *p_history,const Dictionary& p_custom); + Dictionary restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history); + + EditorData(); }; diff --git a/tools/editor/editor_dir_dialog.cpp b/tools/editor/editor_dir_dialog.cpp index 5e6bad41aa..a8421acff8 100644 --- a/tools/editor/editor_dir_dialog.cpp +++ b/tools/editor/editor_dir_dialog.cpp @@ -43,6 +43,7 @@ void EditorDirDialog::_update_dir(TreeItem* p_item) { da->list_dir_begin(); String p=da->get_next(); + List<String> dirs; bool ishidden; bool show_hidden = EditorSettings::get_singleton()->get("file_dialog/show_hidden_files"); @@ -52,16 +53,22 @@ void EditorDirDialog::_update_dir(TreeItem* p_item) { if (show_hidden || !ishidden) { if (da->current_is_dir() && !p.begins_with(".")) { - TreeItem *ti = tree->create_item(p_item); - ti->set_text(0,p); - ti->set_icon(0,get_icon("Folder","EditorIcons")); - ti->set_collapsed(true); + dirs.push_back(p); } } - p=da->get_next(); } + dirs.sort(); + + for(List<String>::Element *E=dirs.front();E;E=E->next()) { + TreeItem *ti = tree->create_item(p_item); + ti->set_text(0,E->get()); + ti->set_icon(0,get_icon("Folder","EditorIcons")); + ti->set_collapsed(true); + + } + memdelete(da); updating=false; diff --git a/tools/editor/editor_file_dialog.cpp b/tools/editor/editor_file_dialog.cpp new file mode 100644 index 0000000000..b1bbd71f7b --- /dev/null +++ b/tools/editor/editor_file_dialog.cpp @@ -0,0 +1,1366 @@ +#include "editor_file_dialog.h" +#include "scene/gui/label.h" +#include "scene/gui/center_container.h" +#include "print_string.h" +#include "os/keyboard.h" +#include "editor_resource_preview.h" +#include "editor_settings.h" +#include "scene/gui/margin_container.h" +EditorFileDialog::GetIconFunc EditorFileDialog::get_icon_func=NULL; +EditorFileDialog::GetIconFunc EditorFileDialog::get_large_icon_func=NULL; + +EditorFileDialog::RegisterFunc EditorFileDialog::register_func=NULL; +EditorFileDialog::RegisterFunc EditorFileDialog::unregister_func=NULL; + + +VBoxContainer *EditorFileDialog::get_vbox() { + return vbox; + +} + +void EditorFileDialog::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + mode_thumbnails->set_icon(get_icon("FileThumbnail","EditorIcons")); + mode_list->set_icon(get_icon("FileList","EditorIcons")); + dir_prev->set_icon(get_icon("ArrowLeft","EditorIcons")); + dir_next->set_icon(get_icon("ArrowRight","EditorIcons")); + dir_up->set_icon(get_icon("ArrowUp","EditorIcons")); + favorite->set_icon(get_icon("Favorites","EditorIcons")); + + fav_up->set_icon(get_icon("MoveUp","EditorIcons")); + fav_down->set_icon(get_icon("MoveDown","EditorIcons")); + fav_rm->set_icon(get_icon("RemoveSmall","EditorIcons")); + + } + if (p_what==NOTIFICATION_PROCESS) { + + if (preview_waiting) { + preview_wheel_timeout-=get_process_delta_time(); + if (preview_wheel_timeout<=0) { + preview_wheel_index++; + if (preview_wheel_index>=8) + preview_wheel_index=0; + Ref<Texture> frame = get_icon("WaitPreview"+itos(preview_wheel_index+1),"EditorIcons"); + preview->set_texture(frame); + preview_wheel_timeout=0.1; + } + } + } + + if (p_what==NOTIFICATION_DRAW) { + + //RID ci = get_canvas_item(); + //get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size())); + } +} + +void EditorFileDialog::set_enable_multiple_selection(bool p_enable) { + + item_list->set_select_mode(p_enable?ItemList::SELECT_MULTI:ItemList::SELECT_SINGLE); + +}; + +Vector<String> EditorFileDialog::get_selected_files() const { + + Vector<String> list; + for(int i=0;i<item_list->get_item_count();i++) { + if (item_list->is_selected(i)) + list.push_back(item_list->get_item_text(i)); + } + return list; + +}; + +void EditorFileDialog::update_dir() { + + dir->set_text(dir_access->get_current_dir()); +} + +void EditorFileDialog::_dir_entered(String p_dir) { + + + dir_access->change_dir(p_dir); + file->set_text(""); + invalidate(); + update_dir(); + _push_history(); + + +} + +void EditorFileDialog::_file_entered(const String& p_file) { + + _action_pressed(); +} + +void EditorFileDialog::_save_confirm_pressed() { + String f=dir_access->get_current_dir().plus_file(file->get_text()); + _save_to_recent(); + emit_signal("file_selected",f); + hide(); +} + +void EditorFileDialog::_post_popup() { + + ConfirmationDialog::_post_popup(); + if (invalidated) { + update_file_list(); + invalidated=false; + } + if (mode==MODE_SAVE_FILE) + file->grab_focus(); + else + item_list->grab_focus(); + + if (is_visible() && get_current_file()!="") + _request_single_thumbnail(get_current_dir().plus_file(get_current_file())); + + if (is_visible()) { + Ref<Texture> folder = get_icon("folder","FileDialog"); + recent->clear(); + + + bool res = access==ACCESS_RESOURCES; + Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs(); + for(int i=0;i<recentd.size();i++) { + bool cres = recentd[i].begins_with("res://"); + if (cres!=res) + continue; + String name = recentd[i]; + if (res && name=="res://") { + name="/"; + } else { + name=name.get_file()+"/"; + } + + //print_line("file: "+name); + recent->add_item(name,folder); + recent->set_item_metadata( recent->get_item_count()-1,recentd[i]); + } + + local_history.clear(); + local_history_pos=-1; + _push_history(); + + _update_favorites(); + } + +} + +void EditorFileDialog::_thumbnail_result(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata) { + + if (display_mode==DISPLAY_LIST || p_preview.is_null()) + return; + + for(int i=0;i<item_list->get_item_count();i++) { + Dictionary d = item_list->get_item_metadata(i); + String pname = d["path"]; + if (pname==p_path) { + item_list->set_item_icon(i,p_preview); + item_list->set_item_tag_icon(i,Ref<Texture>()); + } + } +} + +void EditorFileDialog::_thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata) { + + set_process(false); + preview_waiting=false; + + if (p_preview.is_valid() && get_current_path()==p_path) { + + + preview->set_texture(p_preview); + if (display_mode==DISPLAY_THUMBNAILS) { + preview_vb->hide(); + } else { + preview_vb->show(); + } + + } else { + preview_vb->hide(); + preview->set_texture(Ref<Texture>()); + + } + +} + +void EditorFileDialog::_request_single_thumbnail(const String& p_path) { + + EditorResourcePreview::get_singleton()->queue_resource_preview(p_path,this,"_thumbnail_done",p_path); + print_line("want file "+p_path); + set_process(true); + preview_waiting=true; + preview_wheel_timeout=0; + +} + +void EditorFileDialog::_action_pressed() { + + if (mode==MODE_OPEN_FILES) { + + + String fbase=dir_access->get_current_dir(); + + DVector<String> files; + for(int i=0;i<item_list->get_item_count();i++) { + if (item_list->is_selected(i)) + files.push_back( fbase.plus_file(item_list->get_item_text(i) )); + } + + if (files.size()) { + _save_to_recent(); + emit_signal("files_selected",files); + hide(); + } + + return; + } + + String f=dir_access->get_current_dir().plus_file(file->get_text()); + + if (mode==MODE_OPEN_FILE && dir_access->file_exists(f)) { + _save_to_recent(); + emit_signal("file_selected",f); + hide(); + } + + if (mode==MODE_OPEN_DIR) { + + + String path=dir_access->get_current_dir(); + /*if (tree->get_selected()) { + Dictionary d = tree->get_selected()->get_metadata(0); + if (d["dir"]) { + path=path+"/"+String(d["name"]); + } + }*/ + path=path.replace("\\","/"); + _save_to_recent(); + emit_signal("dir_selected",path); + hide(); + } + + if (mode==MODE_SAVE_FILE) { + + bool valid=false; + + if (filter->get_selected()==filter->get_item_count()-1) { + valid=true; //match none + } else if (filters.size()>1 && filter->get_selected()==0) { + // match all filters + for (int i=0;i<filters.size();i++) { + + String flt=filters[i].get_slice(";",0); + for (int j=0;j<flt.get_slice_count(",");j++) { + + String str = flt.get_slice(",",j).strip_edges(); + if (f.match(str)) { + valid=true; + break; + } + } + if (valid) + break; + } + } else { + int idx=filter->get_selected(); + if (filters.size()>1) + idx--; + if (idx>=0 && idx<filters.size()) { + + String flt=filters[idx].get_slice(";",0); + int filterSliceCount=flt.get_slice_count(","); + for (int j=0;j<filterSliceCount;j++) { + + String str = (flt.get_slice(",",j).strip_edges()); + if (f.match(str)) { + valid=true; + break; + } + } + + if (!valid && filterSliceCount>0) { + String str = (flt.get_slice(",",0).strip_edges()); + f+=str.substr(1, str.length()-1); + _request_single_thumbnail(get_current_dir().plus_file(f.get_file())); + file->set_text(f.get_file()); + valid=true; + } + } else { + valid=true; + } + } + + + if (!valid) { + + exterr->popup_centered_minsize(Size2(250,80)); + return; + + } + + if (dir_access->file_exists(f)) { + confirm_save->set_text("File Exists, Overwrite?"); + confirm_save->popup_centered(Size2(200,80)); + } else { + + _save_to_recent(); + emit_signal("file_selected",f); + hide(); + } + } +} + +void EditorFileDialog::_cancel_pressed() { + + file->set_text(""); + invalidate(); + hide(); +} + +void EditorFileDialog::_item_selected(int p_item) { + + int current = p_item; + if (current<0 || current>=item_list->get_item_count()) + return; + + Dictionary d=item_list->get_item_metadata(current); + + if (!d["dir"]) { + + file->set_text(d["name"]); + _request_single_thumbnail(get_current_dir().plus_file(get_current_file())); + } +} + +void EditorFileDialog::_push_history() { + + local_history.resize(local_history_pos+1); + String new_path = dir_access->get_current_dir(); + if (local_history.size()==0 || new_path!=local_history[local_history_pos]) { + local_history.push_back(new_path); + local_history_pos++; + dir_prev->set_disabled(local_history_pos==0); + dir_next->set_disabled(true); + } + +} +void EditorFileDialog::_item_dc_selected(int p_item) { + + + int current = p_item; + if (current<0 || current>=item_list->get_item_count()) + return; + + Dictionary d=item_list->get_item_metadata(current); + + if (d["dir"]) { + + print_line("change dir: "+String(d["name"])); + dir_access->change_dir(d["name"]); + if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR) + file->set_text(""); + call_deferred("_update_file_list"); + call_deferred("_update_dir"); + + _push_history(); + + + } else { + + _action_pressed(); + } +} + + + +void EditorFileDialog::update_file_list() { + + + int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); + Ref<Texture> folder_thumbnail; + Ref<Texture> file_thumbnail; + + item_list->clear(); + + if (display_mode==DISPLAY_THUMBNAILS) { + + item_list->set_max_columns(0); + item_list->set_icon_mode(ItemList::ICON_MODE_TOP); + item_list->set_fixed_column_width(thumbnail_size*3/2); + item_list->set_max_text_lines(2); + item_list->set_min_icon_size(Size2(thumbnail_size,thumbnail_size)); + + if (!has_icon("ResizedFolder","EditorIcons")) { + Ref<ImageTexture> folder = get_icon("FolderBig","EditorIcons"); + Image img = folder->get_data(); + img.resize(thumbnail_size,thumbnail_size); + Ref<ImageTexture> resized_folder = Ref<ImageTexture>( memnew( ImageTexture)); + resized_folder->create_from_image(img,0); + Theme::get_default()->set_icon("ResizedFolder","EditorIcons",resized_folder); + } + + folder_thumbnail = get_icon("ResizedFolder","EditorIcons"); + + if (!has_icon("ResizedFile","EditorIcons")) { + Ref<ImageTexture> file = get_icon("FileBig","EditorIcons"); + Image img = file->get_data(); + img.resize(thumbnail_size,thumbnail_size); + Ref<ImageTexture> resized_file = Ref<ImageTexture>( memnew( ImageTexture)); + resized_file->create_from_image(img,0); + Theme::get_default()->set_icon("ResizedFile","EditorIcons",resized_file); + } + + file_thumbnail = get_icon("ResizedFile","EditorIcons"); + + preview_vb->hide(); + + } else { + + item_list->set_icon_mode(ItemList::ICON_MODE_LEFT); + item_list->set_max_columns(1); + item_list->set_max_text_lines(1); + item_list->set_fixed_column_width(0); + item_list->set_min_icon_size(Size2()); + if (preview->get_texture().is_valid()) + preview_vb->show(); + + } + + + dir_access->list_dir_begin(); + + + Ref<Texture> folder = get_icon("folder","FileDialog"); + List<String> files; + List<String> dirs; + + bool isdir; + bool ishidden; + bool show_hidden = show_hidden_files; + String item; + + while ((item=dir_access->get_next(&isdir))!="") { + + ishidden = dir_access->current_is_hidden(); + + if (show_hidden || !ishidden) { + if (!isdir) + files.push_back(item); + else + dirs.push_back(item); + } + } + + dirs.sort_custom<NoCaseComparator>(); + files.sort_custom<NoCaseComparator>(); + + while(!dirs.empty()) { + + if (dirs.front()->get()!=".") { + item_list->add_item(dirs.front()->get()+"/"); + if (display_mode==DISPLAY_THUMBNAILS) { + + item_list->set_item_icon(item_list->get_item_count()-1,folder_thumbnail); + } else { + + item_list->set_item_icon(item_list->get_item_count()-1,folder); + } + + Dictionary d; + d["name"]=dirs.front()->get(); + d["path"]=String(); + d["dir"]=true; + item_list->set_item_metadata( item_list->get_item_count() -1, d); + } + dirs.pop_front(); + + } + + dirs.clear(); + + List<String> patterns; + // build filter + if (filter->get_selected()==filter->get_item_count()-1) { + + // match all + } else if (filters.size()>1 && filter->get_selected()==0) { + // match all filters + for (int i=0;i<filters.size();i++) { + + String f=filters[i].get_slice(";",0); + for (int j=0;j<f.get_slice_count(",");j++) { + + patterns.push_back(f.get_slice(",",j).strip_edges()); + } + } + } else { + int idx=filter->get_selected(); + if (filters.size()>1) + idx--; + + if (idx>=0 && idx<filters.size()) { + + String f=filters[idx].get_slice(";",0); + for (int j=0;j<f.get_slice_count(",");j++) { + + patterns.push_back(f.get_slice(",",j).strip_edges()); + } + } + } + + + String base_dir = dir_access->get_current_dir(); + + + while(!files.empty()) { + + bool match=patterns.empty(); + + for(List<String>::Element *E=patterns.front();E;E=E->next()) { + + if (files.front()->get().matchn(E->get())) { + + match=true; + break; + } + } + + if (match) { + //TreeItem *ti=tree->create_item(root); + //ti->set_text(0,files.front()->get()); + item_list->add_item(files.front()->get()); + + if (get_icon_func) { + + Ref<Texture> icon = get_icon_func(base_dir.plus_file(files.front()->get())); + //ti->set_icon(0,icon); + if (display_mode==DISPLAY_THUMBNAILS) { + + item_list->set_item_icon(item_list->get_item_count()-1,file_thumbnail); + item_list->set_item_tag_icon(item_list->get_item_count()-1,icon); + } else { + item_list->set_item_icon(item_list->get_item_count()-1,icon); + } + } + + if (mode==MODE_OPEN_DIR) { + //disabled mode? + //ti->set_custom_color(0,get_color("files_disabled")); + //ti->set_selectable(0,false); + } + Dictionary d; + d["name"]=files.front()->get(); + d["dir"]=false; + String fullpath = base_dir.plus_file(files.front()->get()); + + if (display_mode==DISPLAY_THUMBNAILS) { + EditorResourcePreview::get_singleton()->queue_resource_preview(fullpath,this,"_thumbnail_result",fullpath); + } + d["path"]=base_dir.plus_file(files.front()->get()); + //ti->set_metadata(0,d); + item_list->set_item_metadata(item_list->get_item_count()-1,d); + + if (file->get_text()==files.front()->get()) + item_list->set_current(item_list->get_item_count()-1); + } + + files.pop_front(); + } + + if (favorites->get_current()>=0) { + favorites->unselect(favorites->get_current()); + } + + favorite->set_pressed(false); + fav_up->set_disabled(true); + fav_down->set_disabled(true); + for(int i=0;i<favorites->get_item_count();i++) { + if (favorites->get_item_metadata(i)==base_dir) { + favorites->select(i); + favorite->set_pressed(true); + if (i>0) { + fav_up->set_disabled(false); + } + if (i<favorites->get_item_count()-1) { + fav_down->set_disabled(false); + } + break; + } + + } + // ?? + //if (tree->get_root() && tree->get_root()->get_children()) + // tree->get_root()->get_children()->select(0); + + files.clear(); + +} + +void EditorFileDialog::_filter_selected(int) { + + update_file_list(); +} + +void EditorFileDialog::update_filters() { + + filter->clear(); + + if (filters.size()>1) { + String all_filters; + + const int max_filters=5; + + for(int i=0;i<MIN( max_filters, filters.size()) ;i++) { + String flt=filters[i].get_slice(";",0); + if (i>0) + all_filters+=","; + all_filters+=flt; + } + + if (max_filters<filters.size()) + all_filters+=", ..."; + + filter->add_item("All Recognized ( "+all_filters+" )"); + } + for(int i=0;i<filters.size();i++) { + + String flt=filters[i].get_slice(";",0).strip_edges(); + String desc=filters[i].get_slice(";",1).strip_edges(); + if (desc.length()) + filter->add_item(desc+" ( "+flt+" )"); + else + filter->add_item("( "+flt+" )"); + } + + filter->add_item("All Files (*)"); + +} + +void EditorFileDialog::clear_filters() { + + filters.clear(); + update_filters(); + invalidate(); +} +void EditorFileDialog::add_filter(const String& p_filter) { + + filters.push_back(p_filter); + update_filters(); + invalidate(); + +} + +String EditorFileDialog::get_current_dir() const { + + return dir->get_text(); +} +String EditorFileDialog::get_current_file() const { + + return file->get_text(); +} +String EditorFileDialog::get_current_path() const { + + return dir->get_text().plus_file(file->get_text()); +} +void EditorFileDialog::set_current_dir(const String& p_dir) { + + dir_access->change_dir(p_dir); + update_dir(); + invalidate(); + //_push_history(); + + +} +void EditorFileDialog::set_current_file(const String& p_file) { + + file->set_text(p_file); + update_dir(); + invalidate(); + int lp = p_file.find_last("."); + if (lp!=-1) { + file->select(0,lp); + file->grab_focus(); + } + + if (is_visible()) + _request_single_thumbnail(get_current_dir().plus_file(get_current_file())); + + +} +void EditorFileDialog::set_current_path(const String& p_path) { + + if (!p_path.size()) + return; + int pos=MAX( p_path.find_last("/"), p_path.find_last("\\") ); + if (pos==-1) { + + set_current_file(p_path); + } else { + + String dir=p_path.substr(0,pos); + String file=p_path.substr(pos+1,p_path.length()); + set_current_dir(dir); + set_current_file(file); + } +} + + +void EditorFileDialog::set_mode(Mode p_mode) { + + mode=p_mode; + switch(mode) { + + case MODE_OPEN_FILE: get_ok()->set_text("Open"); set_title("Open a File"); makedir->hide(); break; + case MODE_OPEN_FILES: get_ok()->set_text("Open"); set_title("Open File(s)"); makedir->hide(); break; + case MODE_SAVE_FILE: get_ok()->set_text("Save"); set_title("Save a File"); makedir->show(); break; + case MODE_OPEN_DIR: get_ok()->set_text("Open"); set_title("Open a Directory"); makedir->show(); break; + } + + if (mode==MODE_OPEN_FILES) { + item_list->set_select_mode(ItemList::SELECT_MULTI); + } else { + item_list->set_select_mode(ItemList::SELECT_SINGLE); + } +} + +EditorFileDialog::Mode EditorFileDialog::get_mode() const { + + return mode; +} + +void EditorFileDialog::set_access(Access p_access) { + + ERR_FAIL_INDEX(p_access,3); + if (access==p_access) + return; + memdelete( dir_access ); + switch(p_access) { + case ACCESS_FILESYSTEM: { + + dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + } break; + case ACCESS_RESOURCES: { + + dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES); + } break; + case ACCESS_USERDATA: { + + dir_access = DirAccess::create(DirAccess::ACCESS_USERDATA); + } break; + } + access=p_access; + _update_drives(); + invalidate(); + update_filters(); + update_dir(); +} + +void EditorFileDialog::invalidate() { + + if (is_visible()) { + update_file_list(); + invalidated=false; + } else { + invalidated=true; + } + +} + +EditorFileDialog::Access EditorFileDialog::get_access() const{ + + return access; +} + +void EditorFileDialog::_make_dir_confirm() { + + + Error err = dir_access->make_dir( makedirname->get_text() ); + if (err==OK) { + dir_access->change_dir(makedirname->get_text()); + invalidate(); + update_filters(); + update_dir(); + _push_history(); + + } else { + mkdirerr->popup_centered_minsize(Size2(250,50)); + } +} + + +void EditorFileDialog::_make_dir() { + + makedialog->popup_centered_minsize(Size2(250,80)); + makedirname->grab_focus(); + +} + +void EditorFileDialog::_select_drive(int p_idx) { + + String d = drives->get_item_text(p_idx); + dir_access->change_dir(d); + file->set_text(""); + invalidate(); + update_dir(); + _push_history(); + + +} + +void EditorFileDialog::_update_drives() { + + + int dc = dir_access->get_drive_count(); + if (dc==0 || access!=ACCESS_FILESYSTEM) { + drives->hide(); + } else { + drives->clear(); + drives->show(); + + for(int i=0;i<dir_access->get_drive_count();i++) { + String d = dir_access->get_drive(i); + drives->add_item(dir_access->get_drive(i)); + } + + drives->select(dir_access->get_current_drive()); + + } +} + + +void EditorFileDialog::_favorite_selected(int p_idx) { + + Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs(); + ERR_FAIL_INDEX(p_idx,favorited.size()); + + dir_access->change_dir(favorited[p_idx]); + file->set_text(""); + invalidate(); + update_dir(); + _push_history(); +} + +void EditorFileDialog::_favorite_move_up(){ + + int current = favorites->get_current(); + + if (current>0 && current<favorites->get_item_count()) { + Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs(); + + int a_idx=favorited.find(String(favorites->get_item_metadata(current-1))); + int b_idx=favorited.find(String(favorites->get_item_metadata(current))); + + if (a_idx==-1 || b_idx==-1) + return; + SWAP(favorited[a_idx],favorited[b_idx]); + + EditorSettings::get_singleton()->set_favorite_dirs(favorited); + + _update_favorites(); + update_file_list(); + + } +} +void EditorFileDialog::_favorite_move_down(){ + + int current = favorites->get_current(); + + if (current>=0 && current<favorites->get_item_count()-1) { + Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs(); + + int a_idx=favorited.find(String(favorites->get_item_metadata(current+1))); + int b_idx=favorited.find(String(favorites->get_item_metadata(current))); + + if (a_idx==-1 || b_idx==-1) + return; + SWAP(favorited[a_idx],favorited[b_idx]); + + EditorSettings::get_singleton()->set_favorite_dirs(favorited); + + _update_favorites(); + update_file_list(); + + } +} + + +void EditorFileDialog::_update_favorites() { + + bool res = access==ACCESS_RESOURCES; + + String current = get_current_dir(); + Ref<Texture> star = get_icon("Favorites","EditorIcons"); + favorites->clear(); + + favorite->set_pressed(false); + + + Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs(); + for(int i=0;i<favorited.size();i++) { + bool cres = favorited[i].begins_with("res://"); + if (cres!=res) + continue; + String name = favorited[i]; + + bool setthis = name==current; + + if (res && name=="res://") { + name="/"; + } else { + name=name.get_file()+"/"; + } + + + //print_line("file: "+name); + favorites->add_item(name,star); + favorites->set_item_metadata( favorites->get_item_count()-1,favorited[i]); + + if (setthis) { + favorite->set_pressed(true); + favorites->set_current(favorites->get_item_count()-1); + } + } + + +} + +void EditorFileDialog::_favorite_toggled(bool p_toggle) { + bool res = access==ACCESS_RESOURCES; + + String cd = get_current_dir(); + + Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs(); + + bool found = false; + for(int i=0;i<favorited.size();i++) { + bool cres = favorited[i].begins_with("res://"); + if (cres!=res) + continue; + + if (favorited[i]==cd) { + found=true; + break; + } + } + + if (found) { + favorited.erase(cd); + favorite->set_pressed(false); + } else { + favorited.push_back(cd); + favorite->set_pressed(true); + } + + EditorSettings::get_singleton()->set_favorite_dirs(favorited); + + _update_favorites(); + +} + +void EditorFileDialog::_recent_selected(int p_idx) { + + Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs(); + ERR_FAIL_INDEX(p_idx,recentd.size()); + + dir_access->change_dir(recent->get_item_metadata(p_idx)); + update_file_list(); + update_dir(); + _push_history(); +} + +void EditorFileDialog::_go_up() { + + dir_access->change_dir(".."); + update_file_list(); + update_dir(); + _push_history(); + +} + +void EditorFileDialog::_go_back(){ + + if (local_history_pos<=0) { + return; + } + + local_history_pos--; + dir_access->change_dir(local_history[local_history_pos]); + update_file_list(); + update_dir(); + + dir_prev->set_disabled(local_history_pos==0); + dir_next->set_disabled(local_history_pos==local_history.size()-1); +} +void EditorFileDialog::_go_forward(){ + + if (local_history_pos==local_history.size()-1) { + return; + } + + local_history_pos++; + dir_access->change_dir(local_history[local_history_pos]); + update_file_list(); + update_dir(); + + dir_prev->set_disabled(local_history_pos==0); + dir_next->set_disabled(local_history_pos==local_history.size()-1); + +} + +bool EditorFileDialog::default_show_hidden_files=true; + +void EditorFileDialog::set_display_mode(DisplayMode p_mode) { + + if (display_mode==p_mode) + return; + if (p_mode==DISPLAY_THUMBNAILS) { + mode_list->set_pressed(false); + mode_thumbnails->set_pressed(true); + } else { + mode_thumbnails->set_pressed(false); + mode_list->set_pressed(true); + } + display_mode=p_mode; + invalidate();; +} + +EditorFileDialog::DisplayMode EditorFileDialog::get_display_mode() const{ + + return display_mode; +} + + + +void EditorFileDialog::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("_item_selected"),&EditorFileDialog::_item_selected); + ObjectTypeDB::bind_method(_MD("_item_db_selected"),&EditorFileDialog::_item_dc_selected); + ObjectTypeDB::bind_method(_MD("_dir_entered"),&EditorFileDialog::_dir_entered); + ObjectTypeDB::bind_method(_MD("_file_entered"),&EditorFileDialog::_file_entered); + ObjectTypeDB::bind_method(_MD("_action_pressed"),&EditorFileDialog::_action_pressed); + ObjectTypeDB::bind_method(_MD("_cancel_pressed"),&EditorFileDialog::_cancel_pressed); + ObjectTypeDB::bind_method(_MD("_filter_selected"),&EditorFileDialog::_filter_selected); + ObjectTypeDB::bind_method(_MD("_save_confirm_pressed"),&EditorFileDialog::_save_confirm_pressed); + + ObjectTypeDB::bind_method(_MD("clear_filters"),&EditorFileDialog::clear_filters); + ObjectTypeDB::bind_method(_MD("add_filter","filter"),&EditorFileDialog::add_filter); + ObjectTypeDB::bind_method(_MD("get_current_dir"),&EditorFileDialog::get_current_dir); + ObjectTypeDB::bind_method(_MD("get_current_file"),&EditorFileDialog::get_current_file); + ObjectTypeDB::bind_method(_MD("get_current_path"),&EditorFileDialog::get_current_path); + ObjectTypeDB::bind_method(_MD("set_current_dir","dir"),&EditorFileDialog::set_current_dir); + ObjectTypeDB::bind_method(_MD("set_current_file","file"),&EditorFileDialog::set_current_file); + ObjectTypeDB::bind_method(_MD("set_current_path","path"),&EditorFileDialog::set_current_path); + ObjectTypeDB::bind_method(_MD("set_mode","mode"),&EditorFileDialog::set_mode); + ObjectTypeDB::bind_method(_MD("get_mode"),&EditorFileDialog::get_mode); + ObjectTypeDB::bind_method(_MD("get_vbox:VBoxContainer"),&EditorFileDialog::get_vbox); + ObjectTypeDB::bind_method(_MD("set_access","access"),&EditorFileDialog::set_access); + ObjectTypeDB::bind_method(_MD("get_access"),&EditorFileDialog::get_access); + ObjectTypeDB::bind_method(_MD("set_show_hidden_files"),&EditorFileDialog::set_show_hidden_files); + ObjectTypeDB::bind_method(_MD("is_showing_hidden_files"),&EditorFileDialog::is_showing_hidden_files); + ObjectTypeDB::bind_method(_MD("_select_drive"),&EditorFileDialog::_select_drive); + ObjectTypeDB::bind_method(_MD("_make_dir"),&EditorFileDialog::_make_dir); + ObjectTypeDB::bind_method(_MD("_make_dir_confirm"),&EditorFileDialog::_make_dir_confirm); + ObjectTypeDB::bind_method(_MD("_update_file_list"),&EditorFileDialog::update_file_list); + ObjectTypeDB::bind_method(_MD("_update_dir"),&EditorFileDialog::update_dir); + ObjectTypeDB::bind_method(_MD("_thumbnail_done"),&EditorFileDialog::_thumbnail_done); + ObjectTypeDB::bind_method(_MD("set_display_mode","mode"),&EditorFileDialog::set_display_mode); + ObjectTypeDB::bind_method(_MD("get_display_mode"),&EditorFileDialog::get_display_mode); + ObjectTypeDB::bind_method(_MD("_thumbnail_result"),&EditorFileDialog::_thumbnail_result); + + ObjectTypeDB::bind_method(_MD("_recent_selected"),&EditorFileDialog::_recent_selected); + ObjectTypeDB::bind_method(_MD("_go_back"),&EditorFileDialog::_go_back); + ObjectTypeDB::bind_method(_MD("_go_forward"),&EditorFileDialog::_go_forward); + ObjectTypeDB::bind_method(_MD("_go_up"),&EditorFileDialog::_go_up); + + ObjectTypeDB::bind_method(_MD("_favorite_toggled"),&EditorFileDialog::_favorite_toggled); + ObjectTypeDB::bind_method(_MD("_favorite_selected"),&EditorFileDialog::_favorite_selected); + ObjectTypeDB::bind_method(_MD("_favorite_move_up"),&EditorFileDialog::_favorite_move_up); + ObjectTypeDB::bind_method(_MD("_favorite_move_down"),&EditorFileDialog::_favorite_move_down); + + ObjectTypeDB::bind_method(_MD("invalidate"),&EditorFileDialog::invalidate); + + ADD_SIGNAL(MethodInfo("file_selected",PropertyInfo( Variant::STRING,"path"))); + ADD_SIGNAL(MethodInfo("files_selected",PropertyInfo( Variant::STRING_ARRAY,"paths"))); + ADD_SIGNAL(MethodInfo("dir_selected",PropertyInfo( Variant::STRING,"dir"))); + + BIND_CONSTANT( MODE_OPEN_FILE ); + BIND_CONSTANT( MODE_OPEN_FILES ); + BIND_CONSTANT( MODE_OPEN_DIR ); + BIND_CONSTANT( MODE_SAVE_FILE ); + + BIND_CONSTANT( ACCESS_RESOURCES ); + BIND_CONSTANT( ACCESS_USERDATA ); + BIND_CONSTANT( ACCESS_FILESYSTEM ); + +} + + +void EditorFileDialog::set_show_hidden_files(bool p_show) { + show_hidden_files=p_show; + invalidate(); +} + +bool EditorFileDialog::is_showing_hidden_files() const { + return show_hidden_files; +} + +void EditorFileDialog::set_default_show_hidden_files(bool p_show) { + default_show_hidden_files=p_show; +} + +void EditorFileDialog::_save_to_recent() { + + String dir = get_current_dir(); + Vector<String> recent = EditorSettings::get_singleton()->get_recent_dirs(); + + const int max=20; + int count=0; + bool res=dir.begins_with("res://"); + + for(int i=0;i<recent.size();i++) { + bool cres=recent[i].begins_with("res://"); + if (recent[i]==dir || (res==cres && count>max)) { + recent.remove(i); + i--; + } else { + count++; + } + } + + recent.insert(0,dir); + + EditorSettings::get_singleton()->set_recent_dirs(recent); + + +} + +EditorFileDialog::EditorFileDialog() { + + show_hidden_files=true; + display_mode=DISPLAY_THUMBNAILS; + local_history_pos=0; + + VBoxContainer *vbc = memnew( VBoxContainer ); + add_child(vbc); + set_child_rect(vbc); + + mode=MODE_SAVE_FILE; + set_title("Save a File"); + + HBoxContainer *pathhb = memnew( HBoxContainer ); + + dir_prev = memnew( ToolButton ); + dir_next = memnew( ToolButton ); + dir_up = memnew( ToolButton ); + + pathhb->add_child(dir_prev); + pathhb->add_child(dir_next); + pathhb->add_child(dir_up); + + dir_prev->connect("pressed",this,"_go_back"); + dir_next->connect("pressed",this,"_go_forward"); + dir_up->connect("pressed",this,"_go_up"); + + dir = memnew(LineEdit); + pathhb->add_child(dir); + dir->set_h_size_flags(SIZE_EXPAND_FILL); + + favorite = memnew( ToolButton ); + favorite->set_toggle_mode(true); + favorite->connect("toggled",this,"_favorite_toggled"); + pathhb->add_child(favorite); + + mode_thumbnails = memnew( ToolButton ); + mode_thumbnails->connect("pressed",this,"set_display_mode",varray(DISPLAY_THUMBNAILS)); + mode_thumbnails->set_toggle_mode(true); + mode_thumbnails->set_pressed(true); + pathhb->add_child(mode_thumbnails); + mode_list = memnew( ToolButton ); + mode_list->connect("pressed",this,"set_display_mode",varray(DISPLAY_LIST)); + mode_list->set_toggle_mode(true); + pathhb->add_child(mode_list); + + drives = memnew( OptionButton ); + pathhb->add_child(drives); + drives->connect("item_selected",this,"_select_drive"); + + makedir = memnew( Button ); + makedir->set_text("Create Folder"); + makedir->connect("pressed",this,"_make_dir"); + pathhb->add_child(makedir); + + list_hb = memnew( HBoxContainer ); + + vbc->add_margin_child("Path:",pathhb); + vbc->add_child(list_hb); + list_hb->set_v_size_flags(SIZE_EXPAND_FILL); + + VBoxContainer *fav_vb = memnew( VBoxContainer ); + list_hb->add_child(fav_vb); + HBoxContainer *fav_hb = memnew( HBoxContainer ); + fav_vb->add_child(fav_hb); + fav_hb->add_child(memnew(Label("Favorites:"))); + fav_hb->add_spacer(); + fav_up = memnew( ToolButton ); + fav_hb->add_child(fav_up); + fav_up->connect("pressed",this,"_favorite_move_up"); + fav_down = memnew( ToolButton ); + fav_hb->add_child(fav_down); + fav_down->connect("pressed",this,"_favorite_move_down"); + fav_rm = memnew( ToolButton ); + fav_hb->add_child(fav_rm); + fav_rm->hide(); // redundant + + MarginContainer *fav_mv = memnew( MarginContainer ); + fav_vb->add_child(fav_mv); + fav_mv->set_v_size_flags(SIZE_EXPAND_FILL); + favorites = memnew( ItemList ); + fav_mv->add_child(favorites); + favorites->connect("item_selected",this,"_favorite_selected"); + + recent = memnew( ItemList ); + fav_vb->add_margin_child("Recent:",recent,true); + recent->connect("item_selected",this,"_recent_selected"); + + VBoxContainer *item_vb = memnew( VBoxContainer ); + list_hb->add_child(item_vb); + item_vb->set_h_size_flags(SIZE_EXPAND_FILL); + + item_list = memnew( ItemList ); + item_list->set_v_size_flags(SIZE_EXPAND_FILL); + item_vb->add_margin_child("Directories & Files:",item_list,true); + + HBoxContainer* filter_hb = memnew( HBoxContainer ); + item_vb->add_child(filter_hb); + + VBoxContainer *filter_vb = memnew( VBoxContainer ); + filter_hb->add_child(filter_vb); + filter_vb->set_h_size_flags(SIZE_EXPAND_FILL); + + preview_vb = memnew( VBoxContainer ); + filter_hb->add_child(preview_vb); + CenterContainer *prev_cc = memnew( CenterContainer ); + preview_vb->add_margin_child("Preview:",prev_cc); + preview = memnew( TextureFrame ); + prev_cc->add_child(preview); + preview_vb->hide(); + + + file = memnew(LineEdit); + //add_child(file); + filter_vb->add_margin_child("File:",file); + + + filter = memnew( OptionButton ); + //add_child(filter); + filter_vb->add_margin_child("Filter:",filter); + filter->set_clip_text(true);//too many extensions overflow it + + dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES); + access=ACCESS_RESOURCES; + _update_drives(); + + + connect("confirmed", this,"_action_pressed"); + //cancel->connect("pressed", this,"_cancel_pressed"); + item_list->connect("item_selected", this,"_item_selected",varray(),CONNECT_DEFERRED); + item_list->connect("item_activated", this,"_item_db_selected",varray()); + dir->connect("text_entered", this,"_dir_entered"); + file->connect("text_entered", this,"_file_entered"); + filter->connect("item_selected", this,"_filter_selected"); + + + confirm_save = memnew( ConfirmationDialog ); + confirm_save->set_as_toplevel(true); + add_child(confirm_save); + + + confirm_save->connect("confirmed", this,"_save_confirm_pressed"); + + makedialog = memnew( ConfirmationDialog ); + makedialog->set_title("Create Folder"); + VBoxContainer *makevb= memnew( VBoxContainer ); + makedialog->add_child(makevb); + makedialog->set_child_rect(makevb); + makedirname = memnew( LineEdit ); + makevb->add_margin_child("Name:",makedirname); + add_child(makedialog); + makedialog->register_text_enter(makedirname); + makedialog->connect("confirmed",this,"_make_dir_confirm"); + mkdirerr = memnew( AcceptDialog ); + mkdirerr->set_text("Could not create folder."); + add_child(mkdirerr); + + exterr = memnew( AcceptDialog ); + exterr->set_text("Must use a valid extension."); + add_child(exterr); + + + //update_file_list(); + update_filters(); + update_dir(); + + set_hide_on_ok(false); + vbox=vbc; + + + invalidated=true; + if (register_func) + register_func(this); + + preview_wheel_timeout=0; + preview_wheel_index=0; + preview_waiting=false; + +} + + +EditorFileDialog::~EditorFileDialog() { + + if (unregister_func) + unregister_func(this); + memdelete(dir_access); +} + + +void EditorLineEditFileChooser::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("_browse"),&EditorLineEditFileChooser::_browse); + ObjectTypeDB::bind_method(_MD("_chosen"),&EditorLineEditFileChooser::_chosen); + ObjectTypeDB::bind_method(_MD("get_button:Button"),&EditorLineEditFileChooser::get_button); + ObjectTypeDB::bind_method(_MD("get_line_edit:LineEdit"),&EditorLineEditFileChooser::get_line_edit); + ObjectTypeDB::bind_method(_MD("get_file_dialog:EditorFileDialog"),&EditorLineEditFileChooser::get_file_dialog); + +} + +void EditorLineEditFileChooser::_chosen(const String& p_text){ + + line_edit->set_text(p_text); + line_edit->emit_signal("text_entered",p_text); +} + +void EditorLineEditFileChooser::_browse() { + + dialog->popup_centered_ratio(); +} + +EditorLineEditFileChooser::EditorLineEditFileChooser() { + + line_edit = memnew( LineEdit ); + add_child(line_edit); + line_edit->set_h_size_flags(SIZE_EXPAND_FILL); + button = memnew( Button ); + button->set_text(" .. "); + add_child(button); + button->connect("pressed",this,"_browse"); + dialog = memnew( EditorFileDialog); + add_child(dialog); + dialog->connect("file_selected",this,"_chosen"); + dialog->connect("dir_selected",this,"_chosen"); + dialog->connect("files_selected",this,"_chosen"); + +} diff --git a/tools/editor/editor_file_dialog.h b/tools/editor/editor_file_dialog.h new file mode 100644 index 0000000000..6cfd970516 --- /dev/null +++ b/tools/editor/editor_file_dialog.h @@ -0,0 +1,245 @@ +/*************************************************************************/ +/* file_dialog.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 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 */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + + +#ifndef EDITORFILEDIALOG_H +#define EDITORFILEDIALOG_H + +#include "scene/gui/dialogs.h" +#include "scene/gui/item_list.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/option_button.h" +#include "scene/gui/dialogs.h" +#include "os/dir_access.h" +#include "scene/gui/box_container.h" +#include "scene/gui/texture_frame.h" +#include "scene/gui/tool_button.h" +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ +class EditorFileDialog : public ConfirmationDialog { + + OBJ_TYPE( EditorFileDialog, ConfirmationDialog ); + +public: + + enum DisplayMode { + DISPLAY_THUMBNAILS, + DISPLAY_LIST + }; + + + enum Access { + ACCESS_RESOURCES, + ACCESS_USERDATA, + ACCESS_FILESYSTEM + }; + + + enum Mode { + MODE_OPEN_FILE, + MODE_OPEN_FILES, + MODE_OPEN_DIR, + MODE_SAVE_FILE, + }; + + typedef Ref<Texture> (*GetIconFunc)(const String&); + typedef void (*RegisterFunc)(EditorFileDialog*); + + static GetIconFunc get_icon_func; + static GetIconFunc get_large_icon_func; + static RegisterFunc register_func; + static RegisterFunc unregister_func; + +private: + + ConfirmationDialog *makedialog; + LineEdit *makedirname; + + Button *makedir; + Access access; + //Button *action; + VBoxContainer *vbox; + Mode mode; + LineEdit *dir; + + ToolButton *dir_prev; + ToolButton *dir_next; + ToolButton *dir_up; + + OptionButton *drives; + ItemList *item_list; + TextureFrame *preview; + VBoxContainer *preview_vb; + HBoxContainer *list_hb; + LineEdit *file; + AcceptDialog *mkdirerr; + AcceptDialog *exterr; + OptionButton *filter; + DirAccess *dir_access; + ConfirmationDialog *confirm_save; + ToolButton *mode_thumbnails; + ToolButton *mode_list; + + + ToolButton *favorite; + + ToolButton *fav_up; + ToolButton *fav_down; + ToolButton *fav_rm; + + ItemList *favorites; + ItemList *recent; + + Vector<String> local_history; + int local_history_pos; + void _push_history(); + + Vector<String> filters; + + bool preview_waiting; + int preview_wheel_index; + float preview_wheel_timeout; + static bool default_show_hidden_files; + bool show_hidden_files; + DisplayMode display_mode; + + bool invalidated; + + void update_dir(); + void update_file_list(); + void update_filters(); + + void _update_favorites(); + void _favorite_toggled(bool p_toggle); + void _favorite_selected(int p_idx); + void _favorite_move_up(); + void _favorite_move_down(); + + + + void _recent_selected(int p_idx); + + void _item_selected(int p_item); + void _item_dc_selected(int p_item); + + void _select_drive(int p_idx); + void _dir_entered(String p_dir); + void _file_entered(const String& p_file); + void _action_pressed(); + void _save_confirm_pressed(); + void _cancel_pressed(); + void _filter_selected(int); + void _make_dir(); + void _make_dir_confirm(); + + void _update_drives(); + + void _go_up(); + void _go_back(); + void _go_forward(); + + virtual void _post_popup(); + + void _save_to_recent(); + //callback funtion is callback(String p_path,Ref<Texture> preview,Variant udata) preview null if could not load + + void _thumbnail_result(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata); + void _thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata); + void _request_single_thumbnail(const String& p_path); + +protected: + + void _notification(int p_what); + static void _bind_methods(); + //bind helpers +public: + + void clear_filters(); + void add_filter(const String& p_filter); + + void set_enable_multiple_selection(bool p_enable); + Vector<String> get_selected_files() const; + + String get_current_dir() const; + String get_current_file() const; + String get_current_path() const; + void set_current_dir(const String& p_dir); + void set_current_file(const String& p_file); + void set_current_path(const String& p_path); + + void set_display_mode(DisplayMode p_mode); + DisplayMode get_display_mode() const; + + void set_mode(Mode p_mode); + Mode get_mode() const; + + VBoxContainer *get_vbox(); + LineEdit *get_line_edit() { return file; } + + void set_access(Access p_access); + Access get_access() const; + + void set_show_hidden_files(bool p_show); + bool is_showing_hidden_files() const; + + static void set_default_show_hidden_files(bool p_show); + + void invalidate(); + + EditorFileDialog(); + ~EditorFileDialog(); + +}; + +class EditorLineEditFileChooser : public HBoxContainer { + + OBJ_TYPE( EditorLineEditFileChooser, HBoxContainer ); + Button *button; + LineEdit *line_edit; + EditorFileDialog *dialog; + + void _chosen(const String& p_text); + void _browse(); +protected: + static void _bind_methods(); +public: + + Button *get_button() { return button; } + LineEdit *get_line_edit() { return line_edit; } + EditorFileDialog *get_file_dialog() { return dialog; } + + EditorLineEditFileChooser(); +}; + +VARIANT_ENUM_CAST( EditorFileDialog::Mode ); +VARIANT_ENUM_CAST( EditorFileDialog::Access ); +VARIANT_ENUM_CAST( EditorFileDialog::DisplayMode ); + +#endif // EDITORFILEDIALOG_H diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp index 8e96123c36..d741087a9f 100644 --- a/tools/editor/editor_file_system.cpp +++ b/tools/editor/editor_file_system.cpp @@ -33,7 +33,7 @@ #include "os/file_access.h" #include "editor_node.h" #include "io/resource_saver.h" - +#include "editor_settings.h" EditorFileSystem *EditorFileSystem::singleton=NULL; @@ -357,7 +357,9 @@ void EditorFileSystem::_scan_scenes() { String project=Globals::get_singleton()->get_resource_path(); - FileAccess *f =FileAccess::open(project+"/.fscache",FileAccess::READ); + + String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("file_cache"); + FileAccess *f =FileAccess::open(fscache,FileAccess::READ); if (f) { //read the disk cache @@ -470,7 +472,9 @@ void EditorFileSystem::_scan_scenes() { //save back the findings - f=FileAccess::open(project+"/.fscache",FileAccess::WRITE); +// String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("file_cache"); + + f=FileAccess::open(fscache,FileAccess::WRITE); _save_type_cache_fs(scandir,f); f->close(); memdelete(f); @@ -989,6 +993,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) { void EditorFileSystem::_resource_saved(const String& p_path){ + print_line("resource saved: "+p_path); EditorFileSystem::get_singleton()->update_file(p_path); } diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index f5139cfe4a..f55a3d6894 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -54,7 +54,7 @@ #include "register_exporters.h" #include "bind/core_bind.h" #include "io/zip_io.h" - +#include "io/config_file.h" // plugins #include "plugins/sprite_frames_editor_plugin.h" @@ -91,6 +91,7 @@ #include "plugins/polygon_2d_editor_plugin.h" #include "plugins/navigation_polygon_editor_plugin.h" #include "plugins/light_occluder_2d_editor_plugin.h" +#include "plugins/color_ramp_editor_plugin.h" // end #include "tools/editor/io_plugins/editor_texture_import_plugin.h" #include "tools/editor/io_plugins/editor_scene_import_plugin.h" @@ -99,15 +100,29 @@ #include "tools/editor/io_plugins/editor_translation_import_plugin.h" #include "tools/editor/io_plugins/editor_mesh_import_plugin.h" +#include "plugins/editor_preview_plugins.h" EditorNode *EditorNode::singleton=NULL; +void EditorNode::_update_scene_tabs() { + + scene_tabs->clear_tabs(); + for(int i=0;i<editor_data.get_edited_scene_count();i++) { + int current = editor_data.get_edited_scene(); + bool unsaved = (i==current)?saved_version!=editor_data.get_undo_redo().get_version():editor_data.get_scene_version(i)!=0; + scene_tabs->add_tab(editor_data.get_scene_title(i)+(unsaved?"(*)":"")); + } + + scene_tabs->set_current_tab(editor_data.get_edited_scene()); + +} + void EditorNode::_update_title() { String appname = Globals::get_singleton()->get("application/name"); String title = appname.empty()?String(VERSION_FULL_NAME):String(_MKSTR(VERSION_NAME) + String(" - ") + appname); - String edited = edited_scene?edited_scene->get_filename():String(); + String edited = editor_data.get_edited_scene_root()?editor_data.get_edited_scene_root()->get_filename():String(); if (!edited.empty()) title+=" - " + String(edited.get_file()); if (unsaved_cache) @@ -172,6 +187,11 @@ void EditorNode::_notification(int p_what) { _update_title(); } + if (last_checked_version!=editor_data.get_undo_redo().get_version()) { + _update_scene_tabs(); + last_checked_version=editor_data.get_undo_redo().get_version(); + } + //get_root_node()->set_rect(viewport->get_global_rect()); //update the circle @@ -229,6 +249,13 @@ void EditorNode::_notification(int p_what) { //import_monitor->scan_changes(); } + + if (p_what==NOTIFICATION_EXIT_TREE) { + + + editor_data.clear_edited_scenes(); + + } if (p_what==NOTIFICATION_READY) { VisualServer::get_singleton()->viewport_set_hide_scenario(get_scene_root()->get_viewport(),true); @@ -320,6 +347,11 @@ void EditorNode::_fs_changed() { E->get()->invalidate(); } + + for(Set<EditorFileDialog*>::Element *E=editor_file_dialogs.front();E;E=E->next()) { + + E->get()->invalidate(); + } } void EditorNode::_sources_changed(bool p_exist) { @@ -386,7 +418,7 @@ void EditorNode::edit_node(Node *p_node) { void EditorNode::open_resource(const String& p_type) { - file->set_mode(FileDialog::MODE_OPEN_FILE); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); List<String> extensions; ResourceLoader::get_recognized_extensions_for_type(p_type,&extensions); @@ -461,7 +493,7 @@ void EditorNode::_dialog_display_file_error(String p_file,Error p_error) { void EditorNode::_get_scene_metadata() { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) return; @@ -488,7 +520,7 @@ void EditorNode::_get_scene_metadata() { void EditorNode::_set_scene_metadata() { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) return; @@ -711,16 +743,106 @@ void EditorNode::_save_edited_subresources(Node* scene,Map<RES,bool>& processed, for(int i=0;i<scene->get_child_count();i++) { Node *n = scene->get_child(i); - if (n->get_owner()!=edited_scene) + if (n->get_owner()!=editor_data.get_edited_scene_root()) continue; _save_edited_subresources(n,processed,flags); } } +void EditorNode::_find_node_types(Node* p_node, int&count_2d, int&count_3d) { + + if (p_node->is_type("Viewport") || (p_node!=editor_data.get_edited_scene_root() && p_node->get_owner()!=editor_data.get_edited_scene_root())) + return; + + if (p_node->is_type("CanvasItem")) + count_2d++; + else if (p_node->is_type("Spatial")) + count_3d++; + + for(int i=0;i<p_node->get_child_count();i++) + _find_node_types(p_node->get_child(i),count_2d,count_3d); + +} + + +void EditorNode::_save_scene_with_preview(String p_file) { + + int c2d=0; + int c3d=0; + + EditorProgress save("save","Saving Scene",4); + save.step("Analyzing",0); + _find_node_types(editor_data.get_edited_scene_root(),c2d,c3d); + + RID viewport; + bool is2d; + if (c3d<c2d) { + viewport=scene_root->get_viewport(); + is2d=true; + } else { + viewport=SpatialEditor::get_singleton()->get_editor_viewport(0)->get_viewport_node()->get_viewport(); + is2d=false; + + } + save.step("Creating Thumbnail",1); + //current view? + int screen =-1; + for(int i=0;i<editor_table.size();i++) { + if (editor_plugin_screen==editor_table[i]) { + screen=i; + break; + } + } + + _editor_select(is2d?0:1); + + VS::get_singleton()->viewport_queue_screen_capture(viewport); + save.step("Creating Thumbnail",2); + save.step("Creating Thumbnail",3); + Image img = VS::get_singleton()->viewport_get_screen_capture(viewport); + int preview_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");; + int width,height; + if (img.get_width() > preview_size && img.get_width() >= img.get_height()) { + + width=preview_size; + height = img.get_height() * preview_size / img.get_width(); + } else if (img.get_height() > preview_size && img.get_height() >= img.get_width()) { + + height=preview_size; + width = img.get_width() * preview_size / img.get_height(); + } else { + + width=img.get_width(); + height=img.get_height(); + } + + img.convert(Image::FORMAT_RGB); + img.resize(width,height); + + String pfile = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/last_scene_preview.png"); + img.save_png(pfile); + Vector<uint8_t> imgdata = FileAccess::get_file_as_array(pfile); + + //print_line("img data is "+itos(imgdata.size())); + + if (editor_data.get_edited_scene_import_metadata().is_null()) + editor_data.set_edited_scene_import_metadata(Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ) ); + editor_data.get_edited_scene_import_metadata()->set_option("thumbnail",imgdata); + + //tamanio tel thumbnail + if (screen!=-1) { + _editor_select(screen); + } + save.step("Saving Scene",4); + _save_scene(p_file); + +} + + void EditorNode::_save_scene(String p_file) { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -754,7 +876,7 @@ void EditorNode::_save_scene(String p_file) { return; } - sdata->set_import_metadata(scene_import_metadata); + sdata->set_import_metadata(editor_data.get_edited_scene_import_metadata()); int flg=0; if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources")) flg|=ResourceSaver::FLAG_COMPRESS; @@ -770,7 +892,7 @@ void EditorNode::_save_scene(String p_file) { if (err==OK) { scene->set_filename( Globals::get_singleton()->localize_path(p_file) ); //EditorFileSystem::get_singleton()->update_file(p_file,sdata->get_type()); - saved_version=editor_data.get_undo_redo().get_version(); + set_current_version(editor_data.get_undo_redo().get_version()); _update_title(); } else { @@ -958,7 +1080,7 @@ void EditorNode::_dialog_action(String p_file) { Node *base = selection.front()->get(); Map<Node*,Node*> reown; - reown[get_edited_scene()]=base; + reown[editor_data.get_edited_scene_root()]=base; Node *copy = base->duplicate_and_reown(reown); if (copy) { @@ -1016,7 +1138,9 @@ void EditorNode::_dialog_action(String p_file) { if (file->get_mode()==FileDialog::MODE_SAVE_FILE) { - _save_scene(p_file); + //_save_scene(p_file); + _save_scene_with_preview(p_file); + } } break; @@ -1024,7 +1148,8 @@ void EditorNode::_dialog_action(String p_file) { case FILE_SAVE_AND_RUN: { if (file->get_mode()==FileDialog::MODE_SAVE_FILE) { - _save_scene(p_file); + //_save_scene(p_file); + _save_scene_with_preview(p_file); _run(false); } } break; @@ -1050,7 +1175,7 @@ void EditorNode::_dialog_action(String p_file) { ml = Ref<MeshLibrary>( memnew( MeshLibrary )); } - MeshLibraryEditor::update_library_file(edited_scene,ml,true); + MeshLibraryEditor::update_library_file(editor_data.get_edited_scene_root(),ml,true); Error err = ResourceSaver::save(p_file,ml); if (err) { @@ -1084,7 +1209,7 @@ void EditorNode::_dialog_action(String p_file) { ml = Ref<TileSet>( memnew( TileSet )); } - TileSetEditor::update_library_file(edited_scene,ml,true); + TileSetEditor::update_library_file(editor_data.get_edited_scene_root(),ml,true); Error err = ResourceSaver::save(p_file,ml); if (err) { @@ -1177,7 +1302,8 @@ void EditorNode::_dialog_action(String p_file) { if (file->get_mode()==FileDialog::MODE_SAVE_FILE) { - _save_scene(p_file); + //_save_scene(p_file); + _save_scene_with_preview(p_file); } } break; @@ -1224,15 +1350,15 @@ void EditorNode::_property_editor_back() { void EditorNode::_imported(Node *p_node) { - Node *scene = edited_scene; - set_edited_scene(p_node); - + Node *scene = editor_data.get_edited_scene_root(); +// add_edited_scene(p_node); +/* if (scene) { String path = scene->get_filename(); p_node->set_filename(path); memdelete(scene); } - +*/ } @@ -1276,7 +1402,7 @@ void EditorNode::_edit_current() { object_menu->set_disabled(false); resources_dock->add_resource(Ref<Resource>(current_res)); - top_pallete->set_current_tab(1); + //top_pallete->set_current_tab(1); } @@ -1293,7 +1419,7 @@ void EditorNode::_edit_current() { scene_tree_dock->set_selected(current_node); object_menu->get_popup()->clear(); - top_pallete->set_current_tab(0); + //top_pallete->set_current_tab(0); } @@ -1307,17 +1433,22 @@ void EditorNode::_edit_current() { if (main_plugin!=editor_plugin_screen) { // update screen main_plugin - if (editor_plugin_screen) - editor_plugin_screen->make_visible(false); - editor_plugin_screen=main_plugin; - editor_plugin_screen->edit(current_obj); - editor_plugin_screen->make_visible(true); + if (!changing_scene) { - for(int i=0;i<editor_table.size();i++) { - if (editor_table[i]==main_plugin) { - main_editor_tabs->set_current_tab(i); - break; + if (editor_plugin_screen) + editor_plugin_screen->make_visible(false); + editor_plugin_screen=main_plugin; + editor_plugin_screen->edit(current_obj); + + editor_plugin_screen->make_visible(true); + + + for(int i=0;i<editor_table.size();i++) { + if (editor_table[i]==main_plugin) { + main_editor_tabs->set_current_tab(i); + break; + } } } @@ -1426,10 +1557,10 @@ void EditorNode::_run(bool p_current,const String& p_custom) { - if (p_current || (edited_scene && p_custom==edited_scene->get_filename())) { + if (p_current || (editor_data.get_edited_scene_root() && p_custom==editor_data.get_edited_scene_root()->get_filename())) { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -1491,7 +1622,7 @@ void EditorNode::_run(bool p_current,const String& p_custom) { if (unsaved_cache) { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (scene) { //only autosave if there is a scene obviously @@ -1505,7 +1636,8 @@ void EditorNode::_run(bool p_current,const String& p_custom) { return; } - _save_scene(scene->get_filename()); + //_save_scene(scene->get_filename()); + _save_scene_with_preview(scene->get_filename()); } } @@ -1542,8 +1674,8 @@ void EditorNode::_run(bool p_current,const String& p_custom) { void EditorNode::_cleanup_scene() { - - Node *scene = edited_scene; +#if 0 + Node *scene = editor_data.get_edited_scene_root(); editor_selection->clear(); editor_data.clear_editor_states(); editor_history.clear(); @@ -1552,7 +1684,7 @@ void EditorNode::_cleanup_scene() { property_editor->edit(NULL); resources_dock->cleanup(); scene_import_metadata.unref(); - set_edited_scene(NULL); + //set_edited_scene(NULL); if (scene) { if (scene->get_filename()!="") { previous_scenes.push_back(scene->get_filename()); @@ -1578,7 +1710,7 @@ void EditorNode::_cleanup_scene() { } _update_title(); - +#endif } void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { @@ -1591,16 +1723,20 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { switch( p_option ) { case FILE_NEW_SCENE: { + /* if (!p_confirmed) { confirmation->get_ok()->set_text("Yes"); //confirmation->get_cancel()->show(); confirmation->set_text("Start a New Scene? (Current will be lost)"); confirmation->popup_centered_minsize(); break; - } + }*/ - _cleanup_scene(); + int idx = editor_data.add_edited_scene(-1); + _scene_tab_changed(idx); + + //_cleanup_scene(); } break; @@ -1608,7 +1744,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { //print_tree(); - file->set_mode(FileDialog::MODE_OPEN_FILE); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); //not for now? List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); @@ -1620,7 +1756,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { //file->set_current_path(current_path); - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (scene) { file->set_current_path(scene->get_filename()); }; @@ -1653,20 +1789,36 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { open_request(previous_scenes.back()->get()); } break; + case FILE_CLOSE: { + + if (!p_confirmed) { + confirmation->get_ok()->set_text("Yes"); + //confirmation->get_cancel()->show(); + confirmation->set_text("Close scene? (Unsaved changes will be lost)"); + confirmation->popup_centered_minsize(); + break; + } + + _remove_edited_scene(); + + + + } break; case FILE_SAVE_SCENE: { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (scene && scene->get_filename()!="") { - _save_scene(scene->get_filename()); + //_save_scene(scene->get_filename()); + _save_scene_with_preview(scene->get_filename()); return; }; // fallthrough to save_as }; case FILE_SAVE_AS_SCENE: { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -1678,7 +1830,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { break; } - file->set_mode(FileDialog::MODE_SAVE_FILE); + file->set_mode(EditorFileDialog::MODE_SAVE_FILE); bool relpaths = (scene->has_meta("__editor_relpaths__") && scene->get_meta("__editor_relpaths__").operator bool()); @@ -1728,7 +1880,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { case FILE_DUMP_STRINGS: { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -1761,7 +1913,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { bool relpaths = (scene->has_meta("__editor_relpaths__") && scene->get_meta("__editor_relpaths__").operator bool()); - file->set_mode(FileDialog::MODE_SAVE_FILE); + file->set_mode(EditorFileDialog::MODE_SAVE_FILE); file->set_current_path(cpath); file->set_title("Save Translatable Strings"); @@ -1772,7 +1924,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { case FILE_SAVE_SUBSCENE: { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -1799,7 +1951,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { Node *tocopy = selection.front()->get(); - if (tocopy!=edited_scene && tocopy->get_filename()!="") { + if (tocopy!=editor_data.get_edited_scene_root() && tocopy->get_filename()!="") { current_option=-1; @@ -1810,7 +1962,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { break; } - file->set_mode(FileDialog::MODE_SAVE_FILE); + file->set_mode(EditorFileDialog::MODE_SAVE_FILE); List<String> extensions; Ref<PackedScene> sd = memnew( PackedScene ); @@ -1833,7 +1985,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { file->set_title("Save Sub-Scene As.."); } break; case FILE_SAVE_OPTIMIZED: { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); #if 0 if (!scene) { @@ -1895,7 +2047,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { case FILE_EXPORT_MESH_LIBRARY: { - if (!edited_scene) { + if (!editor_data.get_edited_scene_root()) { current_option=-1; //confirmation->get_cancel()->hide(); @@ -1940,7 +2092,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { //import_subscene->popup_centered_ratio(); - if (!edited_scene) { + if (!editor_data.get_edited_scene_root()) { current_option=-1; //accept->get_cancel()->hide(); @@ -2466,30 +2618,54 @@ void EditorNode::remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_ed _rebuild_import_menu(); } +void EditorNode::_remove_edited_scene() { + int new_index = editor_data.get_edited_scene(); + int old_index=new_index; + + if (new_index>0) { + new_index=new_index-1; + } else if (editor_data.get_edited_scene_count()>1) { + new_index=1; + } else { + editor_data.add_edited_scene(-1); + new_index=1; + } + _scene_tab_changed(new_index); + editor_data.remove_scene(old_index); + editor_data.get_undo_redo().clear_history(); + _update_title(); + _update_scene_tabs(); + + if (editor_data.get_edited_scene_count()==1) { + //make new scene appear saved + set_current_version(editor_data.get_undo_redo().get_version()); + unsaved_cache=false; + } +} void EditorNode::set_edited_scene(Node *p_scene) { - if (edited_scene) { - if (edited_scene->get_parent()==scene_root) - scene_root->remove_child(edited_scene); + if (get_editor_data().get_edited_scene_root()) { + if (get_editor_data().get_edited_scene_root()->get_parent()==scene_root) + scene_root->remove_child(get_editor_data().get_edited_scene_root()); animation_editor->set_root(NULL); } - edited_scene=p_scene; - if (edited_scene && edited_scene->cast_to<Popup>()) - edited_scene->cast_to<Popup>()->show(); //show popups - scene_tree_dock->set_edited_scene(edited_scene); + get_editor_data().set_edited_scene_root(p_scene); + + if (p_scene && p_scene->cast_to<Popup>()) + p_scene->cast_to<Popup>()->show(); //show popups + scene_tree_dock->set_edited_scene(p_scene); if (get_tree()) - get_tree()->set_edited_scene_root(edited_scene); + get_tree()->set_edited_scene_root(p_scene); - if (edited_scene) { + if (p_scene) { if (p_scene->get_parent()!=scene_root) scene_root->add_child(p_scene); animation_editor->set_root(p_scene); } - - } + void EditorNode::_fetch_translatable_strings(const Object *p_object,Set<StringName>& strings) { @@ -2656,7 +2832,7 @@ Error EditorNode::save_optimized_copy(const String& p_scene,const String& p_pres } } - ERR_EXPLAIN("Preset '"+p_preset+"' references unexisting saver: "+type); + ERR_EXPLAIN("Preset '"+p_preset+"' references nonexistent saver: "+type); ERR_FAIL_COND_V(saver.is_null(),ERR_INVALID_DATA); List<Variant> keys; @@ -2715,6 +2891,115 @@ Error EditorNode::save_optimized_copy(const String& p_scene,const String& p_pres return OK; } + +Dictionary EditorNode::_get_main_scene_state() { + + Dictionary state; + state["main_tab"]=main_editor_tabs->get_current_tab(); + state["scene_tree_offset"]=scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->get_val(); + state["property_edit_offset"]=get_property_editor()->get_scene_tree()->get_vscroll_bar()->get_val(); + state["saved_version"]=saved_version; + //print_line(" getting main tab: "+itos(state["main_tab"])); + return state; +} + +void EditorNode::_set_main_scene_state(Dictionary p_state) { + + //print_line("set current 7 "); + + if (p_state.has("main_tab")) { + int idx = p_state["main_tab"]; + int current=-1; + for(int i=0;i<editor_table.size();i++) { + if (editor_plugin_screen==editor_table[i]) { + current=i; + break; + } + } + + if (idx<2 && current<2) { + //only set tab for 2D and 3D + _editor_select(p_state["main_tab"]); + //print_line(" setting main tab: "+itos(p_state["main_tab"])); + } + } + + if (p_state.has("scene_tree_offset")) + scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->set_val(p_state["scene_tree_offset"]); + if (p_state.has("property_edit_offset")) + get_property_editor()->get_scene_tree()->get_vscroll_bar()->set_val(p_state["property_edit_offset"]); + + //print_line("set current 8 "); + + +} + +void EditorNode::set_current_version(uint64_t p_version) { + + saved_version=p_version; + editor_data.set_edited_scene_version(p_version); +} + +bool EditorNode::is_changing_scene() const { + return changing_scene; +} +void EditorNode::set_current_scene(int p_idx) { + + changing_scene=true; + editor_data.save_edited_scene_state(editor_selection,&editor_history,_get_main_scene_state()); + + if (get_editor_data().get_edited_scene_root()) { + if (get_editor_data().get_edited_scene_root()->get_parent()==scene_root) + scene_root->remove_child(get_editor_data().get_edited_scene_root()); + animation_editor->set_root(NULL); + } + + //print_line("set current 2 "); + + editor_selection->clear(); + editor_data.set_edited_scene(p_idx); + + Node* new_scene = editor_data.get_edited_scene_root(); + + if (new_scene && new_scene->cast_to<Popup>()) + new_scene->cast_to<Popup>()->show(); //show popups + + //print_line("set current 3 "); + + scene_tree_dock->set_edited_scene(new_scene); + if (get_tree()) + get_tree()->set_edited_scene_root(new_scene); + + if (new_scene) { + if (new_scene->get_parent()!=scene_root) + scene_root->add_child(new_scene); + animation_editor->set_root(new_scene); + } + //print_line("set current 4 "); + + + Dictionary state = editor_data.restore_edited_scene_state(editor_selection,&editor_history); + _edit_current(); + + /*if (!unsaved) { + saved_version=editor_data.get_undo_redo().get_version(); + if (p_backwards) + saved_version--; + else + saved_version++; + print_line("was saved, updating version"); + } else { + saved_version=state["saved_version"]; + }*/ + //_set_main_scene_state(state); + + call_deferred("_set_main_scene_state",state); //do after everything else is done setting up + //print_line("set current 6 "); + changing_scene=false; + + +} + Error EditorNode::load_scene(const String& p_scene) { if (!is_inside_tree()) { @@ -2723,6 +3008,14 @@ Error EditorNode::load_scene(const String& p_scene) { } + for(int i=0;i<editor_data.get_edited_scene_count();i++) { + + if (editor_data.get_scene_path(i)==p_scene) { + _scene_tab_changed(i); + return OK; + } + } + load_errors->clear(); String lpath = Globals::get_singleton()->localize_path(p_scene); @@ -2738,7 +3031,20 @@ Error EditorNode::load_scene(const String& p_scene) { return ERR_FILE_NOT_FOUND; } - _cleanup_scene(); // i'm sorry but this MUST happen to avoid modified resources to not be reloaded. + int prev = editor_data.get_edited_scene(); + int idx = editor_data.add_edited_scene(-1); + //print_line("load scene callback"); + //set_current_scene(idx); + + if (!editor_data.get_edited_scene_root() && editor_data.get_edited_scene_count()==2) { + _remove_edited_scene(); + } else { + _scene_tab_changed(idx); + } + + + + //_cleanup_scene(); // i'm sorry but this MUST happen to avoid modified resources to not be reloaded. Ref<PackedScene> sdata = ResourceLoader::load(lpath); if (!sdata.is_valid()) { @@ -2749,6 +3055,11 @@ Error EditorNode::load_scene(const String& p_scene) { accept->set_text("Error loading scene."); accept->popup_centered_minsize(); opening_prev=false; + + if (prev!=-1) { + set_current_scene(prev); + editor_data.remove_scene(idx); + } return ERR_FILE_NOT_FOUND; } @@ -2756,15 +3067,23 @@ Error EditorNode::load_scene(const String& p_scene) { if (!new_scene) { + sdata.unref(); current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("Ugh"); accept->set_text("Error loading scene."); accept->popup_centered_minsize(); opening_prev=false; + if (prev!=-1) { + set_current_scene(prev); + editor_data.remove_scene(idx); + } return ERR_FILE_NOT_FOUND; } + //guess not needed in the end? + //new_scene->clear_internal_tree_resource_paths(); //make sure no internal tree paths to internal resources exist + /* Node *old_scene = edited_scene; _hide_top_editors(); @@ -2777,16 +3096,23 @@ Error EditorNode::load_scene(const String& p_scene) { memdelete(old_scene); } */ + set_edited_scene(new_scene); _get_scene_metadata(); + /* + editor_data.set_edited_scene_root(new_scene); + scene_tree_dock->set_selected(new_scene, true); property_editor->edit(new_scene); - scene_import_metadata = sdata->get_import_metadata(); + editor_data.set_edited_scene_root(new_scene); +*/ + editor_data.set_edited_scene_import_metadata( sdata->get_import_metadata() ); - editor_data.get_undo_redo().clear_history(); + +// editor_data.get_undo_redo().clear_history(); saved_version=editor_data.get_undo_redo().get_version(); _update_title(); - + _update_scene_tabs(); _add_to_recent_scenes(lpath); if (new_scene->has_meta("__editor_plugin_screen__")) { @@ -2805,7 +3131,7 @@ Error EditorNode::load_scene(const String& p_scene) { prev_scene->set_disabled(previous_scenes.size()==0); opening_prev=false; - top_pallete->set_current_tab(0); //always go to scene + //top_pallete->set_current_tab(0); //always go to scene push_item(new_scene); @@ -2816,8 +3142,9 @@ Error EditorNode::load_scene(const String& p_scene) { void EditorNode::open_request(const String& p_path) { - external_file=p_path; - _menu_option_confirm(FILE_EXTERNAL_OPEN_SCENE,false); + load_scene(p_path); // as it will be opened in separate tab + //external_file=p_path; + //_menu_option_confirm(FILE_EXTERNAL_OPEN_SCENE,false); } @@ -2838,9 +3165,9 @@ void EditorNode::_instance_request(const String& p_path){ request_instance_scene(p_path); } -void EditorNode::_property_keyed(const String& p_keyed,const Variant& p_value) { +void EditorNode::_property_keyed(const String& p_keyed,const Variant& p_value,bool p_advance) { - animation_editor->insert_value_key(p_keyed,p_value); + animation_editor->insert_value_key(p_keyed,p_value,p_advance); } void EditorNode::_transform_keyed(Object *sp,const String& p_sub,const Transform& p_key) { @@ -2878,15 +3205,15 @@ void EditorNode::_update_keying() { void EditorNode::_close_messages() { // left_split->set_dragger_visible(false); - old_split_ofs = left_split->get_split_offset(); - left_split->set_split_offset(0); + old_split_ofs = center_split->get_split_offset(); + center_split->set_split_offset(0); // scene_root_parent->set_anchor_and_margin(MARGIN_BOTTOM,Control::ANCHOR_END,0); } void EditorNode::_show_messages() { // left_split->set_dragger_visible(true); - left_split->set_split_offset(old_split_ofs); + center_split->set_split_offset(old_split_ofs); // scene_root_parent->set_anchor_and_margin(MARGIN_BOTTOM,Control::ANCHOR_END,log->get_margin(MARGIN_TOP)); } @@ -2955,15 +3282,16 @@ void EditorNode::_open_recent_scene(int p_idx) { String path = "res://"+rc[p_idx]; - if (unsaved_cache) { + + /*if (unsaved_cache) { _recent_scene=rc[p_idx]; open_recent_confirmation->set_text("Discard current scene and open:\n'"+rc[p_idx]+"'"); open_recent_confirmation->get_label()->set_align(Label::ALIGN_CENTER); open_recent_confirmation->popup_centered(Size2(400,100)); return; - } + }*/ - load_scene(rc[p_idx]); + load_scene(path); } @@ -3007,12 +3335,6 @@ void EditorNode::_save_optimized() { #endif } -void EditorNode::_open_recent_scene_confirm() { - - load_scene(_recent_scene); - -} - void EditorNode::_update_recent_scenes() { String base="_"+Globals::get_singleton()->get_resource_path().replace("\\","::").replace("/","::"); @@ -3132,6 +3454,8 @@ void EditorNode::register_editor_types() { ObjectTypeDB::register_type<EditorImportPlugin>(); ObjectTypeDB::register_type<EditorScenePostImport>(); ObjectTypeDB::register_type<EditorScript>(); + ObjectTypeDB::register_type<EditorFileDialog>(); + ObjectTypeDB::register_type<UndoRedo>(); //ObjectTypeDB::register_type<EditorImporter>(); @@ -3221,7 +3545,7 @@ void EditorNode::_bind_methods() { //ObjectTypeDB::bind_method("_import",&EditorNode::_import); // ObjectTypeDB::bind_method("_import_conflicts_solved",&EditorNode::_import_conflicts_solved); ObjectTypeDB::bind_method("_open_recent_scene",&EditorNode::_open_recent_scene); - ObjectTypeDB::bind_method("_open_recent_scene_confirm",&EditorNode::_open_recent_scene_confirm); +// ObjectTypeDB::bind_method("_open_recent_scene_confirm",&EditorNode::_open_recent_scene_confirm); ObjectTypeDB::bind_method("_save_optimized",&EditorNode::_save_optimized); ObjectTypeDB::bind_method(_MD("animation_panel_make_visible","enable"),&EditorNode::animation_panel_make_visible); @@ -3230,6 +3554,22 @@ void EditorNode::_bind_methods() { ObjectTypeDB::bind_method("_sources_changed",&EditorNode::_sources_changed); ObjectTypeDB::bind_method("_fs_changed",&EditorNode::_fs_changed); + ObjectTypeDB::bind_method("_dock_select_draw",&EditorNode::_dock_select_draw); + ObjectTypeDB::bind_method("_dock_select_input",&EditorNode::_dock_select_input); + ObjectTypeDB::bind_method("_dock_pre_popup",&EditorNode::_dock_pre_popup); + ObjectTypeDB::bind_method("_dock_split_dragged",&EditorNode::_dock_split_dragged); + ObjectTypeDB::bind_method("_save_docks",&EditorNode::_save_docks); + ObjectTypeDB::bind_method("_dock_popup_exit",&EditorNode::_dock_popup_exit); + ObjectTypeDB::bind_method("_dock_move_left",&EditorNode::_dock_move_left); + ObjectTypeDB::bind_method("_dock_move_right",&EditorNode::_dock_move_right); + + ObjectTypeDB::bind_method("set_current_scene",&EditorNode::set_current_scene); + ObjectTypeDB::bind_method("set_current_version",&EditorNode::set_current_version); + ObjectTypeDB::bind_method("_scene_tab_changed",&EditorNode::_scene_tab_changed); + ObjectTypeDB::bind_method("_set_main_scene_state",&EditorNode::_set_main_scene_state); + ObjectTypeDB::bind_method("_update_scene_tabs",&EditorNode::_update_scene_tabs); + + ObjectTypeDB::bind_method(_MD("add_editor_import_plugin", "plugin"), &EditorNode::add_editor_import_plugin); ObjectTypeDB::bind_method(_MD("remove_editor_import_plugin", "plugin"), &EditorNode::remove_editor_import_plugin); @@ -3282,6 +3622,16 @@ void EditorNode::_file_dialog_unregister(FileDialog *p_dialog){ singleton->file_dialogs.erase(p_dialog); } +void EditorNode::_editor_file_dialog_register(EditorFileDialog *p_dialog) { + + singleton->editor_file_dialogs.insert(p_dialog); +} + +void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog){ + + singleton->editor_file_dialogs.erase(p_dialog); +} + Vector<EditorNodeInitCallback> EditorNode::_init_callbacks; Error EditorNode::export_platform(const String& p_platform, const String& p_path, bool p_debug,const String& p_password,bool p_quit_after) { @@ -3300,12 +3650,402 @@ void EditorNode::show_warning(const String& p_text) { warning->popup_centered_minsize(); } +void EditorNode::_dock_select_input(const InputEvent& p_input) { + + if (p_input.type==InputEvent::MOUSE_BUTTON || p_input.type==InputEvent::MOUSE_MOTION) { + + Vector2 point(p_input.mouse_motion.x,p_input.mouse_motion.y); + + int nrect = -1; + for(int i=0;i<DOCK_SLOT_MAX;i++) { + if (dock_select_rect[i].has_point(point)) { + nrect=i; + break; + } + } + + + if (nrect!=dock_select_rect_over) { + dock_select->update(); + dock_select_rect_over=nrect; + + } + + + if (nrect==-1) + return; + + if (p_input.type==InputEvent::MOUSE_BUTTON && p_input.mouse_button.button_index==1 && p_input.mouse_button.pressed && dock_popup_selected!=nrect) { + Control *dock = dock_slot[dock_popup_selected]->get_current_tab_control(); + if (dock) { + dock_slot[dock_popup_selected]->remove_child(dock); + } + if (dock_slot[dock_popup_selected]->get_tab_count()==0) { + dock_slot[dock_popup_selected]->hide(); + + } else { + + dock_slot[dock_popup_selected]->set_current_tab(0); + } + + print_line("performing reparent"); + dock_slot[nrect]->add_child(dock); + dock_popup_selected=nrect; + dock_slot[nrect]->set_current_tab(dock_slot[nrect]->get_tab_count()-1); + dock_slot[nrect]->show(); + dock_select->update(); + + VSplitContainer*splits[DOCK_SLOT_MAX/2]={ + left_l_vsplit, + left_r_vsplit, + right_l_vsplit, + right_r_vsplit, + }; + + for(int i=0;i<4;i++) { + bool in_use = dock_slot[i*2+0]->get_tab_count() || dock_slot[i*2+1]->get_tab_count(); + if (in_use) + splits[i]->show(); + else + splits[i]->hide(); + } + + _save_docks(); + } + } +} + +void EditorNode::_dock_popup_exit() { + + dock_select_rect_over=-1; + dock_select->update(); +} + +void EditorNode::_dock_pre_popup(int p_which) { + + + dock_popup_selected=p_which; +} + +void EditorNode::_dock_move_left() { + + if (dock_popup_selected<0 || dock_popup_selected>=DOCK_SLOT_MAX) + return; + Control *current = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab() ); + Control *prev = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab()-1 ); + if (!current || !prev) + return; + dock_slot[dock_popup_selected]->move_child(current,prev->get_index()); + dock_slot[dock_popup_selected]->set_current_tab( dock_slot[dock_popup_selected]->get_current_tab()-1 ); + dock_select->update(); + _save_docks(); + + +} + +void EditorNode::_dock_move_right() { + + Control *current = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab() ); + Control *next = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab()+1 ); + if (!current || !next) + return; + dock_slot[dock_popup_selected]->move_child(next,current->get_index()); + dock_slot[dock_popup_selected]->set_current_tab( dock_slot[dock_popup_selected]->get_current_tab()+1 ); + dock_select->update(); + _save_docks(); +} + +void EditorNode::_dock_select_draw(){ + Size2 s = dock_select->get_size(); + s.y/=2.0; + s.x/=6.0; + + Color used=Color(0.6,0.6,0.6,0.8); + Color used_selected=Color(0.8,0.8,0.8,0.8); + Color tab_selected=Color(1,1,1,1); + Color unused=used; + unused.a=0.4; + Color unusable=unused; + unusable.a=0.1; + + Rect2 unr(s.x*2,0,s.x*2,s.y*2); + unr.pos+=Vector2(2,5); + unr.size-=Vector2(4,7); + + dock_select->draw_rect(unr,unusable); + + dock_tab_move_left->set_disabled(true); + dock_tab_move_right->set_disabled(true); + + if (dock_popup_selected!=-1 && dock_slot[dock_popup_selected]->get_tab_count()) { + + dock_tab_move_left->set_disabled(dock_slot[dock_popup_selected]->get_current_tab()==0); + dock_tab_move_right->set_disabled(dock_slot[dock_popup_selected]->get_current_tab()>=dock_slot[dock_popup_selected]->get_tab_count()-1); + } + + for(int i=0;i<DOCK_SLOT_MAX;i++) { + + Vector2 ofs; + + switch(i) { + case DOCK_SLOT_LEFT_UL: { + + } break; + case DOCK_SLOT_LEFT_BL: { + ofs.y+=s.y; + } break; + case DOCK_SLOT_LEFT_UR: { + ofs.x+=s.x; + } break; + case DOCK_SLOT_LEFT_BR: { + ofs+=s; + } break; + case DOCK_SLOT_RIGHT_UL: { + ofs.x+=s.x*4; + } break; + case DOCK_SLOT_RIGHT_BL: { + ofs.x+=s.x*4; + ofs.y+=s.y; + + } break; + case DOCK_SLOT_RIGHT_UR: { + ofs.x+=s.x*4; + ofs.x+=s.x; + + } break; + case DOCK_SLOT_RIGHT_BR: { + ofs.x+=s.x*4; + ofs+=s; + + } break; + } + + Rect2 r(ofs,s); + dock_select_rect[i]=r; + r.pos+=Vector2(2,5); + r.size-=Vector2(4,7); + + + if (i==dock_select_rect_over) { + dock_select->draw_rect(r,used_selected); + } else if (dock_slot[i]->get_child_count()==0) { + dock_select->draw_rect(r,unused); + } else { + + dock_select->draw_rect(r,used); + } + + for(int j=0;j<MIN(3,dock_slot[i]->get_child_count());j++) { + int xofs = (r.size.width/3)*j; + Color c = used; + if (i==dock_popup_selected && (dock_slot[i]->get_current_tab()>3 || dock_slot[i]->get_current_tab()==j)) + c=tab_selected; + dock_select->draw_rect(Rect2(2+ofs.x+xofs,ofs.y,r.size.width/3-1,3),c); + } + + } +} + +void EditorNode::_save_docks() { + + Ref<ConfigFile> config; + config.instance(); + + for(int i=0;i<DOCK_SLOT_MAX;i++) { + String names; + for(int j=0;j<dock_slot[i]->get_tab_count();j++) { + String name = dock_slot[i]->get_tab_control(j)->get_name(); + if (names!="") + names+=","; + names+=name; + } + + if (names!="") { + config->set_value("docks","dock_"+itos(i+1),names); + } + } + + VSplitContainer*splits[DOCK_SLOT_MAX/2]={ + left_l_vsplit, + left_r_vsplit, + right_l_vsplit, + right_r_vsplit, + }; + + for(int i=0;i<DOCK_SLOT_MAX/2;i++) { + + if (splits[i]->is_visible()) { + config->set_value("docks","dock_split_"+itos(i+1),splits[i]->get_split_offset()); + } + } + + + HSplitContainer *h_splits[4]={ + left_l_hsplit, + left_r_hsplit, + main_hsplit, + right_hsplit, + }; + + for(int i=0;i<4;i++) { + + config->set_value("docks","dock_hsplit_"+itos(i+1),h_splits[i]->get_split_offset()); + } + + editor_data.get_plugin_window_layout(config); + + config->save(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg")); + +} + +void EditorNode::save_layout() { + + dock_drag_timer->start(); +} + +void EditorNode::_dock_split_dragged(int ofs) { + + dock_drag_timer->start(); +} + +void EditorNode::_load_docks() { + + Ref<ConfigFile> config; + config.instance(); + Error err = config->load(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg")); + if (err!=OK) { + return; //no config + } + + for(int i=0;i<DOCK_SLOT_MAX;i++) { + + if (!config->has_section_key("docks","dock_"+itos(i+1))) + continue; + + Vector<String> names = String(config->get_value("docks","dock_"+itos(i+1))).split(","); + + for(int j=0;j<names.size();j++) { + + String name=names[j]; + //find it, in a horribly inefficient way + int atidx=-1; + Control *node=NULL; + for(int k=0;k<DOCK_SLOT_MAX;k++) { + if (!dock_slot[k]->has_node(name)) + continue; + node=dock_slot[k]->get_node(name)->cast_to<Control>(); + if (!node) + continue; + atidx=k; + break; + } + if (atidx==-1) //well, it's not anywhere + continue; + + if (atidx==j) { + node->raise(); + continue; + } + + + dock_slot[atidx]->remove_child(node); + + if (dock_slot[atidx]->get_tab_count()==0) { + dock_slot[atidx]->hide(); + + } + dock_slot[i]->add_child(node); + dock_slot[i]->show(); + } + + } + + VSplitContainer*splits[DOCK_SLOT_MAX/2]={ + left_l_vsplit, + left_r_vsplit, + right_l_vsplit, + right_r_vsplit, + }; + + for(int i=0;i<DOCK_SLOT_MAX/2;i++) { + + if (!config->has_section_key("docks","dock_split_"+itos(i+1))) + continue; + + int ofs = config->get_value("docks","dock_split_"+itos(i+1)); + splits[i]->set_split_offset(ofs); + } + + HSplitContainer *h_splits[4]={ + left_l_hsplit, + left_r_hsplit, + main_hsplit, + right_hsplit, + }; + + for(int i=0;i<4;i++) { + if (!config->has_section_key("docks","dock_hsplit_"+itos(i+1))) + continue; + int ofs = config->get_value("docks","dock_hsplit_"+itos(i+1)); + h_splits[i]->set_split_offset(ofs); + } + + for(int i=0;i<DOCK_SLOT_MAX/2;i++) { + bool in_use = dock_slot[i*2+0]->get_tab_count() || dock_slot[i*2+1]->get_tab_count(); + if (in_use) + splits[i]->show(); + else + splits[i]->hide(); + } + + for(int i=0;i<DOCK_SLOT_MAX;i++) { + + if (!dock_slot[i]->is_hidden() && dock_slot[i]->get_tab_count()) { + dock_slot[i]->set_current_tab(0); + } + } + + editor_data.set_plugin_window_layout(config); + +} + + +void EditorNode::_scene_tab_changed(int p_tab) { + + + //print_line("set current 1 "); + bool unsaved = (saved_version!=editor_data.get_undo_redo().get_version()); + //print_line("version: "+itos(editor_data.get_undo_redo().get_version())+", saved "+itos(saved_version)); + + if (p_tab==editor_data.get_edited_scene()) + return; //pointless + + uint64_t next_scene_version = editor_data.get_scene_version(p_tab); + + + + //print_line("scene tab changed???"); + editor_data.get_undo_redo().create_action("Switch Scene Tab"); + editor_data.get_undo_redo().add_do_method(this,"set_current_version",unsaved?saved_version:0); + editor_data.get_undo_redo().add_do_method(this,"set_current_scene",p_tab); + editor_data.get_undo_redo().add_do_method(scene_tabs,"set_current_tab",p_tab); + editor_data.get_undo_redo().add_do_method(this,"set_current_version",next_scene_version==0?editor_data.get_undo_redo().get_version()+1:next_scene_version); + + editor_data.get_undo_redo().add_undo_method(this,"set_current_version",next_scene_version); + editor_data.get_undo_redo().add_undo_method(this,"set_current_scene",editor_data.get_edited_scene()); + editor_data.get_undo_redo().add_undo_method(scene_tabs,"set_current_tab",editor_data.get_edited_scene()); + editor_data.get_undo_redo().add_undo_method(this,"set_current_version",saved_version); + editor_data.get_undo_redo().commit_action(); + +} EditorNode::EditorNode() { EditorHelp::generate_doc(); //before any editor classes are crated singleton=this; + last_checked_version=0; + changing_scene=false; FileAccess::set_backup_save(true); @@ -3334,6 +4074,11 @@ EditorNode::EditorNode() { FileDialog::register_func=_file_dialog_register; FileDialog::unregister_func=_file_dialog_unregister; + EditorFileDialog::get_icon_func=_file_dialog_get_icon; + EditorFileDialog::register_func=_editor_file_dialog_register; + EditorFileDialog::unregister_func=_editor_file_dialog_unregister; + + editor_import_export = memnew( EditorImportExport ); add_child(editor_import_export); @@ -3358,6 +4103,9 @@ EditorNode::EditorNode() { editor_register_icons(theme); editor_register_fonts(theme); + //theme->set_icon("folder","EditorFileDialog",Theme::get_default()->get_icon("folder","EditorFileDialog")); + //theme->set_color("files_disabled","EditorFileDialog",Color(0,0,0,0.7)); + String global_font = EditorSettings::get_singleton()->get("global/font"); if (global_font!="") { Ref<Font> fnt = ResourceLoader::load(global_font); @@ -3376,6 +4124,8 @@ EditorNode::EditorNode() { theme->set_stylebox("EditorFocus","EditorStyles",focus_sbt); + resource_preview = memnew( EditorResourcePreview ); + add_child(resource_preview); progress_dialog = memnew( ProgressDialog ); gui_base->add_child(progress_dialog); @@ -3383,26 +4133,162 @@ EditorNode::EditorNode() { gui_base->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END ); gui_base->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_END ); gui_base->set_end( Point2(0,0) ); - + main_vbox = memnew( VBoxContainer ); gui_base->add_child(main_vbox); main_vbox->set_area_as_parent_rect(8); - menu_hb = memnew( HBoxContainer ); - main_vbox->add_child(menu_hb); + PanelContainer *top_dark_panel = memnew( PanelContainer ); + Ref<StyleBoxTexture> top_dark_sb; + top_dark_sb.instance();; + top_dark_sb->set_texture(theme->get_icon("PanelTop","EditorIcons")); + for(int i=0;i<4;i++) { + top_dark_sb->set_margin_size(Margin(i),3); + top_dark_sb->set_default_margin(Margin(i),0); + } + top_dark_sb->set_expand_margin_size(MARGIN_LEFT,20); + top_dark_sb->set_expand_margin_size(MARGIN_RIGHT,20); + + top_dark_panel->add_style_override("panel",top_dark_sb); + VBoxContainer *top_dark_vb = memnew( VBoxContainer ); + main_vbox->add_child(top_dark_panel); + top_dark_panel->add_child(top_dark_vb); + - main_split = memnew( HSplitContainer ); - main_vbox->add_child(main_split); - main_split->set_v_size_flags(Control::SIZE_EXPAND_FILL); - left_split = memnew( VSplitContainer ); - main_split->add_child(left_split); - left_split->set_h_size_flags(Control::SIZE_EXPAND_FILL); - left_split->set_collapsed(false); + menu_hb = memnew( HBoxContainer ); + top_dark_vb->add_child(menu_hb); + + scene_tabs=memnew( Tabs ); + scene_tabs->add_tab("unsaved"); + scene_tabs->set_tab_align(Tabs::ALIGN_CENTER); + scene_tabs->connect("tab_changed",this,"_scene_tab_changed"); + top_dark_vb->add_child(scene_tabs); + //left + left_l_hsplit = memnew( HSplitContainer ); + main_vbox->add_child(left_l_hsplit); + + left_l_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL); + + left_l_vsplit = memnew( VSplitContainer ); + left_l_hsplit->add_child(left_l_vsplit); + dock_slot[DOCK_SLOT_LEFT_UL]=memnew( TabContainer ); + left_l_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_UL]); + dock_slot[DOCK_SLOT_LEFT_BL]=memnew( TabContainer ); + left_l_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_BL]); + left_l_vsplit->hide(); + dock_slot[DOCK_SLOT_LEFT_UL]->hide(); + dock_slot[DOCK_SLOT_LEFT_BL]->hide(); + + left_r_hsplit = memnew( HSplitContainer ); + left_l_hsplit->add_child(left_r_hsplit); + left_r_vsplit = memnew( VSplitContainer ); + left_r_hsplit->add_child(left_r_vsplit); + dock_slot[DOCK_SLOT_LEFT_UR]=memnew( TabContainer ); + left_r_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_UR]); + dock_slot[DOCK_SLOT_LEFT_BR]=memnew( TabContainer ); + left_r_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_BR]); + //left_r_vsplit->hide(); + //dock_slot[DOCK_SLOT_LEFT_UR]->hide(); + //dock_slot[DOCK_SLOT_LEFT_BR]->hide(); + + + main_hsplit = memnew( HSplitContainer ); + left_r_hsplit->add_child(main_hsplit); + //main_split->set_v_size_flags(Control::SIZE_EXPAND_FILL); + + center_split = memnew( VSplitContainer ); + main_hsplit->add_child(center_split); + center_split->set_h_size_flags(Control::SIZE_EXPAND_FILL); + center_split->set_collapsed(false); + + right_hsplit = memnew( HSplitContainer ); + main_hsplit->add_child(right_hsplit); + + right_l_vsplit = memnew( VSplitContainer ); + right_hsplit->add_child(right_l_vsplit); + dock_slot[DOCK_SLOT_RIGHT_UL]=memnew( TabContainer ); + right_l_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_UL]); + dock_slot[DOCK_SLOT_RIGHT_BL]=memnew( TabContainer ); + right_l_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_BL]); + + right_r_vsplit = memnew( VSplitContainer ); + right_hsplit->add_child(right_r_vsplit); + dock_slot[DOCK_SLOT_RIGHT_UR]=memnew( TabContainer ); + right_r_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_UR]); + dock_slot[DOCK_SLOT_RIGHT_BR]=memnew( TabContainer ); + right_r_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_BR]); + right_r_vsplit->hide(); + //dock_slot[DOCK_SLOT_RIGHT_UL]->hide(); + //dock_slot[DOCK_SLOT_RIGHT_BL]->hide(); + + left_l_vsplit->connect("dragged",this,"_dock_split_dragged"); + left_r_vsplit->connect("dragged",this,"_dock_split_dragged"); + right_l_vsplit->connect("dragged",this,"_dock_split_dragged"); + right_r_vsplit->connect("dragged",this,"_dock_split_dragged"); + + left_l_hsplit->connect("dragged",this,"_dock_split_dragged"); + left_r_hsplit->connect("dragged",this,"_dock_split_dragged"); + main_hsplit->connect("dragged",this,"_dock_split_dragged"); + right_hsplit->connect("dragged",this,"_dock_split_dragged"); + + + + dock_select_popoup = memnew( PopupPanel ); + gui_base->add_child(dock_select_popoup); + VBoxContainer *dock_vb = memnew( VBoxContainer ); + dock_select_popoup->add_child(dock_vb); + + HBoxContainer *dock_hb = memnew( HBoxContainer); + dock_tab_move_left = memnew( ToolButton ); + dock_tab_move_left->set_icon(theme->get_icon("Back","EditorIcons")); + dock_tab_move_left->set_focus_mode(Control::FOCUS_NONE); + dock_tab_move_left->connect("pressed",this,"_dock_move_left"); + //dock_tab_move_left->set_h_size_flags(Control::SIZE_EXPAND_FILL); + dock_hb->add_child(dock_tab_move_left); + dock_hb->add_spacer(); + dock_tab_move_right = memnew( ToolButton ); + dock_tab_move_right->set_icon(theme->get_icon("Forward","EditorIcons")); + dock_tab_move_right->set_focus_mode(Control::FOCUS_NONE); + dock_tab_move_right->connect("pressed",this,"_dock_move_right"); + + //dock_tab_move_right->set_h_size_flags(Control::SIZE_EXPAND_FILL); + dock_hb->add_child(dock_tab_move_right); + dock_vb->add_child(dock_hb); + + dock_select = memnew( Control ); + dock_select->set_custom_minimum_size(Size2(128,64)); + dock_select->connect("input_event",this,"_dock_select_input"); + dock_select->connect("draw",this,"_dock_select_draw"); + dock_select->connect("mouse_exit",this,"_dock_popup_exit"); + dock_select->set_v_size_flags(Control::SIZE_EXPAND_FILL); + dock_vb->add_child(dock_select); + + + dock_select_popoup->set_child_rect(dock_vb); + dock_select_popoup->set_as_minsize(); + dock_select_rect_over=-1; + dock_popup_selected=-1; + //dock_select_popoup->set_(Size2(20,20)); + + for(int i=0;i<DOCK_SLOT_MAX;i++) { + dock_slot[i]->set_custom_minimum_size(Size2(250,250)); + dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL); + dock_slot[i]->set_popup(dock_select_popoup); + dock_slot[i]->connect("pre_popup_pressed",this,"_dock_pre_popup",varray(i)); + + //dock_slot[i]->set_tab_align(TabContainer::ALIGN_LEFT); + } + + dock_drag_timer = memnew( Timer ); + add_child(dock_drag_timer); + dock_drag_timer->set_wait_time(0.5); + dock_drag_timer->set_one_shot(true); + dock_drag_timer->connect("timeout",this,"_save_docks"); top_split = memnew( VSplitContainer ); - left_split->add_child(top_split); + center_split->add_child(top_split); top_split->set_v_size_flags(Control::SIZE_EXPAND_FILL); top_split->set_collapsed(true); @@ -3473,6 +4359,7 @@ EditorNode::EditorNode() { animation_panel=pc; animation_panel->hide(); + HBoxContainer *animation_hb = memnew( HBoxContainer); animation_vb->add_child(animation_hb); @@ -3536,7 +4423,9 @@ EditorNode::EditorNode() { p->add_item("Save Scene",FILE_SAVE_SCENE,KEY_MASK_CMD+KEY_S); p->add_item("Save Scene As..",FILE_SAVE_AS_SCENE,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_S); p->add_separator(); - p->add_item("Goto Prev. Scene",FILE_OPEN_PREV,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_P); + p->add_item("Close Scene",FILE_CLOSE,KEY_MASK_SHIFT+KEY_MASK_CTRL+KEY_W); + p->add_separator(); + p->add_item("Close Goto Prev. Scene",FILE_OPEN_PREV,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_P); p->add_submenu_item("Open Recent","RecentScenes",FILE_OPEN_RECENT); p->add_separator(); p->add_item("Quick Open Scene..",FILE_QUICK_OPEN_SCENE,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_O); @@ -3770,45 +4659,47 @@ EditorNode::EditorNode() { - editor_hsplit = memnew( HSplitContainer ); - main_split->add_child(editor_hsplit); - editor_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL); + //editor_hsplit = memnew( HSplitContainer ); + //main_split->add_child(editor_hsplit); + //editor_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL); - editor_vsplit = memnew( VSplitContainer ); - editor_hsplit->add_child(editor_vsplit); + //editor_vsplit = memnew( VSplitContainer ); + //editor_hsplit->add_child(editor_vsplit); - top_pallete = memnew( TabContainer ); + //top_pallete = memnew( TabContainer ); scene_tree_dock = memnew( SceneTreeDock(this,scene_root,editor_selection,editor_data) ); scene_tree_dock->set_name("Scene"); - top_pallete->add_child(scene_tree_dock); + //top_pallete->add_child(scene_tree_dock); + dock_slot[DOCK_SLOT_LEFT_UR]->add_child(scene_tree_dock); resources_dock = memnew( ResourcesDock(this) ); resources_dock->set_name("Resources"); - top_pallete->add_child(resources_dock); - top_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL); + //top_pallete->add_child(resources_dock); + dock_slot[DOCK_SLOT_RIGHT_BL]->add_child(resources_dock); + //top_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL); - Control *editor_spacer = memnew( Control ); + /*Control *editor_spacer = memnew( Control ); editor_spacer->set_custom_minimum_size(Size2(260,200)); editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL); editor_vsplit->add_child( editor_spacer ); editor_spacer->add_child( top_pallete ); - top_pallete->set_area_as_parent_rect(); + top_pallete->set_area_as_parent_rect();*/ - prop_pallete = memnew( TabContainer ); + //prop_pallete = memnew( TabContainer ); - prop_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL); + //prop_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL); - editor_spacer = memnew( Control ); + /*editor_spacer = memnew( Control ); editor_spacer->set_custom_minimum_size(Size2(260,200)); editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL); editor_vsplit->add_child( editor_spacer ); editor_spacer->add_child( prop_pallete ); - prop_pallete->set_area_as_parent_rect(); + prop_pallete->set_area_as_parent_rect();*/ VBoxContainer *prop_editor_base = memnew( VBoxContainer ); prop_editor_base->set_name("Inspector"); // Properties? - prop_pallete->add_child(prop_editor_base); + dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(prop_editor_base); HBoxContainer *prop_editor_hb = memnew( HBoxContainer ); prop_editor_base->add_child(prop_editor_hb); @@ -3850,14 +4741,15 @@ EditorNode::EditorNode() { scenes_dock = memnew( ScenesDock(this) ); scenes_dock->set_name("FileSystem"); - prop_pallete->add_child(scenes_dock); + dock_slot[DOCK_SLOT_LEFT_BR]->add_child(scenes_dock); + //prop_pallete->add_child(scenes_dock); scenes_dock->connect("open",this,"open_request"); scenes_dock->connect("instance",this,"_instance_request"); log = memnew( EditorLog ); - left_split->add_child(log); + center_split->add_child(log); log->connect("close_request",this,"_close_messages"); log->connect("show_request",this,"_show_messages"); //left_split->set_dragger_visible(false); @@ -3873,7 +4765,7 @@ EditorNode::EditorNode() { animation_vb->add_child(animation_editor); - left_split->connect("resized",this,"_vp_resized"); + center_split->connect("resized",this,"_vp_resized"); animation_editor->hide(); @@ -4031,7 +4923,7 @@ EditorNode::EditorNode() { file_templates->add_filter("*.tpz ; Template Package"); - file = memnew( FileDialog ); + file = memnew( EditorFileDialog ); gui_base->add_child(file); file->set_current_dir("res://"); @@ -4105,8 +4997,9 @@ EditorNode::EditorNode() { editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_TEXTURE_2D) ))); - editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_TEXTURE_3D) ))); editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_ATLAS) ))); + editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_LARGE) ))); + editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_TEXTURE_3D) ))); Ref<EditorSceneImportPlugin> _scene_import = memnew(EditorSceneImportPlugin(this) ); Ref<EditorSceneImporterCollada> _collada_import = memnew( EditorSceneImporterCollada); _scene_import->add_importer(_collada_import); @@ -4157,10 +5050,19 @@ EditorNode::EditorNode() { add_editor_plugin( memnew( Polygon2DEditorPlugin(this) ) ); add_editor_plugin( memnew( LightOccluder2DEditorPlugin(this) ) ); add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) ); + add_editor_plugin( memnew( ColorRampEditorPlugin(this) ) ); for(int i=0;i<EditorPlugins::get_plugin_count();i++) add_editor_plugin( EditorPlugins::create(i,this) ); + + resource_preview->add_preview_generator( Ref<EditorTexturePreviewPlugin>( memnew(EditorTexturePreviewPlugin ))); + resource_preview->add_preview_generator( Ref<EditorPackedScenePreviewPlugin>( memnew(EditorPackedScenePreviewPlugin ))); + resource_preview->add_preview_generator( Ref<EditorMaterialPreviewPlugin>( memnew(EditorMaterialPreviewPlugin ))); + resource_preview->add_preview_generator( Ref<EditorScriptPreviewPlugin>( memnew(EditorScriptPreviewPlugin ))); + resource_preview->add_preview_generator( Ref<EditorSamplePreviewPlugin>( memnew(EditorSamplePreviewPlugin ))); + resource_preview->add_preview_generator( Ref<EditorMeshPreviewPlugin>( memnew(EditorMeshPreviewPlugin ))); + circle_step_msec=OS::get_singleton()->get_ticks_msec(); circle_step_frame=OS::get_singleton()->get_frames_drawn();; circle_step=0; @@ -4213,8 +5115,8 @@ EditorNode::EditorNode() { } - edited_scene=NULL; - saved_version=0; + //edited_scene=NULL; + saved_version=1; unsaved_cache=true; _last_instanced_scene=NULL; @@ -4268,12 +5170,21 @@ EditorNode::EditorNode() { Node::set_human_readable_collision_renaming(true); + + // Ref<ImageTexture> it = gui_base->get_icon("logo","Icons"); // OS::get_singleton()->set_icon( it->get_data() ); for(int i=0;i<_init_callbacks.size();i++) _init_callbacks[i](); + editor_data.add_edited_scene(-1); + editor_data.set_edited_scene(0); + _update_scene_tabs(); + + _load_docks(); + + } diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 76e82b5a6b..293da2031d 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -78,7 +78,7 @@ #include "tools/editor/editor_plugin.h" #include "fileserver/editor_file_server.h" - +#include "editor_resource_preview.h" @@ -94,6 +94,8 @@ typedef void (*EditorNodeInitCallback)(); + + class EditorNode : public Node { OBJ_TYPE( EditorNode, Node ); @@ -123,6 +125,7 @@ class EditorNode : public Node { FILE_QUICK_OPEN_SCRIPT, FILE_RUN_SCRIPT, FILE_OPEN_PREV, + FILE_CLOSE, FILE_QUIT, FILE_EXTERNAL_OPEN_SCENE, EDIT_UNDO, @@ -168,19 +171,46 @@ class EditorNode : public Node { OBJECT_METHOD_BASE=500 }; + enum DockSlot { + DOCK_SLOT_LEFT_UL, + DOCK_SLOT_LEFT_BL, + DOCK_SLOT_LEFT_UR, + DOCK_SLOT_LEFT_BR, + DOCK_SLOT_RIGHT_UL, + DOCK_SLOT_RIGHT_BL, + DOCK_SLOT_RIGHT_UR, + DOCK_SLOT_RIGHT_BR, + DOCK_SLOT_MAX + }; - - Node *edited_scene; //scene being edited + //Node *edited_scene; //scene being edited Viewport *scene_root; //root of the scene being edited - Ref<ResourceImportMetadata> scene_import_metadata; + //Ref<ResourceImportMetadata> scene_import_metadata; Control* scene_root_parent; Control *gui_base; VBoxContainer *main_vbox; - HSplitContainer *main_split; - VSplitContainer *left_split; + + //split + + HSplitContainer *left_l_hsplit; + VSplitContainer *left_l_vsplit; + HSplitContainer *left_r_hsplit; + VSplitContainer *left_r_vsplit; + HSplitContainer *main_hsplit; + HSplitContainer *right_hsplit; + VSplitContainer *right_l_vsplit; + VSplitContainer *right_r_vsplit; + + VSplitContainer *center_split; + + //main tabs + + Tabs *scene_tabs; + + int old_split_ofs; VSplitContainer *top_split; HBoxContainer *bottom_hb; @@ -190,8 +220,9 @@ class EditorNode : public Node { TextureButton *anim_close; Panel *menu_panel; - HSplitContainer *editor_hsplit; - VSplitContainer *editor_vsplit; + + //HSplitContainer *editor_hsplit; + //VSplitContainer *editor_vsplit; HBoxContainer *menu_hb; Control *viewport; MenuButton *file_menu; @@ -238,7 +269,7 @@ class EditorNode : public Node { EditorSettingsDialog *settings_config_dialog; RunSettingsDialog *run_settings_dialog; ProjectSettings *project_settings; - FileDialog *file; + EditorFileDialog *file; FileDialog *file_templates; FileDialog *file_export; FileDialog *file_export_lib; @@ -249,8 +280,8 @@ class EditorNode : public Node { String current_path; MenuButton *update_menu; ToolButton *sources_button; - TabContainer *prop_pallete; - TabContainer *top_pallete; + //TabContainer *prop_pallete; + //TabContainer *top_pallete; String defer_load_scene; String defer_translatable; String defer_optimize; @@ -277,6 +308,16 @@ class EditorNode : public Node { ProgressDialog *progress_dialog; BackgroundProgress *progress_hb; + TabContainer *dock_slot[DOCK_SLOT_MAX]; + Rect2 dock_select_rect[DOCK_SLOT_MAX]; + int dock_select_rect_over; + PopupPanel *dock_select_popoup; + Control *dock_select; + ToolButton *dock_tab_move_left; + ToolButton *dock_tab_move_right; + int dock_popup_selected; + Timer *dock_drag_timer; + String _tmp_import_path; EditorImportExport *editor_import_export; @@ -287,8 +328,10 @@ class EditorNode : public Node { bool reference_resource_mem; bool save_external_resources_mem; uint64_t saved_version; + uint64_t last_checked_version; bool unsaved_cache; String open_navigate; + bool changing_scene; uint32_t circle_step_msec; uint64_t circle_step_frame; @@ -304,6 +347,7 @@ class EditorNode : public Node { EditorSelection *editor_selection; ProjectExport *project_export; ProjectExportDialog *project_export_settings; + EditorResourcePreview *resource_preview; EditorFileServer *file_server; @@ -337,6 +381,7 @@ class EditorNode : public Node { void _set_scene_metadata(); void _get_scene_metadata(); void _update_title(); + void _update_scene_tabs(); void _close_messages(); void _show_messages(); void _vp_resized(); @@ -348,7 +393,7 @@ class EditorNode : public Node { void _instance_request(const String& p_path); - void _property_keyed(const String& p_keyed,const Variant& p_value); + void _property_keyed(const String& p_keyed, const Variant& p_value, bool p_advance); void _transform_keyed(Object *sp,const String& p_sub,const Transform& p_key); void _update_keying(); @@ -364,7 +409,7 @@ class EditorNode : public Node { void _add_to_recent_scenes(const String& p_scene); void _update_recent_scenes(); void _open_recent_scene(int p_idx); - void _open_recent_scene_confirm(); + //void _open_recent_scene_confirm(); String _recent_scene; bool convert_old; @@ -381,19 +426,26 @@ class EditorNode : public Node { String import_reload_fn; Set<FileDialog*> file_dialogs; + Set<EditorFileDialog*> editor_file_dialogs; + Map<String,Ref<Texture> > icon_type_cache; static Ref<Texture> _file_dialog_get_icon(const String& p_path); static void _file_dialog_register(FileDialog *p_dialog); static void _file_dialog_unregister(FileDialog *p_dialog); + static void _editor_file_dialog_register(EditorFileDialog *p_dialog); + static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog); void _cleanup_scene(); - + void _remove_edited_scene(); bool _find_and_save_resource(RES p_res,Map<RES,bool>& processed,int32_t flags); bool _find_and_save_edited_subresources(Object *obj,Map<RES,bool>& processed,int32_t flags); void _save_edited_subresources(Node* scene,Map<RES,bool>& processed,int32_t flags); + void _find_node_types(Node* p_node, int&count_2d, int&count_3d); + void _save_scene_with_preview(String p_file); + struct ExportDefer { String platform; @@ -409,6 +461,20 @@ class EditorNode : public Node { bool _find_scene_in_use(Node* p_node,const String& p_path) const; + void _dock_select_input(const InputEvent& p_input); + void _dock_move_left(); + void _dock_move_right(); + void _dock_select_draw(); + void _dock_pre_popup(int p_which); + void _dock_split_dragged(int ofs); + void _dock_popup_exit(); + void _scene_tab_changed(int p_tab); + + Dictionary _get_main_scene_state(); + void _set_main_scene_state(Dictionary p_state); + + void _save_docks(); + void _load_docks(); protected: void _notification(int p_what); @@ -443,7 +509,7 @@ public: void open_request(const String& p_path); - void set_edited_scene(Node *p_scene); + bool is_changing_scene() const; static EditorLog *get_log() { return singleton->log; } @@ -456,7 +522,9 @@ public: void hide_animation_player_editors(); void animation_panel_make_visible(bool p_visible); - Node *get_edited_scene() { return edited_scene; } + void set_edited_scene(Node *p_scene); + + Node *get_edited_scene() { return editor_data.get_edited_scene_root(); } Viewport *get_scene_root() { return scene_root; } //root of the scene being edited Error save_optimized_copy(const String& p_scene,const String& p_preset); @@ -465,6 +533,9 @@ public: Error load_scene(const String& p_scene); Error load_resource(const String& p_scene); + void set_current_version(uint64_t p_version); + void set_current_scene(int p_idx); + static EditorData& get_editor_data() { return singleton->editor_data; } static VSplitContainer *get_top_split() { return singleton->top_split; } @@ -511,6 +582,9 @@ public: bool is_scene_in_use(const String& p_path); void scan_import_changes(); + + void save_layout(); + EditorNode(); ~EditorNode(); void get_singleton(const char* arg1, bool arg2); diff --git a/tools/editor/editor_plugin.cpp b/tools/editor/editor_plugin.cpp index e6b8ee0993..04c34d9a88 100644 --- a/tools/editor/editor_plugin.cpp +++ b/tools/editor/editor_plugin.cpp @@ -197,6 +197,13 @@ bool EditorPlugin::get_remove_list(List<Node*> *p_list) { void EditorPlugin::restore_global_state() {} void EditorPlugin::save_global_state() {} +void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) { + +} + +void EditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){ + +} void EditorPlugin::_bind_methods() { diff --git a/tools/editor/editor_plugin.h b/tools/editor/editor_plugin.h index a9e6b1be49..0f3a1e2e3c 100644 --- a/tools/editor/editor_plugin.h +++ b/tools/editor/editor_plugin.h @@ -32,7 +32,7 @@ #include "scene/main/node.h" #include "scene/resources/texture.h" #include "undo_redo.h" - +#include "io/config_file.h" /** @author Juan Linietsky <reduzio@gmail.com> */ @@ -90,6 +90,8 @@ public: virtual void apply_changes() ; // if changes are pending in editor, apply them virtual void get_breakpoints(List<String> *p_breakpoints); virtual bool get_remove_list(List<Node*> *p_list); + virtual void set_window_layout(Ref<ConfigFile> p_layout); + virtual void get_window_layout(Ref<ConfigFile> p_layout); virtual void restore_global_state(); virtual void save_global_state(); diff --git a/tools/editor/editor_resource_preview.cpp b/tools/editor/editor_resource_preview.cpp new file mode 100644 index 0000000000..f684b49a2c --- /dev/null +++ b/tools/editor/editor_resource_preview.cpp @@ -0,0 +1,261 @@ +#include "editor_resource_preview.h" +#include "editor_settings.h" +#include "os/file_access.h" +#include "io/resource_loader.h" +#include "io/resource_saver.h" +#include "globals.h" + + +Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String& p_path) { + + RES res = ResourceLoader::load(p_path); + if (!res.is_valid()) + return res; + return generate(res); +} + +EditorResourcePreviewGenerator::EditorResourcePreviewGenerator() { + + +} + + +EditorResourcePreview* EditorResourcePreview::singleton=NULL; + + +void EditorResourcePreview::_thread_func(void *ud) { + + EditorResourcePreview *erp=(EditorResourcePreview*)ud; + erp->_thread(); + +} + + +void EditorResourcePreview::_preview_ready(const String& p_str,const Ref<Texture>& p_texture,ObjectID id,const StringName& p_func,const Variant& p_ud) { + + //print_line("preview is ready"); + preview_mutex->lock(); + + Item item; + item.order=order++; + item.preview=p_texture; + cache[p_str]=item; + + Object *recv = ObjectDB::get_instance(id); + if (recv) { + recv->call_deferred(p_func,p_str,p_texture,p_ud); + } + + preview_mutex->unlock(); +} + +Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem& p_item,const String& cache_base) { + + String type = ResourceLoader::get_resource_type(p_item.path); + //print_line("resource type is: "+type); + + if (type=="") + return Ref<Texture>(); //could not guess type + + Ref<Texture> generated; + + for(int i=0;i<preview_generators.size();i++) { + if (!preview_generators[i]->handles(type)) + continue; + generated = preview_generators[i]->generate_from_path(p_item.path); + + break; + } + + if (generated.is_valid()) { + //print_line("was generated"); + int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); + //wow it generated a preview... save cache + ResourceSaver::save(cache_base+".png",generated); + FileAccess *f=FileAccess::open(cache_base+".txt",FileAccess::WRITE); + f->store_line(itos(thumbnail_size)); + f->store_line(itos(FileAccess::get_modified_time(p_item.path))); + f->store_line(FileAccess::get_md5(p_item.path)); + memdelete(f); + } else { + //print_line("was not generated"); + + } + + return generated; +} + +void EditorResourcePreview::_thread() { + + //print_line("begin thread"); + while(!exit) { + + //print_line("wait for semaphore"); + preview_sem->wait(); + preview_mutex->lock(); + + //print_line("blue team go"); + + if (queue.size()) { + + + + QueueItem item = queue.front()->get(); + queue.pop_front(); + preview_mutex->unlock(); + + Ref<Texture> texture; + + //print_line("pop from queue "+item.path); + + uint64_t modtime = FileAccess::get_modified_time(item.path); + int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); + + if (cache.has(item.path)) { + //already has it because someone loaded it, just let it know it's ready + call_deferred("_preview_ready",item.path,cache[item.path].preview,item.id,item.function,item.userdata); + + } else { + + + String temp_path=EditorSettings::get_singleton()->get_settings_path().plus_file("tmp"); + String cache_base = Globals::get_singleton()->globalize_path(item.path).md5_text(); + cache_base = temp_path.plus_file("resthumb-"+cache_base); + + //does not have it, try to load a cached thumbnail + + String file = cache_base+".txt"; + //print_line("cachetxt at "+file); + FileAccess *f=FileAccess::open(file,FileAccess::READ); + if (!f) { + + //print_line("generate because not cached"); + + //generate + texture=_generate_preview(item,cache_base); + } else { + + int tsize = f->get_line().to_int64(); + uint64_t last_modtime = f->get_line().to_int64(); + + bool cache_valid = true; + + if (tsize!=thumbnail_size) { + cache_valid=false; + memdelete(f); + } else if (last_modtime!=modtime) { + + String last_md5 = f->get_line(); + String md5 = FileAccess::get_md5(item.path); + memdelete(f); + + if (last_md5!=md5) { + + cache_valid=false; + } else { + //update modified time + + f=FileAccess::open(file,FileAccess::WRITE); + f->store_line(itos(modtime)); + f->store_line(md5); + memdelete(f); + } + } else { + memdelete(f); + } + + if (cache_valid) { + + texture = ResourceLoader::load(cache_base+".png","ImageTexture",true); + if (!texture.is_valid()) { + //well fuck + cache_valid=false; + } + } + + if (!cache_valid) { + + texture=_generate_preview(item,cache_base); + } + + } + + //print_line("notify of preview ready"); + call_deferred("_preview_ready",item.path,texture,item.id,item.function,item.userdata); + + } + + } else { + preview_mutex->unlock(); + } + + } +} + + + + +void EditorResourcePreview::queue_resource_preview(const String& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata) { + + ERR_FAIL_NULL(p_receiver); + preview_mutex->lock(); + if (cache.has(p_path)) { + cache[p_path].order=order++; + p_receiver->call_deferred(p_receiver_func,p_path,cache[p_path].preview,p_userdata); + preview_mutex->unlock(); + return; + + } + + //print_line("send to thread "+p_path); + QueueItem item; + item.function=p_receiver_func; + item.id=p_receiver->get_instance_ID(); + item.path=p_path; + item.userdata=p_userdata; + + queue.push_back(item); + preview_mutex->unlock(); + preview_sem->post(); + +} + +void EditorResourcePreview::add_preview_generator(const Ref<EditorResourcePreviewGenerator>& p_generator) { + + preview_generators.push_back(p_generator); +} + +EditorResourcePreview* EditorResourcePreview::get_singleton() { + + return singleton; +} + +void EditorResourcePreview::_bind_methods() { + + ObjectTypeDB::bind_method("_preview_ready",&EditorResourcePreview::_preview_ready); +} + +EditorResourcePreview::EditorResourcePreview() { + singleton=this; + preview_mutex = Mutex::create(); + preview_sem = Semaphore::create(); + order=0; + exit=false; + + thread = Thread::create(_thread_func,this); +} + + +EditorResourcePreview::~EditorResourcePreview() +{ + + exit=true; + preview_sem->post(); + Thread::wait_to_finish(thread); + memdelete(thread); + memdelete(preview_mutex); + memdelete(preview_sem); + + +} + diff --git a/tools/editor/editor_resource_preview.h b/tools/editor/editor_resource_preview.h new file mode 100644 index 0000000000..aadae75597 --- /dev/null +++ b/tools/editor/editor_resource_preview.h @@ -0,0 +1,95 @@ +#ifndef EDITORRESOURCEPREVIEW_H +#define EDITORRESOURCEPREVIEW_H + +#include "scene/main/node.h" +#include "os/semaphore.h" +#include "os/thread.h" +#include "scene/resources/texture.h" + +/* make previews for: +*packdscene +*wav +*image +*mesh +-font +*script +*material +-shader +-shader graph? +-navigation mesh +-collision? +-occluder polygon +-navigation polygon +-tileset +-curve and curve2D +*/ + + +class EditorResourcePreviewGenerator : public Reference { + + OBJ_TYPE(EditorResourcePreviewGenerator,Reference ); + +public: + + virtual bool handles(const String& p_type) const=0; + virtual Ref<Texture> generate(const RES& p_from)=0; + virtual Ref<Texture> generate_from_path(const String& p_path); + + EditorResourcePreviewGenerator(); +}; + + +class EditorResourcePreview : public Node { + + OBJ_TYPE(EditorResourcePreview,Node); + + + static EditorResourcePreview* singleton; + + struct QueueItem { + String path; + ObjectID id; + StringName function; + Variant userdata; + }; + + List<QueueItem> queue; + + Mutex *preview_mutex; + Semaphore *preview_sem; + Thread *thread; + bool exit; + + struct Item { + Ref<Texture> preview; + int order; + }; + + int order; + + Map<String,Item> cache; + + void _preview_ready(const String& p_str,const Ref<Texture>& p_texture, ObjectID id, const StringName &p_func, const Variant &p_ud); + Ref<Texture> _generate_preview(const QueueItem& p_item, const String &cache_base); + + static void _thread_func(void *ud); + void _thread(); + + Vector<Ref<EditorResourcePreviewGenerator> > preview_generators; +protected: + + static void _bind_methods(); +public: + + static EditorResourcePreview* get_singleton(); + + //callback funtion is callback(String p_path,Ref<Texture> preview,Variant udata) preview null if could not load + void queue_resource_preview(const String& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata); + + void add_preview_generator(const Ref<EditorResourcePreviewGenerator>& p_generator); + + EditorResourcePreview(); + ~EditorResourcePreview(); +}; + +#endif // EDITORRESOURCEPREVIEW_H diff --git a/tools/editor/editor_run_script.cpp b/tools/editor/editor_run_script.cpp index 5f8598d052..90581374f6 100644 --- a/tools/editor/editor_run_script.cpp +++ b/tools/editor/editor_run_script.cpp @@ -18,7 +18,7 @@ void EditorScript::add_root_node(Node *p_node) { return; } - editor->set_edited_scene(p_node); +// editor->set_edited_scene(p_node); } Node *EditorScript::get_scene() { diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index f49d3b496d..0df9fcadef 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -224,6 +224,28 @@ void EditorSettings::create() { dir->change_dir(".."); } + if (dir->change_dir("config")!=OK) { + dir->make_dir("config"); + } else { + + dir->change_dir(".."); + } + + dir->change_dir("config"); + + String pcp=Globals::get_singleton()->get_resource_path(); + if (pcp.ends_with("/")) + pcp=config_path.substr(0,pcp.size()-1); + pcp=pcp.get_file()+"-"+pcp.md5_text(); + + if (dir->change_dir(pcp)) { + dir->make_dir(pcp); + } else { + dir->change_dir(".."); + } + + dir->change_dir(".."); + // path at least is validated, so validate config file @@ -244,6 +266,7 @@ void EditorSettings::create() { } singleton->config_file_path=config_file_path; + singleton->project_config_path=pcp; singleton->settings_path=config_path+"/"+config_dir; if (OS::get_singleton()->is_stdout_verbose()) { @@ -251,7 +274,7 @@ void EditorSettings::create() { print_line("EditorSettings: Load OK!"); } - + singleton->load_favorites(); singleton->scan_plugins(); return; @@ -410,9 +433,11 @@ void EditorSettings::_load_defaults() { set("text_editor/idle_parse_delay",2); set("text_editor/create_signal_callbacks",true); set("text_editor/autosave_interval_secs",0); + set("text_editor/font",""); hints["text_editor/font"]=PropertyInfo(Variant::STRING,"text_editor/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt"); set("text_editor/auto_brace_complete", false); + set("text_editor/restore_scripts_on_load",true); set("scenetree_editor/duplicate_node_name_num_separator",0); @@ -448,6 +473,8 @@ void EditorSettings::_load_defaults() { set("text_editor/create_signal_callbacks",true); set("file_dialog/show_hidden_files", false); + set("file_dialog/thumbnail_size", 64); + hints["file_dialog/thumbnail_size"]=PropertyInfo(Variant::INT,"file_dialog/thumbnail_size",PROPERTY_HINT_RANGE,"32,128,16"); set("animation/autorename_animation_tracks",true); set("animation/confirm_insert_track",true); @@ -646,6 +673,71 @@ void EditorSettings::set_plugin_enabled(const String& p_plugin, bool p_enabled) } +void EditorSettings::set_favorite_dirs(const Vector<String>& p_favorites) { + + favorite_dirs=p_favorites; + FileAccess *f = FileAccess::open(get_project_settings_path().plus_file("favorite_dirs"),FileAccess::WRITE); + if (f) { + for(int i=0;i<favorite_dirs.size();i++) + f->store_line(favorite_dirs[i]); + memdelete(f); + } + +} + +Vector<String> EditorSettings::get_favorite_dirs() const { + + return favorite_dirs; +} + + +void EditorSettings::set_recent_dirs(const Vector<String>& p_recent) { + + recent_dirs=p_recent; + FileAccess *f = FileAccess::open(get_project_settings_path().plus_file("recent_dirs"),FileAccess::WRITE); + if (f) { + for(int i=0;i<recent_dirs.size();i++) + f->store_line(recent_dirs[i]); + memdelete(f); + } +} + +Vector<String> EditorSettings::get_recent_dirs() const { + + return recent_dirs; +} + +String EditorSettings::get_project_settings_path() const { + + + return get_settings_path().plus_file("config").plus_file(project_config_path); +} + + +void EditorSettings::load_favorites() { + + FileAccess *f = FileAccess::open(get_project_settings_path().plus_file("favorite_dirs"),FileAccess::READ); + if (f) { + String line = f->get_line().strip_edges(); + while(line!="") { + favorite_dirs.push_back(line); + line = f->get_line().strip_edges(); + } + memdelete(f); + } + + f = FileAccess::open(get_project_settings_path().plus_file("recent_dirs"),FileAccess::READ); + if (f) { + String line = f->get_line().strip_edges(); + while(line!="") { + recent_dirs.push_back(line); + line = f->get_line().strip_edges(); + } + memdelete(f); + } + +} + void EditorSettings::_bind_methods() { diff --git a/tools/editor/editor_settings.h b/tools/editor/editor_settings.h index 1594719a92..6b7e6eb989 100644 --- a/tools/editor/editor_settings.h +++ b/tools/editor/editor_settings.h @@ -88,6 +88,11 @@ private: void _load_defaults(); + String project_config_path; + + Vector<String> favorite_dirs; + Vector<String> recent_dirs; + protected: static void _bind_methods(); @@ -102,6 +107,7 @@ public: static EditorSettings *get_singleton(); void erase(String p_var); String get_settings_path() const; + String get_project_settings_path() const; const Map<String,Plugin>& get_plugins() const { return plugins; } @@ -125,6 +131,14 @@ public: void add_property_hint(const PropertyInfo& p_hint); + void set_favorite_dirs(const Vector<String>& p_favorite_dirs); + Vector<String> get_favorite_dirs() const; + + void set_recent_dirs(const Vector<String>& p_recent_dirs); + Vector<String> get_recent_dirs() const; + + void load_favorites(); + EditorSettings(); ~EditorSettings(); diff --git a/tools/editor/editor_sub_scene.cpp b/tools/editor/editor_sub_scene.cpp index 49385daeaa..2a6eba2554 100644 --- a/tools/editor/editor_sub_scene.cpp +++ b/tools/editor/editor_sub_scene.cpp @@ -215,7 +215,7 @@ EditorSubScene::EditorSubScene() { tree->set_v_size_flags(SIZE_EXPAND_FILL); vb->add_margin_child("Import From Node:",tree)->set_v_size_flags(SIZE_EXPAND_FILL); - file_dialog = memnew( FileDialog ); + file_dialog = memnew( EditorFileDialog ); List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); @@ -224,7 +224,7 @@ EditorSubScene::EditorSubScene() { file_dialog->add_filter("*."+E->get()); } - file_dialog->set_mode(FileDialog::MODE_OPEN_FILE); + file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); add_child(file_dialog); file_dialog->connect("file_selected",this,"_path_selected"); diff --git a/tools/editor/editor_sub_scene.h b/tools/editor/editor_sub_scene.h index 9d78dab2a2..dfd6c531e2 100644 --- a/tools/editor/editor_sub_scene.h +++ b/tools/editor/editor_sub_scene.h @@ -31,7 +31,7 @@ #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" -#include "scene/gui/file_dialog.h" +#include "tools/editor/editor_file_dialog.h" class EditorSubScene : public ConfirmationDialog { @@ -42,7 +42,7 @@ class EditorSubScene : public ConfirmationDialog { Tree *tree; Node *scene; - FileDialog *file_dialog; + EditorFileDialog *file_dialog; void _fill_tree(Node* p_node,TreeItem *p_parent); void _reown(Node* p_node,List<Node*> *p_to_reown); diff --git a/tools/editor/groups_editor.cpp b/tools/editor/groups_editor.cpp index ed76f54562..2e82854014 100644 --- a/tools/editor/groups_editor.cpp +++ b/tools/editor/groups_editor.cpp @@ -39,6 +39,9 @@ void GroupsEditor::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { connect("confirmed", this,"_close"); } + if (p_what==NOTIFICATION_EXIT_TREE) { + disconnect("confirmed", this,"_close"); + } } void GroupsEditor::_close() { diff --git a/tools/editor/icons/icon_arrow_left.png b/tools/editor/icons/icon_arrow_left.png Binary files differnew file mode 100644 index 0000000000..b72ac2a10d --- /dev/null +++ b/tools/editor/icons/icon_arrow_left.png diff --git a/tools/editor/icons/icon_arrow_left_disabled.png b/tools/editor/icons/icon_arrow_left_disabled.png Binary files differnew file mode 100644 index 0000000000..f1f9d0f988 --- /dev/null +++ b/tools/editor/icons/icon_arrow_left_disabled.png diff --git a/tools/editor/icons/icon_arrow_right.png b/tools/editor/icons/icon_arrow_right.png Binary files differnew file mode 100644 index 0000000000..d0a48b01ac --- /dev/null +++ b/tools/editor/icons/icon_arrow_right.png diff --git a/tools/editor/icons/icon_arrow_right_disabled.png b/tools/editor/icons/icon_arrow_right_disabled.png Binary files differnew file mode 100644 index 0000000000..840cd0da0a --- /dev/null +++ b/tools/editor/icons/icon_arrow_right_disabled.png diff --git a/tools/editor/icons/icon_arrow_up.png b/tools/editor/icons/icon_arrow_up.png Binary files differnew file mode 100644 index 0000000000..10aac0e0f6 --- /dev/null +++ b/tools/editor/icons/icon_arrow_up.png diff --git a/tools/editor/icons/icon_arrow_up_disabled.png b/tools/editor/icons/icon_arrow_up_disabled.png Binary files differnew file mode 100644 index 0000000000..fb46aa1373 --- /dev/null +++ b/tools/editor/icons/icon_arrow_up_disabled.png diff --git a/tools/editor/icons/icon_back_disabled.png b/tools/editor/icons/icon_back_disabled.png Binary files differnew file mode 100644 index 0000000000..31aab496e2 --- /dev/null +++ b/tools/editor/icons/icon_back_disabled.png diff --git a/tools/editor/icons/icon_color_ramp.png b/tools/editor/icons/icon_color_ramp.png Binary files differnew file mode 100644 index 0000000000..9031b5ec53 --- /dev/null +++ b/tools/editor/icons/icon_color_ramp.png diff --git a/tools/editor/icons/icon_curve_constant.png b/tools/editor/icons/icon_curve_constant.png Binary files differnew file mode 100644 index 0000000000..cdeac1785e --- /dev/null +++ b/tools/editor/icons/icon_curve_constant.png diff --git a/tools/editor/icons/icon_curve_in.png b/tools/editor/icons/icon_curve_in.png Binary files differnew file mode 100644 index 0000000000..2db202632e --- /dev/null +++ b/tools/editor/icons/icon_curve_in.png diff --git a/tools/editor/icons/icon_curve_in_out.png b/tools/editor/icons/icon_curve_in_out.png Binary files differnew file mode 100644 index 0000000000..f4cb593496 --- /dev/null +++ b/tools/editor/icons/icon_curve_in_out.png diff --git a/tools/editor/icons/icon_curve_linear.png b/tools/editor/icons/icon_curve_linear.png Binary files differnew file mode 100644 index 0000000000..9467dc97a3 --- /dev/null +++ b/tools/editor/icons/icon_curve_linear.png diff --git a/tools/editor/icons/icon_curve_out.png b/tools/editor/icons/icon_curve_out.png Binary files differnew file mode 100644 index 0000000000..c91ade6f4a --- /dev/null +++ b/tools/editor/icons/icon_curve_out.png diff --git a/tools/editor/icons/icon_curve_out_in.png b/tools/editor/icons/icon_curve_out_in.png Binary files differnew file mode 100644 index 0000000000..6499fa753e --- /dev/null +++ b/tools/editor/icons/icon_curve_out_in.png diff --git a/tools/editor/icons/icon_favorites.png b/tools/editor/icons/icon_favorites.png Binary files differindex da4713d032..4a3b575f95 100644 --- a/tools/editor/icons/icon_favorites.png +++ b/tools/editor/icons/icon_favorites.png diff --git a/tools/editor/icons/icon_file_big.png b/tools/editor/icons/icon_file_big.png Binary files differnew file mode 100644 index 0000000000..887a4ee05c --- /dev/null +++ b/tools/editor/icons/icon_file_big.png diff --git a/tools/editor/icons/icon_file_list.png b/tools/editor/icons/icon_file_list.png Binary files differnew file mode 100644 index 0000000000..e5e9213e61 --- /dev/null +++ b/tools/editor/icons/icon_file_list.png diff --git a/tools/editor/icons/icon_file_thumbnail.png b/tools/editor/icons/icon_file_thumbnail.png Binary files differnew file mode 100644 index 0000000000..c32be5e8f8 --- /dev/null +++ b/tools/editor/icons/icon_file_thumbnail.png diff --git a/tools/editor/icons/icon_folder_big.png b/tools/editor/icons/icon_folder_big.png Binary files differnew file mode 100644 index 0000000000..988e070f98 --- /dev/null +++ b/tools/editor/icons/icon_folder_big.png diff --git a/tools/editor/icons/icon_item_list.png b/tools/editor/icons/icon_item_list.png Binary files differnew file mode 100644 index 0000000000..f930e7ecaa --- /dev/null +++ b/tools/editor/icons/icon_item_list.png diff --git a/tools/editor/icons/icon_key_next.png b/tools/editor/icons/icon_key_next.png Binary files differnew file mode 100644 index 0000000000..759008d064 --- /dev/null +++ b/tools/editor/icons/icon_key_next.png diff --git a/tools/editor/icons/icon_panel_top.png b/tools/editor/icons/icon_panel_top.png Binary files differnew file mode 100644 index 0000000000..20e67fad1a --- /dev/null +++ b/tools/editor/icons/icon_panel_top.png diff --git a/tools/editor/icons/icon_pause.png b/tools/editor/icons/icon_pause.png Binary files differindex e63661353c..7c0a57003e 100644 --- a/tools/editor/icons/icon_pause.png +++ b/tools/editor/icons/icon_pause.png diff --git a/tools/editor/icons/icon_play.png b/tools/editor/icons/icon_play.png Binary files differindex 08cce495a9..d2bd9d310c 100644 --- a/tools/editor/icons/icon_play.png +++ b/tools/editor/icons/icon_play.png diff --git a/tools/editor/icons/icon_play_backwards.png b/tools/editor/icons/icon_play_backwards.png Binary files differnew file mode 100644 index 0000000000..8dff5f20e3 --- /dev/null +++ b/tools/editor/icons/icon_play_backwards.png diff --git a/tools/editor/icons/icon_play_start.png b/tools/editor/icons/icon_play_start.png Binary files differnew file mode 100644 index 0000000000..5b085aa1ed --- /dev/null +++ b/tools/editor/icons/icon_play_start.png diff --git a/tools/editor/icons/icon_play_start_backwards.png b/tools/editor/icons/icon_play_start_backwards.png Binary files differnew file mode 100644 index 0000000000..09afac637c --- /dev/null +++ b/tools/editor/icons/icon_play_start_backwards.png diff --git a/tools/editor/icons/icon_remove.png b/tools/editor/icons/icon_remove.png Binary files differindex 10e56d5bb8..f0f814e304 100644 --- a/tools/editor/icons/icon_remove.png +++ b/tools/editor/icons/icon_remove.png diff --git a/tools/editor/icons/icon_remove_small.png b/tools/editor/icons/icon_remove_small.png Binary files differnew file mode 100644 index 0000000000..e0903689cf --- /dev/null +++ b/tools/editor/icons/icon_remove_small.png diff --git a/tools/editor/icons/icon_stop.png b/tools/editor/icons/icon_stop.png Binary files differindex fd568b61a8..0fd43b403a 100644 --- a/tools/editor/icons/icon_stop.png +++ b/tools/editor/icons/icon_stop.png diff --git a/tools/editor/icons/icon_tab_menu.png b/tools/editor/icons/icon_tab_menu.png Binary files differnew file mode 100644 index 0000000000..29edd02f01 --- /dev/null +++ b/tools/editor/icons/icon_tab_menu.png diff --git a/tools/editor/icons/icon_wait_no_preview.png b/tools/editor/icons/icon_wait_no_preview.png Binary files differnew file mode 100644 index 0000000000..5d20cd99ec --- /dev/null +++ b/tools/editor/icons/icon_wait_no_preview.png diff --git a/tools/editor/icons/icon_wait_preview_1.png b/tools/editor/icons/icon_wait_preview_1.png Binary files differnew file mode 100644 index 0000000000..0aab42e04a --- /dev/null +++ b/tools/editor/icons/icon_wait_preview_1.png diff --git a/tools/editor/icons/icon_wait_preview_2.png b/tools/editor/icons/icon_wait_preview_2.png Binary files differnew file mode 100644 index 0000000000..f476b9ce1f --- /dev/null +++ b/tools/editor/icons/icon_wait_preview_2.png diff --git a/tools/editor/icons/icon_wait_preview_3.png b/tools/editor/icons/icon_wait_preview_3.png Binary files differnew file mode 100644 index 0000000000..2775d1ef43 --- /dev/null +++ b/tools/editor/icons/icon_wait_preview_3.png diff --git a/tools/editor/icons/icon_wait_preview_4.png b/tools/editor/icons/icon_wait_preview_4.png Binary files differnew file mode 100644 index 0000000000..2eaa86fec9 --- /dev/null +++ b/tools/editor/icons/icon_wait_preview_4.png diff --git a/tools/editor/icons/icon_wait_preview_5.png b/tools/editor/icons/icon_wait_preview_5.png Binary files differnew file mode 100644 index 0000000000..6590644bc1 --- /dev/null +++ b/tools/editor/icons/icon_wait_preview_5.png diff --git a/tools/editor/icons/icon_wait_preview_6.png b/tools/editor/icons/icon_wait_preview_6.png Binary files differnew file mode 100644 index 0000000000..307e412310 --- /dev/null +++ b/tools/editor/icons/icon_wait_preview_6.png diff --git a/tools/editor/icons/icon_wait_preview_7.png b/tools/editor/icons/icon_wait_preview_7.png Binary files differnew file mode 100644 index 0000000000..b0edc94d93 --- /dev/null +++ b/tools/editor/icons/icon_wait_preview_7.png diff --git a/tools/editor/icons/icon_wait_preview_8.png b/tools/editor/icons/icon_wait_preview_8.png Binary files differnew file mode 100644 index 0000000000..67a2f48ec3 --- /dev/null +++ b/tools/editor/icons/icon_wait_preview_8.png diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp index 375333ddf6..10a3877529 100644 --- a/tools/editor/io_plugins/editor_font_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp @@ -28,7 +28,7 @@ /*************************************************************************/ #include "editor_font_import_plugin.h" #include "scene/gui/dialogs.h" -#include "scene/gui/file_dialog.h" +#include "tools/editor/editor_file_dialog.h" #include "tools/editor/editor_node.h" #include "os/file_access.h" #include "editor_atlas.h" @@ -379,8 +379,8 @@ class EditorFontImportDialog : public ConfirmationDialog { OBJ_TYPE(EditorFontImportDialog, ConfirmationDialog); - LineEditFileChooser *source; - LineEditFileChooser *dest; + EditorLineEditFileChooser *source; + EditorLineEditFileChooser *dest; SpinBox *font_size; LineEdit *test_string; ColorPickerButton *test_color; @@ -612,9 +612,9 @@ public: hbc->add_child(vbr); vbr->set_h_size_flags(SIZE_EXPAND_FILL); - source = memnew( LineEditFileChooser ); - source->get_file_dialog()->set_access(FileDialog::ACCESS_FILESYSTEM); - source->get_file_dialog()->set_mode(FileDialog::MODE_OPEN_FILE); + source = memnew( EditorLineEditFileChooser ); + source->get_file_dialog()->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + source->get_file_dialog()->set_mode(EditorFileDialog::MODE_OPEN_FILE); source->get_file_dialog()->add_filter("*.ttf;TrueType"); source->get_file_dialog()->add_filter("*.otf;OpenType"); source->get_line_edit()->connect("text_entered",this,"_src_changed"); @@ -626,7 +626,7 @@ public: font_size->set_max(256); font_size->set_val(16); font_size->connect("value_changed",this,"_font_size_changed"); - dest = memnew( LineEditFileChooser ); + dest = memnew( EditorLineEditFileChooser ); // List<String> fl; Ref<Font> font= memnew(Font); diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp index 7d6f400ccc..2139513025 100644 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp @@ -1,6 +1,6 @@ #include "editor_mesh_import_plugin.h" -#include "scene/gui/file_dialog.h" +#include "tools/editor/editor_file_dialog.h" #include "tools/editor/editor_dir_dialog.h" #include "tools/editor/editor_node.h" #include "tools/editor/property_editor.h" @@ -105,7 +105,7 @@ public: _EditorMeshImportOptions() { generate_tangents=true; - generate_normals=true; + generate_normals=false; flip_faces=false; smooth_shading=false; weld_vertices=true; @@ -126,7 +126,7 @@ class EditorMeshImportDialog : public ConfirmationDialog { LineEdit *import_path; LineEdit *save_path; - FileDialog *file_select; + EditorFileDialog *file_select; EditorDirDialog *save_select; ConfirmationDialog *error_dialog; PropertyEditor *option_editor; @@ -300,16 +300,16 @@ public: save_choose->connect("pressed", this,"_browse_target"); - file_select = memnew(FileDialog); - file_select->set_access(FileDialog::ACCESS_FILESYSTEM); + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - file_select->set_mode(FileDialog::MODE_OPEN_FILES); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); file_select->connect("files_selected", this,"_choose_files"); file_select->add_filter("*.obj ; Wavefront OBJ"); save_select = memnew( EditorDirDialog ); add_child(save_select); - // save_select->set_mode(FileDialog::MODE_OPEN_DIR); + // save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); save_select->connect("dir_selected", this,"_choose_save_dir"); get_ok()->connect("pressed", this,"_import"); diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.cpp b/tools/editor/io_plugins/editor_sample_import_plugin.cpp index d1fe10df03..9491f957c3 100644 --- a/tools/editor/io_plugins/editor_sample_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_sample_import_plugin.cpp @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "editor_sample_import_plugin.h" -#include "scene/gui/file_dialog.h" +#include "tools/editor/editor_file_dialog.h" #include "tools/editor/editor_dir_dialog.h" #include "tools/editor/editor_node.h" #include "tools/editor/property_editor.h" @@ -171,7 +171,7 @@ class EditorSampleImportDialog : public ConfirmationDialog { LineEdit *import_path; LineEdit *save_path; - FileDialog *file_select; + EditorFileDialog *file_select; EditorDirDialog *save_select; ConfirmationDialog *error_dialog; PropertyEditor *option_editor; @@ -363,16 +363,16 @@ public: save_choose->connect("pressed", this,"_browse_target"); - file_select = memnew(FileDialog); - file_select->set_access(FileDialog::ACCESS_FILESYSTEM); + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - file_select->set_mode(FileDialog::MODE_OPEN_FILES); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); file_select->connect("files_selected", this,"_choose_files"); file_select->add_filter("*.wav ; MS Waveform"); save_select = memnew( EditorDirDialog ); add_child(save_select); - // save_select->set_mode(FileDialog::MODE_OPEN_DIR); + // save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); save_select->connect("dir_selected", this,"_choose_save_dir"); get_ok()->connect("pressed", this,"_import"); @@ -610,6 +610,7 @@ Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceI dst_format=Sample::FORMAT_IMA_ADPCM; _compress_ima_adpcm(data,dst_data); + print_line("compressing ima-adpcm, resulting buffersize is "+itos(dst_data.size())+" from "+itos(data.size())); } else { @@ -755,10 +756,10 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D prev+=vpdiff ; if (prev > 32767) { - printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev); + //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev); prev=32767; } else if (prev < -32768) { - printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev); + //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev); prev = -32768 ; } diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp index 3fb4b06f3c..99dcf4ed28 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp @@ -162,8 +162,8 @@ class EditorSceneImportDialog : public ConfirmationDialog { LineEdit *save_path; LineEdit *script_path; Tree *import_options; - FileDialog *file_select; - FileDialog *script_select; + EditorFileDialog *file_select; + EditorFileDialog *script_select; EditorDirDialog *save_select; OptionButton *texture_action; @@ -1079,19 +1079,19 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce vbc->set_v_size_flags(SIZE_EXPAND_FILL); vbc->add_margin_child("Options:",import_options,true); - file_select = memnew(FileDialog); - file_select->set_access(FileDialog::ACCESS_FILESYSTEM); + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - file_select->set_mode(FileDialog::MODE_OPEN_FILE); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); file_select->connect("file_selected", this,"_choose_file"); save_select = memnew(EditorDirDialog); add_child(save_select); - //save_select->set_mode(FileDialog::MODE_SAVE_FILE); + //save_select->set_mode(EditorFileDialog::MODE_SAVE_FILE); save_select->connect("dir_selected", this,"_choose_save_file"); get_ok()->connect("pressed", this,"_import"); @@ -1140,7 +1140,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce script_choose->connect("pressed", this,"_browse_script"); - script_select = memnew(FileDialog); + script_select = memnew(EditorFileDialog); add_child(script_select); for(int i=0;i<ScriptServer::get_language_count();i++) { @@ -1152,7 +1152,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce } - script_select->set_mode(FileDialog::MODE_OPEN_FILE); + script_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); script_select->connect("file_selected", this,"_choose_script"); @@ -2638,8 +2638,11 @@ void EditorSceneImportPlugin::_filter_tracks(Node *scene, const String& p_text) for(Set<String>::Element *F=keep_local.front();F;F=F->next()) { keep.insert(F->get()); } - + print_line("FILTERING ANIM: "+String(E->get())); _filter_anim_tracks(anim->get_animation(name),keep); + } else { + print_line("NOT FILTERING ANIM: "+String(E->get())); + } } diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index 3add30d81e..4f7ec1839a 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -144,6 +144,8 @@ void EditorImportTextureOptions::_changed() { void EditorImportTextureOptions::_bind_methods() { + print_line("bind toptions"); + ObjectTypeDB::bind_method("_changed",&EditorImportTextureOptions::_changed); ObjectTypeDB::bind_method("_changedp",&EditorImportTextureOptions::_changedp); @@ -219,7 +221,6 @@ EditorImportTextureOptions::EditorImportTextureOptions() { fname++; } - add_margin_child("Texture Options",flags,true); notice_for_2d = memnew( Label ); @@ -247,17 +248,20 @@ class EditorTextureImportDialog : public ConfirmationDialog { LineEdit *import_path; LineEdit *save_path; - FileDialog *file_select; - FileDialog *save_file_select; + EditorFileDialog *file_select; + EditorFileDialog *save_file_select; EditorDirDialog *save_select; OptionButton *texture_action; ConfirmationDialog *error_dialog; CheckButton *crop_source; + SpinBox *size; bool atlas; + bool large; EditorTextureImportPlugin *plugin; void _choose_files(const Vector<String>& p_path); + void _choose_file(const String& p_path); void _choose_save_dir(const String& p_path); void _browse(); void _browse_target(); @@ -272,7 +276,7 @@ public: Error import(const String& p_from, const String& p_to, const String& p_preset); void popup_import(const String &p_from=String()); - EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL,bool p_2d=false,bool p_atlas=false); + EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL,bool p_2d=false,bool p_atlas=false,bool p_large=false); }; @@ -301,6 +305,15 @@ void EditorTextureImportDialog::_choose_files(const Vector<String>& p_path) { import_path->set_text(files); } + + + +void EditorTextureImportDialog::_choose_file(const String& p_path) { + + + import_path->set_text(p_path); + +} void EditorTextureImportDialog::_choose_save_dir(const String& p_path) { save_path->set_text(p_path); @@ -336,7 +349,7 @@ void EditorTextureImportDialog::_import() { } - if (!atlas && !DirAccess::exists(save_path->get_text())) { + if (!atlas && !large && !DirAccess::exists(save_path->get_text())) { error_dialog->set_text("Target path must exist."); error_dialog->popup_centered_minsize(); return; @@ -362,6 +375,8 @@ void EditorTextureImportDialog::_import() { imd->set_option("flags",texture_options->get_flags()); imd->set_option("quality",texture_options->get_quality()); imd->set_option("atlas",true); + imd->set_option("atlas_size",int(size->get_val())); + imd->set_option("large",false); imd->set_option("crop",crop_source->is_pressed()); Error err = plugin->import(dst_file,imd); @@ -372,7 +387,38 @@ void EditorTextureImportDialog::_import() { return; } + } else if (large) { //atlas + + if (files.size()!=1) { + + error_dialog->set_text("Only one file is required for large texture"); + error_dialog->popup_centered(Size2(200,100)); + return; + + } + String dst_file = dst_path; + //dst_file=dst_file.basename()+".tex"; + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + //imd->set_editor(); + for(int i=0;i<files.size();i++) { + imd->add_source(EditorImportPlugin::validate_source_path(files[i])); + } + imd->set_option("format",texture_options->get_format()); + imd->set_option("flags",texture_options->get_flags()); + imd->set_option("quality",texture_options->get_quality()); + imd->set_option("atlas",false); + imd->set_option("large",true); + imd->set_option("large_cell_size",int(size->get_val())); + imd->set_option("crop",crop_source->is_pressed()); + Error err = plugin->import(dst_file,imd); + if (err) { + + error_dialog->set_text("Error importing: "+dst_file.get_file()); + error_dialog->popup_centered(Size2(200,100)); + return; + + } } else { @@ -387,6 +433,8 @@ void EditorTextureImportDialog::_import() { imd->set_option("flags",texture_options->get_flags()); imd->set_option("quality",texture_options->get_quality()); imd->set_option("atlas",false); + imd->set_option("large",false); + Error err = plugin->import(dst_file,imd); if (err) { @@ -408,7 +456,7 @@ void EditorTextureImportDialog::_browse() { void EditorTextureImportDialog::_browse_target() { - if (atlas) { + if (atlas || large) { save_file_select->popup_centered_ratio(); } else { save_select->popup_centered_ratio(); @@ -424,7 +472,7 @@ void EditorTextureImportDialog::popup_import(const String& p_from) { Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); ERR_FAIL_COND(!rimd.is_valid()); - if (plugin->get_mode()==EditorTextureImportPlugin::MODE_ATLAS) + if (plugin->get_mode()==EditorTextureImportPlugin::MODE_ATLAS || plugin->get_mode()==EditorTextureImportPlugin::MODE_LARGE) save_path->set_text(p_from); else save_path->set_text(p_from.get_base_dir()); @@ -474,6 +522,7 @@ void EditorTextureImportDialog::_bind_methods() { ObjectTypeDB::bind_method("_choose_files",&EditorTextureImportDialog::_choose_files); + ObjectTypeDB::bind_method("_choose_file",&EditorTextureImportDialog::_choose_file); ObjectTypeDB::bind_method("_choose_save_dir",&EditorTextureImportDialog::_choose_save_dir); ObjectTypeDB::bind_method("_import",&EditorTextureImportDialog::_import); ObjectTypeDB::bind_method("_browse",&EditorTextureImportDialog::_browse); @@ -481,21 +530,25 @@ void EditorTextureImportDialog::_bind_methods() { // ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); } -EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin, bool p_2d, bool p_atlas) { +EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin, bool p_2d, bool p_atlas,bool p_large) { atlas=p_atlas; + large=p_large; plugin=p_plugin; set_title("Import Textures"); - texture_options = memnew( EditorImportTextureOptions );; - VBoxContainer *vbc = texture_options; + + VBoxContainer *vbc = memnew(VBoxContainer); add_child(vbc); set_child_rect(vbc); VBoxContainer *source_vb=memnew(VBoxContainer); - vbc->add_margin_child("Source Texture(s):",source_vb); + if (large) + vbc->add_margin_child("Source Texture:",source_vb); + else + vbc->add_margin_child("Source Texture(s):",source_vb); HBoxContainer *hbc = memnew( HBoxContainer ); source_vb->add_child(hbc); @@ -510,6 +563,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* if (!p_atlas) crop_source->hide(); + Button * import_choose = memnew( Button ); import_choose->set_text(" .. "); hbc->add_child(import_choose); @@ -519,6 +573,19 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* hbc = memnew( HBoxContainer ); vbc->add_margin_child("Target Path:",hbc); + size = memnew( SpinBox ); + size->set_min(128); + size->set_max(16384); + + if (p_atlas) { + size->set_val(2048); + vbc->add_margin_child("Max Texture size:",size); + } else { + size->set_val(256); + vbc->add_margin_child("Cell Size:",size); + } + + save_path = memnew( LineEdit ); save_path->set_h_size_flags(SIZE_EXPAND_FILL); hbc->add_child(save_path); @@ -529,32 +596,39 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* save_choose->connect("pressed", this,"_browse_target"); - file_select = memnew(FileDialog); - file_select->set_access(FileDialog::ACCESS_FILESYSTEM); + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - file_select->set_mode(FileDialog::MODE_OPEN_FILES); + if (!large) + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); + else + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); file_select->connect("files_selected", this,"_choose_files"); + file_select->connect("file_selected", this,"_choose_file"); - save_file_select = memnew(FileDialog); - save_file_select->set_access(FileDialog::ACCESS_RESOURCES); + save_file_select = memnew(EditorFileDialog); + save_file_select->set_access(EditorFileDialog::ACCESS_RESOURCES); add_child(save_file_select); - save_file_select->set_mode(FileDialog::MODE_SAVE_FILE); + save_file_select->set_mode(EditorFileDialog::MODE_SAVE_FILE); save_file_select->clear_filters(); - save_file_select->add_filter("*.tex;Base Atlas Texture"); + if (large) + save_file_select->add_filter("*.ltex;Large Texture"); + else + save_file_select->add_filter("*.tex;Base Atlas Texture"); save_file_select->connect("file_selected", this,"_choose_save_dir"); save_select = memnew( EditorDirDialog ); add_child(save_select); -// save_select->set_mode(FileDialog::MODE_OPEN_DIR); +// save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); save_select->connect("dir_selected", this,"_choose_save_dir"); get_ok()->connect("pressed", this,"_import"); get_ok()->set_text("Import"); //move stuff up - for(int i=0;i<4;i++) - vbc->move_child( vbc->get_child( vbc->get_child_count() -1), 0); + //for(int i=0;i<4;i++) + // vbc->move_child( vbc->get_child( vbc->get_child_count() -1), 0); error_dialog = memnew ( ConfirmationDialog ); add_child(error_dialog); @@ -563,13 +637,24 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* set_hide_on_ok(false); + texture_options = memnew( EditorImportTextureOptions );; + vbc->add_child(texture_options); + texture_options->set_v_size_flags(SIZE_EXPAND_FILL); + if (atlas) { texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); texture_options->set_quality(0.7); texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); - texture_options->show_2d_notice(); + //texture_options->show_2d_notice(); set_title("Import Textures for Atlas (2D)"); + } else if (large) { + + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); + texture_options->set_quality(0.7); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); + texture_options->show_2d_notice(); + set_title("Import Large Textures (2D)"); } else if (p_2d) { @@ -615,12 +700,17 @@ String EditorTextureImportPlugin::get_name() const { return "texture_atlas"; } break; + case MODE_LARGE: { + + return "texture_large"; + } break; } return ""; } + String EditorTextureImportPlugin::get_visible_name() const { switch(mode) { @@ -635,7 +725,11 @@ String EditorTextureImportPlugin::get_visible_name() const { } break; case MODE_ATLAS: { - return "Atlas Texture"; + return "2D Atlas Texture"; + } break; + case MODE_LARGE: { + + return "2D Large Texture"; } break; } @@ -733,6 +827,135 @@ Error EditorTextureImportPlugin::import(const String& p_path, const Ref<Resource return import2(p_path,p_from,EditorExportPlatform::IMAGE_COMPRESSION_BC,false); } + +Error EditorTextureImportPlugin::_process_texture_data(Ref<ImageTexture> &texture,int format, float quality,int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,int shrink) { + + + if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS || format==IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { + + Image image=texture->get_data(); + ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); + + bool has_alpha=image.detect_alpha(); + if (!has_alpha && image.get_format()==Image::FORMAT_RGBA) { + + image.convert(Image::FORMAT_RGB); + + } + + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { + + image.fix_alpha_edges(); + } + + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + + if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { + image.normalmap_to_xy(); + } + + //if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { + + // image.srgb_to_linear(); + //} + + if (shrink>1) { + + int orig_w=image.get_width(); + int orig_h=image.get_height(); + image.resize(orig_w/shrink,orig_h/shrink); + texture->create_from_image(image,tex_flags); + texture->set_size_override(Size2(orig_w,orig_h)); + + + } else { + + texture->create_from_image(image,tex_flags); + } + + + if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS) { + texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSLESS); + } else { + texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY); + } + + + + texture->set_lossy_storage_quality(quality); + + + } else { + + + Image image=texture->get_data(); + ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); + + + bool has_alpha=image.detect_alpha(); + if (!has_alpha && image.get_format()==Image::FORMAT_RGBA) { + + image.convert(Image::FORMAT_RGB); + + } + + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { + + image.fix_alpha_edges(); + } + + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + + if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { + image.normalmap_to_xy(); + } + + //if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { +// + // print_line("CONVERT BECAUSE: "+itos(flags)); + // image.srgb_to_linear(); + //} + + int orig_w=image.get_width(); + int orig_h=image.get_height(); + + if (shrink>1) { + image.resize(orig_w/shrink,orig_h/shrink); + texture->create_from_image(image,tex_flags); + texture->set_size_override(Size2(orig_w,orig_h)); + } + + if (!(flags&IMAGE_FLAG_NO_MIPMAPS)) { + image.generate_mipmaps(); + + } + + if (format!=IMAGE_FORMAT_UNCOMPRESSED) { + + compress_image(p_compr,image,flags&IMAGE_FLAG_COMPRESS_EXTRA); + } + + + texture->create_from_image(image,tex_flags); + + + if (shrink>1 || (format!=IMAGE_FORMAT_UNCOMPRESSED && (image.get_width()!=orig_w || image.get_height()!=orig_h))) { + texture->set_size_override(Size2(orig_w,orig_h)); + } + + //uint32_t save_flags=ResourceSaver::FLAG_COMPRESS; + } + + return OK; +} + + Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<ResourceImportMetadata>& p_from,EditorExportPlatform::ImageCompression p_compr, bool p_external){ @@ -744,8 +967,11 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc Ref<ImageTexture> texture; Vector<Ref<AtlasTexture> > atlases; bool atlas = from->get_option("atlas"); + bool large = from->get_option("large"); int flags=from->get_option("flags"); + int format=from->get_option("format"); + float quality=from->get_option("quality"); uint32_t tex_flags=0; @@ -765,7 +991,80 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc if (from->has_option("shrink")) shrink=from->get_option("shrink"); - if (atlas) { + if (large) { + ERR_FAIL_COND_V(from->get_source_count()!=1,ERR_INVALID_PARAMETER); + + String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); + + + int cell_size=from->get_option("large_cell_size"); + ERR_FAIL_COND_V(cell_size<128 || cell_size>16384,ERR_CANT_OPEN); + + EditorProgress pg("ltex","Import Large Texture",3); + + pg.step("Load Source Image",0); + Image img; + Error err = ImageLoader::load_image(src_path,&img); + if (err) { + return err; + } + + pg.step("Slicing",1); + + Map<Vector2,Image> pieces; + for(int i=0;i<img.get_width();i+=cell_size) { + int w = MIN(img.get_width()-i,cell_size); + for(int j=0;j<img.get_height();j+=cell_size) { + int h = MIN(img.get_height()-j,cell_size); + + Image piece(w,h,0,img.get_format()); + piece.blit_rect(img,Rect2(i,j,w,h),Point2(0,0)); + if (!piece.is_invisible()) { + pieces[Vector2(i,j)]=piece; + //print_line("ADDING PIECE AT "+Vector2(i,j)); + } + } + } + + Ref<LargeTexture> existing; + if (ResourceCache::has(p_path)) { + existing = ResourceCache::get(p_path); + } + + if (existing.is_valid()) { + existing->clear(); + } else { + existing = Ref<LargeTexture>(memnew( LargeTexture )); + } + + existing->set_size(Size2(img.get_width(),img.get_height())); + pg.step("Inserting",2); + + for (Map<Vector2,Image>::Element *E=pieces.front();E;E=E->next()) { + + Ref<ImageTexture> imgtex = Ref<ImageTexture>( memnew( ImageTexture ) ); + imgtex->create_from_image(E->get(),tex_flags); + _process_texture_data(imgtex,format,quality,flags,p_compr,tex_flags,shrink); + existing->add_piece(E->key(),imgtex); + } + + if (!p_external) { + from->set_editor(get_name()); + existing->set_path(p_path); + existing->set_import_metadata(from); + } + pg.step("Saving",3); + + err = ResourceSaver::save(p_path,existing); + if (err!=OK) { + EditorNode::add_io_error("Couldn't save large texture: "+p_path); + return err; + } + + return OK; + + + } else if (atlas) { //prepare atlas! Vector< Image > sources; @@ -897,8 +1196,6 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc } - int format=from->get_option("format"); - float quality=from->get_option("quality"); if (!p_external) { from->set_editor(get_name()); @@ -932,7 +1229,11 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc } } + bool compress=false; +#if 1 + _process_texture_data(texture,format,quality,flags,p_compr,tex_flags,shrink); +#else if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS || format==IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { Image image=texture->get_data(); @@ -989,13 +1290,6 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc texture->set_lossy_storage_quality(quality); - Error err = ResourceSaver::save(p_path,texture); - - if (err!=OK) { - EditorNode::add_io_error("Couldn't save converted texture: "+p_path); - return err; - } - } else { @@ -1058,15 +1352,20 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc texture->set_size_override(Size2(orig_w,orig_h)); } - uint32_t save_flags=ResourceSaver::FLAG_COMPRESS; + compress=true; - Error err = ResourceSaver::save(p_path,texture,save_flags); - if (err!=OK) { - EditorNode::add_io_error("Couldn't save converted texture: "+p_path); - return err; - } } +#endif + uint32_t save_flags=0; + if (compress) + save_flags=ResourceSaver::FLAG_COMPRESS; + + Error err = ResourceSaver::save(p_path,texture,save_flags); + if (err!=OK) { + EditorNode::add_io_error("Couldn't save converted texture: "+p_path); + return err; + } return OK; } @@ -1255,14 +1554,14 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c } -EditorTextureImportPlugin *EditorTextureImportPlugin::singleton[3]={NULL,NULL,NULL}; +EditorTextureImportPlugin *EditorTextureImportPlugin::singleton[EditorTextureImportPlugin::MODE_MAX]={NULL,NULL,NULL,NULL}; EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor, Mode p_mode) { singleton[p_mode]=this; editor=p_editor; - mode=p_mode; - dialog = memnew( EditorTextureImportDialog(this,p_mode==MODE_TEXTURE_2D || p_mode==MODE_ATLAS,p_mode==MODE_ATLAS) ); + mode=p_mode; + dialog = memnew( EditorTextureImportDialog(this,p_mode==MODE_TEXTURE_2D || p_mode==MODE_ATLAS || p_mode==MODE_LARGE,p_mode==MODE_ATLAS,p_mode==MODE_LARGE) ); editor->get_gui_base()->add_child(dialog); } diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h index 5cd36e838e..02d09d9e17 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ b/tools/editor/io_plugins/editor_texture_import_plugin.h @@ -56,7 +56,9 @@ public: enum Mode { MODE_TEXTURE_2D, MODE_TEXTURE_3D, - MODE_ATLAS + MODE_ATLAS, + MODE_LARGE, + MODE_MAX }; @@ -65,10 +67,10 @@ private: Mode mode; EditorNode *editor; EditorTextureImportDialog *dialog; - static EditorTextureImportPlugin *singleton[3]; + static EditorTextureImportPlugin *singleton[MODE_MAX]; //used by other importers such as mesh - + Error _process_texture_data(Ref<ImageTexture> &texture, int format, float quality, int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,int shrink); void compress_image(EditorExportPlatform::ImageCompression p_mode,Image& image,bool p_smaller); public: diff --git a/tools/editor/io_plugins/editor_translation_import_plugin.cpp b/tools/editor/io_plugins/editor_translation_import_plugin.cpp index 6d59b52fb5..d152d71af4 100644 --- a/tools/editor/io_plugins/editor_translation_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_translation_import_plugin.cpp @@ -47,7 +47,7 @@ class EditorTranslationImportDialog : public ConfirmationDialog { LineEdit *import_path; LineEdit *save_path; - FileDialog *file_select; + EditorFileDialog *file_select; CheckButton *ignore_first; CheckButton *compress; CheckButton *add_to_project; @@ -347,16 +347,16 @@ public: add_to_project->set_text("Add to Project (engine.cfg)"); tcomp->add_child(add_to_project); - file_select = memnew(FileDialog); - file_select->set_access(FileDialog::ACCESS_FILESYSTEM); + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - file_select->set_mode(FileDialog::MODE_OPEN_FILE); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); file_select->connect("file_selected", this,"_choose_file"); file_select->add_filter("*.csv ; Translation CSV"); save_select = memnew( EditorDirDialog ); add_child(save_select); - // save_select->set_mode(FileDialog::MODE_OPEN_DIR); + // save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); save_select->connect("dir_selected", this,"_choose_save_dir"); get_ok()->connect("pressed", this,"_import"); diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp index fee2f4f977..05b12543d2 100644 --- a/tools/editor/plugins/animation_player_editor_plugin.cpp +++ b/tools/editor/plugins/animation_player_editor_plugin.cpp @@ -28,7 +28,8 @@ /*************************************************************************/ #include "animation_player_editor_plugin.h" #include "io/resource_loader.h" - +#include "os/keyboard.h" +#include "tools/editor/editor_settings.h" void AnimationPlayerEditor::_node_removed(Node *p_node) { @@ -97,15 +98,21 @@ void AnimationPlayerEditor::_notification(int p_what) { duplicate_anim->set_icon( get_icon("Duplicate","EditorIcons") ); autoplay->set_icon( get_icon("AutoPlay","EditorIcons") ); load_anim->set_icon( get_icon("Folder","EditorIcons") ); - remove_anim->set_icon( get_icon("Del","EditorIcons") ); + remove_anim->set_icon( get_icon("Remove","EditorIcons") ); edit_anim->set_icon( get_icon("Edit","EditorIcons") ); blend_anim->set_icon( get_icon("Blend","EditorIcons") ); - play->set_icon( get_icon("Play","EditorIcons") ); + play->set_icon( get_icon("PlayStart","EditorIcons") ); + play_from->set_icon( get_icon("Play","EditorIcons") ); + play_bw->set_icon( get_icon("PlayStartBackwards","EditorIcons") ); + play_bw_from->set_icon( get_icon("PlayBackwards","EditorIcons") ); + autoplay_icon=get_icon("AutoPlay","EditorIcons"); stop->set_icon( get_icon("Stop","EditorIcons") ); resource_edit_anim->set_icon( get_icon("EditResource","EditorIcons") ); pin->set_normal_texture(get_icon("Pin","EditorIcons") ); pin->set_pressed_texture( get_icon("PinPressed","EditorIcons") ); + tool_anim->set_icon(get_icon("Tools","EditorIcons")); + tool_anim->get_popup()->connect("item_pressed",this,"_animation_tool_menu"); blend_editor.next->connect("text_changed",this,"_blend_editor_next_changed"); @@ -180,9 +187,82 @@ void AnimationPlayerEditor::_play_pressed() { //unpause //pause->set_pressed(false); } + +void AnimationPlayerEditor::_play_from_pressed() { + + String current; + if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { + + current = animation->get_item_text( animation->get_selected() ); + } + + if (current!="") { + + float time = player->get_current_animation_pos(); + + if (current==player->get_current_animation() && player->is_playing()) { + + player->stop(); //so it wont blend with itself + } + + player->play( current ); + player->seek(time); + } + + //unstop + stop->set_pressed(false); + //unpause + //pause->set_pressed(false); +} + + +void AnimationPlayerEditor::_play_bw_pressed() { + + String current; + if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { + + current = animation->get_item_text( animation->get_selected() ); + } + + if (current!="") { + + if (current==player->get_current_animation()) + player->stop(); //so it wont blend with itself + player->play(current,-1,-1,true); + } + + //unstop + stop->set_pressed(false); + //unpause + //pause->set_pressed(false); +} + +void AnimationPlayerEditor::_play_bw_from_pressed() { + + String current; + if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { + + current = animation->get_item_text( animation->get_selected() ); + } + + if (current!="") { + + float time = player->get_current_animation_pos(); + if (current==player->get_current_animation()) + player->stop(); //so it wont blend with itself + + player->play(current,-1,-1,true); + player->seek(time); + } + + //unstop + stop->set_pressed(false); + //unpause + //pause->set_pressed(false); +} void AnimationPlayerEditor::_stop_pressed() { - player->stop(); + player->stop(false); play->set_pressed(false); stop->set_pressed(true); //pause->set_pressed(false); @@ -275,7 +355,7 @@ void AnimationPlayerEditor::_animation_rename() { } void AnimationPlayerEditor::_animation_load() { ERR_FAIL_COND(!player); - file->set_mode( FileDialog::MODE_OPEN_FILE ); + file->set_mode( EditorFileDialog::MODE_OPEN_FILE ); file->clear_filters(); List<String> extensions; @@ -598,6 +678,9 @@ void AnimationPlayerEditor::_update_player() { stop->set_disabled(animlist.size()==0); play->set_disabled(animlist.size()==0); + play_bw->set_disabled(animlist.size()==0); + play_bw_from->set_disabled(animlist.size()==0); + play_from->set_disabled(animlist.size()==0); autoplay->set_disabled(animlist.size()==0); duplicate_anim->set_disabled(animlist.size()==0); rename_anim->set_disabled(animlist.size()==0); @@ -877,11 +960,108 @@ void AnimationPlayerEditor::_hide_anim_editors() { } } + +void AnimationPlayerEditor::_animation_tool_menu(int p_option) { + + switch(p_option) { + + case TOOL_COPY_ANIM: { + + if (!animation->get_item_count()) { + error_dialog->set_text("ERROR: No animation to copy!"); + error_dialog->popup_centered_minsize(); + return; + } + + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + //editor->edit_resource(anim); + EditorSettings::get_singleton()->set_resource_clipboard(anim); + + } break; + case TOOL_PASTE_ANIM: { + + Ref<Animation> anim = EditorSettings::get_singleton()->get_resource_clipboard(); + if (!anim.is_valid()) { + error_dialog->set_text("ERROR: No animation resource on clipboard!"); + error_dialog->popup_centered_minsize(); + return; + } + + String name = anim->get_name(); + if (name=="") { + name="Pasted Animation"; + } + + int idx=1; + String base = name; + while (player->has_animation(name)) { + + idx++; + name=base+" "+itos(idx); + } + + undo_redo->create_action("Paste Animation"); + undo_redo->add_do_method(player,"add_animation",name,anim); + undo_redo->add_undo_method(player,"remove_animation",name); + undo_redo->add_do_method(this,"_animation_player_changed",player); + undo_redo->add_undo_method(this,"_animation_player_changed",player); + undo_redo->commit_action(); + + _select_anim_by_name(name); + + + } break; + case TOOL_EDIT_RESOURCE: { + + if (!animation->get_item_count()) { + error_dialog->set_text("ERROR: No animation to edit!"); + error_dialog->popup_centered_minsize(); + return; + } + + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + editor->edit_resource(anim); + + } break; + + } +} + +void AnimationPlayerEditor::_unhandled_key_input(const InputEvent& p_ev) { + + if (is_visible() && p_ev.type==InputEvent::KEY && p_ev.key.pressed && !p_ev.key.echo && !p_ev.key.mod.alt && !p_ev.key.mod.control && !p_ev.key.mod.meta) { + + switch(p_ev.key.scancode) { + + case KEY_A: { + if (!p_ev.key.mod.shift) + _play_bw_from_pressed(); + else + _play_bw_pressed(); + } break; + case KEY_S: { + _stop_pressed(); + } break; + case KEY_D: { + if (!p_ev.key.mod.shift) + _play_from_pressed(); + else + _play_pressed(); + } break; + } + } +} + void AnimationPlayerEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&AnimationPlayerEditor::_input_event); ObjectTypeDB::bind_method(_MD("_node_removed"),&AnimationPlayerEditor::_node_removed); ObjectTypeDB::bind_method(_MD("_play_pressed"),&AnimationPlayerEditor::_play_pressed); + ObjectTypeDB::bind_method(_MD("_play_from_pressed"),&AnimationPlayerEditor::_play_from_pressed); + ObjectTypeDB::bind_method(_MD("_play_bw_pressed"),&AnimationPlayerEditor::_play_bw_pressed); + ObjectTypeDB::bind_method(_MD("_play_bw_from_pressed"),&AnimationPlayerEditor::_play_bw_from_pressed); ObjectTypeDB::bind_method(_MD("_stop_pressed"),&AnimationPlayerEditor::_stop_pressed); ObjectTypeDB::bind_method(_MD("_autoplay_pressed"),&AnimationPlayerEditor::_autoplay_pressed); ObjectTypeDB::bind_method(_MD("_pause_pressed"),&AnimationPlayerEditor::_pause_pressed); @@ -908,6 +1088,8 @@ void AnimationPlayerEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_hide_anim_editors"),&AnimationPlayerEditor::_hide_anim_editors); ObjectTypeDB::bind_method(_MD("_animation_duplicate"),&AnimationPlayerEditor::_animation_duplicate); ObjectTypeDB::bind_method(_MD("_blend_editor_next_changed"),&AnimationPlayerEditor::_blend_editor_next_changed); + ObjectTypeDB::bind_method(_MD("_unhandled_key_input"),&AnimationPlayerEditor::_unhandled_key_input); + ObjectTypeDB::bind_method(_MD("_animation_tool_menu"),&AnimationPlayerEditor::_animation_tool_menu); @@ -935,47 +1117,56 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { add_child(hb); - add_anim = memnew( Button ); + add_anim = memnew( ToolButton ); add_anim->set_tooltip("Create new animation in player."); hb->add_child(add_anim); - - load_anim = memnew( Button ); + load_anim = memnew( ToolButton ); load_anim->set_tooltip("Load an animation from disk."); hb->add_child(load_anim); - duplicate_anim = memnew( Button ); + duplicate_anim = memnew( ToolButton ); hb->add_child(duplicate_anim); duplicate_anim->set_tooltip("Duplicate Animation"); + rename_anim = memnew( ToolButton ); + hb->add_child(rename_anim); + rename_anim->set_tooltip("Rename Animation"); + + remove_anim = memnew( ToolButton ); + + hb->add_child(remove_anim); + remove_anim->set_tooltip("Remove Animation"); + + animation = memnew( OptionButton ); hb->add_child(animation); animation->set_h_size_flags(SIZE_EXPAND_FILL); animation->set_tooltip("Display list of animations in player."); - autoplay = memnew( Button ); + autoplay = memnew( ToolButton ); hb->add_child(autoplay); autoplay->set_tooltip("Autoplay On Load"); - rename_anim = memnew( Button ); - hb->add_child(rename_anim); - rename_anim->set_tooltip("Rename Animation"); - - remove_anim = memnew( Button ); - - hb->add_child(remove_anim); - remove_anim->set_tooltip("Remove Animation"); - blend_anim = memnew( Button ); + blend_anim = memnew( ToolButton ); hb->add_child(blend_anim); blend_anim->set_tooltip("Edit Target Blend Times"); + tool_anim = memnew( MenuButton); + //tool_anim->set_flat(false); + tool_anim->set_tooltip("Animation Tools"); + tool_anim->get_popup()->add_item("Copy Animation",TOOL_COPY_ANIM); + tool_anim->get_popup()->add_item("Paste Animation",TOOL_PASTE_ANIM); + //tool_anim->get_popup()->add_separator(); + //tool_anim->get_popup()->add_item("Edit Anim Resource",TOOL_PASTE_ANIM); + hb->add_child(tool_anim); - edit_anim = memnew( Button ); + edit_anim = memnew( ToolButton ); edit_anim->set_toggle_mode(true); hb->add_child(edit_anim); edit_anim->set_tooltip("Open animation editor.\nProperty editor will displays all editable keys too."); @@ -984,15 +1175,29 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { hb = memnew (HBoxContainer); add_child(hb); - play = memnew( Button ); - play->set_tooltip("Play selected animation."); + play_bw_from = memnew( ToolButton ); + play_bw_from->set_tooltip("Play backwards selected animation from current pos. (A)"); + hb->add_child(play_bw_from); - hb->add_child(play); + play_bw = memnew( ToolButton ); + play_bw->set_tooltip("Play backwards selected animation from end. (Shift+A)"); + hb->add_child(play_bw); - stop = memnew( Button ); + stop = memnew( ToolButton ); stop->set_toggle_mode(true); hb->add_child(stop); - play->set_tooltip("Stop animation playback."); + stop->set_tooltip("Stop animation playback. (S)"); + + play = memnew( ToolButton ); + play->set_tooltip("Play selected animation from start. (Shift+D)"); + hb->add_child(play); + + + play_from = memnew( ToolButton ); + play_from->set_tooltip("Play selected animation from current pos. (D)"); + hb->add_child(play_from); + + //pause = memnew( Button ); //pause->set_toggle_mode(true); @@ -1024,9 +1229,10 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { resource_edit_anim= memnew( Button ); hb->add_child(resource_edit_anim); + resource_edit_anim->hide(); - file = memnew(FileDialog); + file = memnew(EditorFileDialog); add_child(file); name_dialog = memnew( ConfirmationDialog ); @@ -1074,7 +1280,10 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { autoplay->connect("pressed", this,"_autoplay_pressed"); autoplay->set_toggle_mode(true); - play->connect("pressed", this,"_play_pressed"); + play->connect("pressed", this,"_play_pressed"); + play_from->connect("pressed", this,"_play_from_pressed"); + play_bw->connect("pressed", this,"_play_bw_pressed"); + play_bw_from->connect("pressed", this,"_play_bw_from_pressed"); stop->connect("pressed", this,"_stop_pressed"); //pause->connect("pressed", this,"_pause_pressed"); add_anim->connect("pressed", this,"_animation_new"); @@ -1104,6 +1313,8 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { renaming=false; last_active=false; + + set_process_unhandled_key_input(true); } diff --git a/tools/editor/plugins/animation_player_editor_plugin.h b/tools/editor/plugins/animation_player_editor_plugin.h index 380dfd1903..9f0413088d 100644 --- a/tools/editor/plugins/animation_player_editor_plugin.h +++ b/tools/editor/plugins/animation_player_editor_plugin.h @@ -49,10 +49,19 @@ class AnimationPlayerEditor : public VBoxContainer { EditorNode *editor; AnimationPlayer *player; + enum { + TOOL_COPY_ANIM, + TOOL_PASTE_ANIM, + TOOL_EDIT_RESOURCE + }; OptionButton *animation; Button *stop; Button *play; + Button *play_from; + Button *play_bw; + Button *play_bw_from; + // Button *pause; Button *add_anim; Button *autoplay; @@ -63,6 +72,7 @@ class AnimationPlayerEditor : public VBoxContainer { Button *load_anim; Button *blend_anim; Button *remove_anim; + MenuButton *tool_anim; TextureButton *pin; Label *nodename; SpinBox *frame; @@ -74,7 +84,7 @@ class AnimationPlayerEditor : public VBoxContainer { Ref<Texture> autoplay_icon; bool last_active; - FileDialog *file; + EditorFileDialog *file; struct BlendEditor { @@ -95,6 +105,9 @@ class AnimationPlayerEditor : public VBoxContainer { void _select_anim_by_name(const String& p_anim); void _play_pressed(); + void _play_from_pressed(); + void _play_bw_pressed(); + void _play_bw_from_pressed(); void _autoplay_pressed(); void _stop_pressed(); void _pause_pressed(); @@ -126,6 +139,8 @@ class AnimationPlayerEditor : public VBoxContainer { void _animation_key_editor_seek(float p_pos); void _animation_key_editor_anim_len_changed(float p_new); + void _unhandled_key_input(const InputEvent& p_ev); + void _animation_tool_menu(int p_option); AnimationPlayerEditor(); protected: diff --git a/tools/editor/plugins/animation_tree_editor_plugin.cpp b/tools/editor/plugins/animation_tree_editor_plugin.cpp index 2df9377daf..382bc44726 100644 --- a/tools/editor/plugins/animation_tree_editor_plugin.cpp +++ b/tools/editor/plugins/animation_tree_editor_plugin.cpp @@ -1193,7 +1193,7 @@ void AnimationTreeEditor::_add_menu_item(int p_item) { } else if (p_item == MENU_IMPORT_ANIMATIONS) { file_op = MENU_IMPORT_ANIMATIONS; - file_dialog->set_mode(FileDialog::MODE_OPEN_FILE); + file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); file_dialog->popup_centered_ratio(); } else { @@ -1458,7 +1458,7 @@ AnimationTreeEditor::AnimationTreeEditor() { edit_check->hide();; edit_check->connect("pressed", this,"_edit_dialog_changed"); - file_dialog = memnew( FileDialog ); + file_dialog = memnew( EditorFileDialog ); file_dialog->set_enable_multiple_selection(true); file_dialog->set_current_dir(Globals::get_singleton()->get_resource_path()); add_child(file_dialog); diff --git a/tools/editor/plugins/animation_tree_editor_plugin.h b/tools/editor/plugins/animation_tree_editor_plugin.h index beb67c7196..bd29530c7a 100644 --- a/tools/editor/plugins/animation_tree_editor_plugin.h +++ b/tools/editor/plugins/animation_tree_editor_plugin.h @@ -79,7 +79,7 @@ class AnimationTreeEditor : public Control { Button *edit_button; Button *filter_button; CheckButton *edit_check; - FileDialog* file_dialog; + EditorFileDialog* file_dialog; int file_op; void _popup_edit_dialog(); diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index fef5890f11..f2738f0a62 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -150,8 +150,56 @@ void CanvasItemEditor::_unhandled_key_input(const InputEvent& p_ev) { _tool_select(TOOL_MOVE); if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_E) _tool_select(TOOL_ROTATE); - if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_V && drag==DRAG_ALL && can_move_pivot) - drag=DRAG_PIVOT; + if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_V && drag==DRAG_NONE && can_move_pivot) { + if (p_ev.key.mod.shift) { + //move drag pivot + drag=DRAG_PIVOT; + } else if (!Input::get_singleton()->is_mouse_button_pressed(0)) { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + Vector2 mouse_pos = viewport->get_local_mouse_pos(); + if (selection.size() && viewport->get_rect().has_point(mouse_pos)) { + //just in case, make it work if over viewport + mouse_pos=transform.affine_inverse().xform(mouse_pos); + mouse_pos=snap_point(mouse_pos); + + undo_redo->create_action("Move Pivot"); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Node2D *n2d = E->get()->cast_to<Node2D>(); + + if (n2d && n2d->edit_has_pivot()) { + + Vector2 offset = n2d->edit_get_pivot(); + Vector2 gpos = n2d->get_global_pos(); + + Vector2 motion_ofs = gpos-mouse_pos; + + undo_redo->add_do_method(n2d,"set_global_pos",mouse_pos); + undo_redo->add_do_method(n2d,"edit_set_pivot",offset+n2d->get_global_transform().affine_inverse().basis_xform(motion_ofs)); + undo_redo->add_undo_method(n2d,"set_global_pos",gpos); + undo_redo->add_undo_method(n2d,"edit_set_pivot",offset); + for(int i=0;i<n2d->get_child_count();i++) { + Node2D *n2dc = n2d->get_child(i)->cast_to<Node2D>(); + if (!n2dc) + continue; + + undo_redo->add_do_method(n2dc,"set_global_pos",n2dc->get_global_pos()); + undo_redo->add_undo_method(n2dc,"set_global_pos",n2dc->get_global_pos()); + + } + + } + + } + + undo_redo->commit_action(); + } + + } + } } @@ -1685,7 +1733,7 @@ void CanvasItemEditor::_viewport_draw() { viewport->draw_line(endpoints[i],endpoints[(i+1)%4],c,2); } - if (single && (tool==TOOL_SELECT || tool == TOOL_MOVE)) { //kind of sucks + if (single && (tool==TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_ROTATE)) { //kind of sucks if (canvas_item->cast_to<Node2D>()) { @@ -2854,7 +2902,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { hb->add_child(select_button); select_button->connect("pressed",this,"_tool_select",make_binds(TOOL_SELECT)); select_button->set_pressed(true); - select_button->set_tooltip("Select Mode (Q)\n"+keycode_get_string(KEY_MASK_CMD)+"Drag: Rotate\nAlt+Drag: Move\nPress 'v' to Move Pivot (while moving)"); + select_button->set_tooltip("Select Mode (Q)\n"+keycode_get_string(KEY_MASK_CMD)+"Drag: Rotate\nAlt+Drag: Move\nPress 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."); move_button = memnew( ToolButton ); move_button->set_toggle_mode(true); diff --git a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp index a533c6aa1e..8eea723126 100644 --- a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp +++ b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp @@ -380,6 +380,7 @@ void CollisionPolygon2DEditor::_bind_methods() { CollisionPolygon2DEditor::CollisionPolygon2DEditor(EditorNode *p_editor) { + node=NULL; canvas_item_editor=NULL; editor=p_editor; undo_redo = editor->get_undo_redo(); diff --git a/tools/editor/plugins/collision_polygon_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_editor_plugin.cpp index de40727f1b..381cfd74ab 100644 --- a/tools/editor/plugins/collision_polygon_editor_plugin.cpp +++ b/tools/editor/plugins/collision_polygon_editor_plugin.cpp @@ -533,6 +533,7 @@ void CollisionPolygonEditor::_bind_methods() { CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) { + node=NULL; editor=p_editor; undo_redo = editor->get_undo_redo(); diff --git a/tools/editor/plugins/color_ramp_editor_plugin.cpp b/tools/editor/plugins/color_ramp_editor_plugin.cpp new file mode 100644 index 0000000000..df50535402 --- /dev/null +++ b/tools/editor/plugins/color_ramp_editor_plugin.cpp @@ -0,0 +1,83 @@ +/* + * color_ramp_editor_plugin.cpp + */ + +#include "color_ramp_editor_plugin.h" + +ColorRampEditorPlugin::ColorRampEditorPlugin(EditorNode *p_node) { + + editor=p_node; + ramp_editor = memnew( ColorRampEdit ); + + add_custom_control(CONTAINER_CANVAS_EDITOR_BOTTOM,ramp_editor); + //add_custom_control(CONTAINER_SPATIAL_EDITOR_BOTTOM,ramp_editor); + ramp_editor->set_custom_minimum_size(Size2(100, 48)); + ramp_editor->hide(); + ramp_editor->connect("ramp_changed", this, "ramp_changed"); +} + +void ColorRampEditorPlugin::edit(Object *p_object) { + + ColorRamp* color_ramp = p_object->cast_to<ColorRamp>(); + if (!color_ramp) + return; + color_ramp_ref = Ref<ColorRamp>(color_ramp); + ramp_editor->set_points(color_ramp_ref->get_points()); +} + +bool ColorRampEditorPlugin::handles(Object *p_object) const { + + return p_object->is_type("ColorRamp"); +} + +void ColorRampEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + ramp_editor->show(); + } else { + ramp_editor->hide(); + } + +} + +void ColorRampEditorPlugin::_ramp_changed() { + + if(color_ramp_ref.is_valid()) + { + + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + + //Not sure if I should convert this data to DVector + Vector<float> new_offsets=ramp_editor->get_offsets(); + Vector<Color> new_colors=ramp_editor->get_colors(); + Vector<float> old_offsets=color_ramp_ref->get_offsets(); + Vector<Color> old_colors=color_ramp_ref->get_colors(); + + if (old_offsets.size()!=new_offsets.size()) + ur->create_action("Add/Remove Color Ramp Point"); + else + ur->create_action("Modify Color Ramp",true); + ur->add_do_method(this,"undo_redo_color_ramp",new_offsets,new_colors); + ur->add_undo_method(this,"undo_redo_color_ramp",old_offsets,old_colors); + ur->commit_action(); + + //color_ramp_ref->set_points(ramp_editor->get_points()); + } +} + +void ColorRampEditorPlugin::_undo_redo_color_ramp(const Vector<float>& offsets, + const Vector<Color>& colors) { + + color_ramp_ref->set_offsets(offsets); + color_ramp_ref->set_colors(colors); + ramp_editor->set_points(color_ramp_ref->get_points()); + ramp_editor->update(); +} + +ColorRampEditorPlugin::~ColorRampEditorPlugin(){ +} + +void ColorRampEditorPlugin::_bind_methods() { + ObjectTypeDB::bind_method(_MD("ramp_changed"),&ColorRampEditorPlugin::_ramp_changed); + ObjectTypeDB::bind_method(_MD("undo_redo_color_ramp","offsets","colors"),&ColorRampEditorPlugin::_undo_redo_color_ramp); +} diff --git a/tools/editor/plugins/color_ramp_editor_plugin.h b/tools/editor/plugins/color_ramp_editor_plugin.h new file mode 100644 index 0000000000..e39a5d65fe --- /dev/null +++ b/tools/editor/plugins/color_ramp_editor_plugin.h @@ -0,0 +1,37 @@ +/* + * color_ramp_editor_plugin.h + */ + +#ifndef TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ +#define TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ + +#include "tools/editor/editor_plugin.h" +#include "tools/editor/editor_node.h" +#include "scene/gui/color_ramp_edit.h" + +class ColorRampEditorPlugin : public EditorPlugin { + + OBJ_TYPE( ColorRampEditorPlugin, EditorPlugin ); + + Ref<ColorRamp> color_ramp_ref; + ColorRampEdit *ramp_editor; + EditorNode *editor; + +protected: + static void _bind_methods(); + void _ramp_changed(); + void _undo_redo_color_ramp(const Vector<float>& offsets, const Vector<Color>& colors); + +public: + virtual String get_name() const { return "ColorRamp"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + ColorRampEditorPlugin(EditorNode *p_node); + ~ColorRampEditorPlugin(); + +}; + +#endif /* TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ */ diff --git a/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp b/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp index 7d243b8a65..c118485083 100644 --- a/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp +++ b/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp @@ -269,8 +269,8 @@ void MeshLibraryEditor::_bind_methods() { MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) { - file = memnew( FileDialog ); - file->set_mode(FileDialog::MODE_OPEN_FILE); + file = memnew( EditorFileDialog ); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); //not for now? List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); diff --git a/tools/editor/plugins/cube_grid_theme_editor_plugin.h b/tools/editor/plugins/cube_grid_theme_editor_plugin.h index 70ccef2add..583ddf6e14 100644 --- a/tools/editor/plugins/cube_grid_theme_editor_plugin.h +++ b/tools/editor/plugins/cube_grid_theme_editor_plugin.h @@ -42,7 +42,7 @@ class MeshLibraryEditor : public Control { EditorNode *editor; MenuButton *menu; ConfirmationDialog *cd; - FileDialog *file; + EditorFileDialog *file; int to_erase; enum { diff --git a/tools/editor/plugins/editor_preview_plugins.cpp b/tools/editor/plugins/editor_preview_plugins.cpp new file mode 100644 index 0000000000..a77ba9a605 --- /dev/null +++ b/tools/editor/plugins/editor_preview_plugins.cpp @@ -0,0 +1,777 @@ +#include "editor_preview_plugins.h" +#include "io/resource_loader.h" +#include "tools/editor/editor_settings.h" +#include "io/file_access_memory.h" +#include "os/os.h" +#include "scene/resources/material.h" +#include "scene/resources/sample.h" +#include "scene/resources/mesh.h" + +bool EditorTexturePreviewPlugin::handles(const String& p_type) const { + + return ObjectTypeDB::is_type(p_type,"ImageTexture"); +} + +Ref<Texture> EditorTexturePreviewPlugin::generate(const RES& p_from) { + + Ref<ImageTexture> tex =p_from; + Image img = tex->get_data(); + if (img.empty()) + return Ref<Texture>(); + + img.clear_mipmaps(); + + int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); + if (img.is_compressed()) { + if (img.decompress()!=OK) + return Ref<Texture>(); + } else if (img.get_format()!=Image::FORMAT_RGB && img.get_format()!=Image::FORMAT_RGB) { + img.convert(Image::FORMAT_RGBA); + } + + int width,height; + if (img.get_width() > thumbnail_size && img.get_width() >= img.get_height()) { + + width=thumbnail_size; + height = img.get_height() * thumbnail_size / img.get_width(); + } else if (img.get_height() > thumbnail_size && img.get_height() >= img.get_width()) { + + height=thumbnail_size; + width = img.get_width() * thumbnail_size / img.get_height(); + } else { + + width=img.get_width(); + height=img.get_height(); + } + + img.resize(width,height); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); + + ptex->create_from_image(img,0); + return ptex; + +} + +EditorTexturePreviewPlugin::EditorTexturePreviewPlugin() { + + +} + +/////////////////////////////////////////////////////////////////////////// + + +Ref<Texture> EditorPackedScenePreviewPlugin::_gen_from_imd(Ref<ResourceImportMetadata> p_imd) { + + if (p_imd.is_null()) { + return Ref<Texture>(); + } + + if (!p_imd->has_option("thumbnail")) + return Ref<Texture>(); + + Variant tn = p_imd->get_option("thumbnail"); + //print_line(Variant::get_type_name(tn.get_type())); + DVector<uint8_t> thumbnail = tn; + + int len = thumbnail.size(); + if (len==0) + return Ref<Texture>(); + + + DVector<uint8_t>::Read r = thumbnail.read(); + + Image img(r.ptr(),len); + if (img.empty()) + return Ref<Texture>(); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); + ptex->create_from_image(img,0); + return ptex; + +} + +bool EditorPackedScenePreviewPlugin::handles(const String& p_type) const { + + return ObjectTypeDB::is_type(p_type,"PackedScene"); +} +Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES& p_from) { + + Ref<ResourceImportMetadata> imd = p_from->get_import_metadata(); + return _gen_from_imd(imd); +} + +Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String& p_path) { + + Ref<ResourceImportMetadata> imd = ResourceLoader::load_import_metadata(p_path); + return _gen_from_imd(imd); +} + +EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() { + +} + +////////////////////////////////////////////////////////////////// + +bool EditorMaterialPreviewPlugin::handles(const String& p_type) const { + + return ObjectTypeDB::is_type(p_type,"Material"); //any material +} + +Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES& p_from) { + + Ref<Material> material = p_from; + ERR_FAIL_COND_V(material.is_null(),Ref<Texture>()); + + VS::get_singleton()->mesh_surface_set_material(sphere,0,material->get_rid()); + + VS::get_singleton()->viewport_queue_screen_capture(viewport); + VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_ONCE); //once used for capture +// print_line("queue capture!"); + Image img; + + int timeout=1000; + while(timeout) { + //print_line("try capture?"); + OS::get_singleton()->delay_usec(10); + img = VS::get_singleton()->viewport_get_screen_capture(viewport); + if (!img.empty()) + break; + timeout--; + } + + //print_line("captured!"); + VS::get_singleton()->mesh_surface_set_material(sphere,0,RID()); + + int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); + img.resize(thumbnail_size,thumbnail_size); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); + ptex->create_from_image(img,0); + return ptex; +} + +EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { + + scenario = VS::get_singleton()->scenario_create(); + + viewport = VS::get_singleton()->viewport_create(); + VS::get_singleton()->viewport_set_as_render_target(viewport,true); + VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_DISABLED); + VS::get_singleton()->viewport_set_scenario(viewport,scenario); + VS::ViewportRect vr; + vr.x=0; + vr.y=0; + vr.width=128; + vr.height=128; + VS::get_singleton()->viewport_set_rect(viewport,vr); + + camera = VS::get_singleton()->camera_create(); + VS::get_singleton()->viewport_attach_camera(viewport,camera); + VS::get_singleton()->camera_set_transform(camera,Transform(Matrix3(),Vector3(0,0,3))); + VS::get_singleton()->camera_set_perspective(camera,45,0.1,10); + + light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); + light_instance = VS::get_singleton()->instance_create2(light,scenario); + VS::get_singleton()->instance_set_transform(light_instance,Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); + + light2 = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); + VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_DIFFUSE,Color(0.7,0.7,0.7)); + VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_SPECULAR,Color(0.0,0.0,0.0)); + light_instance2 = VS::get_singleton()->instance_create2(light2,scenario); + + VS::get_singleton()->instance_set_transform(light_instance2,Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); + + sphere = VS::get_singleton()->mesh_create(); + sphere_instance = VS::get_singleton()->instance_create2(sphere,scenario); + + int lats=32; + int lons=32; + float radius=1.0; + + DVector<Vector3> vertices; + DVector<Vector3> normals; + DVector<Vector2> uvs; + DVector<float> tangents; + Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5); + + for(int i = 1; i <= lats; i++) { + double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats); + double z0 = Math::sin(lat0); + double zr0 = Math::cos(lat0); + + double lat1 = Math_PI * (-0.5 + (double) i / lats); + double z1 = Math::sin(lat1); + double zr1 = Math::cos(lat1); + + for(int j = lons; j >= 1; j--) { + + double lng0 = 2 * Math_PI * (double) (j - 1) / lons; + double x0 = Math::cos(lng0); + double y0 = Math::sin(lng0); + + double lng1 = 2 * Math_PI * (double) (j) / lons; + double x1 = Math::cos(lng1); + double y1 = Math::sin(lng1); + + + Vector3 v[4]={ + Vector3(x1 * zr0, z0, y1 *zr0), + Vector3(x1 * zr1, z1, y1 *zr1), + Vector3(x0 * zr1, z1, y0 *zr1), + Vector3(x0 * zr0, z0, y0 *zr0) + }; + +#define ADD_POINT(m_idx) \ + normals.push_back(v[m_idx]);\ + vertices.push_back(v[m_idx]*radius);\ + { Vector2 uv(Math::atan2(v[m_idx].x,v[m_idx].z),Math::atan2(-v[m_idx].y,v[m_idx].z));\ + uv/=Math_PI;\ + uv*=4.0;\ + uv=uv*0.5+Vector2(0.5,0.5);\ + uvs.push_back(uv);\ + }\ + { Vector3 t = tt.xform(v[m_idx]);\ + tangents.push_back(t.x);\ + tangents.push_back(t.y);\ + tangents.push_back(t.z);\ + tangents.push_back(1.0);\ + } + + + + ADD_POINT(0); + ADD_POINT(1); + ADD_POINT(2); + + ADD_POINT(2); + ADD_POINT(3); + ADD_POINT(0); + } + } + + Array arr; + arr.resize(VS::ARRAY_MAX); + arr[VS::ARRAY_VERTEX]=vertices; + arr[VS::ARRAY_NORMAL]=normals; + arr[VS::ARRAY_TANGENT]=tangents; + arr[VS::ARRAY_TEX_UV]=uvs; + VS::get_singleton()->mesh_add_surface(sphere,VS::PRIMITIVE_TRIANGLES,arr); + +} + +EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() { + + VS::get_singleton()->free(sphere); + VS::get_singleton()->free(sphere_instance); + VS::get_singleton()->free(viewport); + VS::get_singleton()->free(light); + VS::get_singleton()->free(light_instance); + VS::get_singleton()->free(light2); + VS::get_singleton()->free(light_instance2); + VS::get_singleton()->free(camera); + VS::get_singleton()->free(scenario); + +} + +/////////////////////////////////////////////////////////////////////////// + +static bool _is_text_char(CharType c) { + + return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_'; +} + +bool EditorScriptPreviewPlugin::handles(const String& p_type) const { + + return ObjectTypeDB::is_type(p_type,"Script"); +} + +Ref<Texture> EditorScriptPreviewPlugin::generate(const RES& p_from) { + + + Ref<Script> scr = p_from; + if (scr.is_null()) + return Ref<Texture>(); + + String code = scr->get_source_code().strip_edges(); + if (code=="") + return Ref<Texture>(); + + List<String> kwors; + scr->get_language()->get_reserved_words(&kwors); + + Set<String> keywords; + + for(List<String>::Element *E=kwors.front();E;E=E->next()) { + + keywords.insert(E->get()); + + } + + + int line = 0; + int col=0; + int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); + Image img(thumbnail_size,thumbnail_size,0,Image::FORMAT_RGBA); + + + + Color bg_color = EditorSettings::get_singleton()->get("text_editor/background_color"); + bg_color.a=1.0; + Color keyword_color = EditorSettings::get_singleton()->get("text_editor/keyword_color"); + Color text_color = EditorSettings::get_singleton()->get("text_editor/text_color"); + Color symbol_color = EditorSettings::get_singleton()->get("text_editor/symbol_color"); + Color comment_color = EditorSettings::get_singleton()->get("text_editor/comment_color"); + + + for(int i=0;i<thumbnail_size;i++) { + for(int j=0;j<thumbnail_size;j++) { + img.put_pixel(i,j,bg_color); + } + + } + + bool prev_is_text=false; + bool in_keyword=false; + for(int i=0;i<code.length();i++) { + + CharType c = code[i]; + if (c>32) { + if (col<thumbnail_size) { + Color color = text_color; + + if (c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t')) { + //make symbol a little visible + color=symbol_color; + in_keyword=false; + } else if (!prev_is_text && _is_text_char(c)) { + int pos = i; + + while(_is_text_char(code[pos])) { + pos++; + } + ///print_line("from "+itos(i)+" to "+itos(pos)); + String word = code.substr(i,pos-i); + //print_line("found word: "+word); + if (keywords.has(word)) + in_keyword=true; + + } else if (!_is_text_char(c)) { + in_keyword=false; + } + + if (in_keyword) + color=keyword_color; + + Color ul=color; + ul.a*=0.5; + img.put_pixel(col,line*2,bg_color.blend(ul)); + img.put_pixel(col,line*2+1,color); + + prev_is_text=_is_text_char(c); + } + } else { + + prev_is_text=false; + in_keyword=false; + + if (c=='\n') { + col=0; + line++; + if (line>=thumbnail_size/2) + break; + } else if (c=='\t') { + col+=3; + } + } + col++; + } + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture)); + + ptex->create_from_image(img,0); + return ptex; + +} + +EditorScriptPreviewPlugin::EditorScriptPreviewPlugin() { + + +} +/////////////////////////////////////////////////////////////////// + +bool EditorSamplePreviewPlugin::handles(const String& p_type) const { + + return ObjectTypeDB::is_type(p_type,"Sample"); +} + +Ref<Texture> EditorSamplePreviewPlugin::generate(const RES& p_from) { + + Ref<Sample> smp =p_from; + ERR_FAIL_COND_V(smp.is_null(),Ref<Texture>()); + + + int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); + + DVector<uint8_t> img; + int w = thumbnail_size; + int h = thumbnail_size; + img.resize(w*h*3); + + DVector<uint8_t>::Write imgdata = img.write(); + uint8_t * imgw = imgdata.ptr(); + DVector<uint8_t> data = smp->get_data(); + DVector<uint8_t>::Read sampledata = data.read(); + const uint8_t *sdata=sampledata.ptr(); + + bool stereo = smp->is_stereo(); + bool _16=smp->get_format()==Sample::FORMAT_PCM16; + int len = smp->get_length(); + + if (len<1) + return Ref<Texture>(); + + if (smp->get_format()==Sample::FORMAT_IMA_ADPCM) { + + struct IMA_ADPCM_State { + + int16_t step_index; + int32_t predictor; + /* values at loop point */ + int16_t loop_step_index; + int32_t loop_predictor; + int32_t last_nibble; + int32_t loop_pos; + int32_t window_ofs; + const uint8_t *ptr; + } ima_adpcm; + + ima_adpcm.step_index=0; + ima_adpcm.predictor=0; + ima_adpcm.loop_step_index=0; + ima_adpcm.loop_predictor=0; + ima_adpcm.last_nibble=-1; + ima_adpcm.loop_pos=0x7FFFFFFF; + ima_adpcm.window_ofs=0; + ima_adpcm.ptr=NULL; + + + for(int i=0;i<w;i++) { + + float max[2]={-1e10,-1e10}; + float min[2]={1e10,1e10}; + int from = i*len/w; + int to = (i+1)*len/w; + if (to>=len) + to=len-1; + + for(int j=from;j<to;j++) { + + while(j>ima_adpcm.last_nibble) { + + static const int16_t _ima_adpcm_step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 + }; + + static const int8_t _ima_adpcm_index_table[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 + }; + + int16_t nibble,signed_nibble,diff,step; + + ima_adpcm.last_nibble++; + const uint8_t *src_ptr=sdata; + + nibble = (ima_adpcm.last_nibble&1)? + (src_ptr[ima_adpcm.last_nibble>>1]>>4):(src_ptr[ima_adpcm.last_nibble>>1]&0xF); + step=_ima_adpcm_step_table[ima_adpcm.step_index]; + + ima_adpcm.step_index += _ima_adpcm_index_table[nibble]; + if (ima_adpcm.step_index<0) + ima_adpcm.step_index=0; + if (ima_adpcm.step_index>88) + ima_adpcm.step_index=88; + + /* + signed_nibble = (nibble&7) * ((nibble&8)?-1:1); + diff = (2 * signed_nibble + 1) * step / 4; */ + + diff = step >> 3 ; + if (nibble & 1) + diff += step >> 2 ; + if (nibble & 2) + diff += step >> 1 ; + if (nibble & 4) + diff += step ; + if (nibble & 8) + diff = -diff ; + + ima_adpcm.predictor+=diff; + if (ima_adpcm.predictor<-0x8000) + ima_adpcm.predictor=-0x8000; + else if (ima_adpcm.predictor>0x7FFF) + ima_adpcm.predictor=0x7FFF; + + + /* store loop if there */ + if (ima_adpcm.last_nibble==ima_adpcm.loop_pos) { + + ima_adpcm.loop_step_index = ima_adpcm.step_index; + ima_adpcm.loop_predictor = ima_adpcm.predictor; + } + + } + + float v=ima_adpcm.predictor/32767.0; + if (v>max[0]) + max[0]=v; + if (v<min[0]) + min[0]=v; + } + max[0]*=0.8; + min[0]*=0.8; + + for(int j=0;j<h;j++) { + float v = (j/(float)h) * 2.0 - 1.0; + uint8_t* imgofs = &imgw[(j*w+i)*3]; + if (v>min[0] && v<max[0]) { + imgofs[0]=255; + imgofs[1]=150; + imgofs[2]=80; + } else { + imgofs[0]=0; + imgofs[1]=0; + imgofs[2]=0; + } + } + } + } else { + for(int i=0;i<w;i++) { + // i trust gcc will optimize this loop + float max[2]={-1e10,-1e10}; + float min[2]={1e10,1e10}; + int c=stereo?2:1; + int from = i*len/w; + int to = (i+1)*len/w; + if (to>=len) + to=len-1; + + if (_16) { + const int16_t*src =(const int16_t*)sdata; + + for(int j=0;j<c;j++) { + + for(int k=from;k<=to;k++) { + + float v = src[k*c+j]/32768.0; + if (v>max[j]) + max[j]=v; + if (v<min[j]) + min[j]=v; + } + + } + } else { + + const int8_t*src =(const int8_t*)sdata; + + for(int j=0;j<c;j++) { + + for(int k=from;k<=to;k++) { + + float v = src[k*c+j]/128.0; + if (v>max[j]) + max[j]=v; + if (v<min[j]) + min[j]=v; + } + + } + } + + max[0]*=0.8; + max[1]*=0.8; + min[0]*=0.8; + min[1]*=0.8; + + if (!stereo) { + for(int j=0;j<h;j++) { + float v = (j/(float)h) * 2.0 - 1.0; + uint8_t* imgofs = &imgw[(j*w+i)*3]; + if (v>min[0] && v<max[0]) { + imgofs[0]=255; + imgofs[1]=150; + imgofs[2]=80; + } else { + imgofs[0]=0; + imgofs[1]=0; + imgofs[2]=0; + } + } + } else { + + for(int j=0;j<h;j++) { + + int half,ofs; + float v; + if (j<(h/2)) { + half=0; + ofs=0; + v = (j/(float)(h/2)) * 2.0 - 1.0; + } else { + half=1; + ofs=h/2; + v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0; + } + + uint8_t* imgofs = &imgw[(j*w+i)*3]; + if (v>min[half] && v<max[half]) { + imgofs[0]=255; + imgofs[1]=150; + imgofs[2]=80; + } else { + imgofs[0]=0; + imgofs[1]=0; + imgofs[2]=0; + } + } + + } + + } + } + + imgdata = DVector<uint8_t>::Write(); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture)); + ptex->create_from_image(Image(w,h,0,Image::FORMAT_RGB,img),0); + return ptex; + +} + +EditorSamplePreviewPlugin::EditorSamplePreviewPlugin() { + + +} + +/////////////////////////////////////////////////////////////////////////// + +bool EditorMeshPreviewPlugin::handles(const String& p_type) const { + + return ObjectTypeDB::is_type(p_type,"Mesh"); //any Mesh +} + +Ref<Texture> EditorMeshPreviewPlugin::generate(const RES& p_from) { + + Ref<Mesh> mesh = p_from; + ERR_FAIL_COND_V(mesh.is_null(),Ref<Texture>()); + + VS::get_singleton()->instance_set_base(mesh_instance,mesh->get_rid()); + + AABB aabb= mesh->get_aabb(); + Vector3 ofs = aabb.pos + aabb.size*0.5; + aabb.pos-=ofs; + Transform xform; + xform.basis=Matrix3().rotated(Vector3(0,1,0),Math_PI*0.125); + xform.basis = Matrix3().rotated(Vector3(1,0,0),-Math_PI*0.125)*xform.basis; + AABB rot_aabb = xform.xform(aabb); + float m = MAX(rot_aabb.size.x,rot_aabb.size.y)*0.5; + if (m==0) + return Ref<Texture>(); + m=1.0/m; + m*=0.5; + //print_line("scale: "+rtos(m)); + xform.basis.scale(Vector3(m,m,m)); + xform.origin=-xform.basis.xform(ofs); //-ofs*m; + xform.origin.z-=rot_aabb.size.z*2; + VS::get_singleton()->instance_set_transform(mesh_instance,xform); + + + + VS::get_singleton()->viewport_queue_screen_capture(viewport); + VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_ONCE); //once used for capture +// print_line("queue capture!"); + Image img; + + int timeout=1000; + while(timeout) { + //print_line("try capture?"); + OS::get_singleton()->delay_usec(10); + img = VS::get_singleton()->viewport_get_screen_capture(viewport); + if (!img.empty()) + break; + timeout--; + } + + //print_line("captured!"); + VS::get_singleton()->instance_set_base(mesh_instance,RID()); + + int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); + img.resize(thumbnail_size,thumbnail_size); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); + ptex->create_from_image(img,0); + return ptex; +} + +EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() { + + scenario = VS::get_singleton()->scenario_create(); + viewport = VS::get_singleton()->viewport_create(); + VS::get_singleton()->viewport_set_as_render_target(viewport,true); + VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_DISABLED); + VS::get_singleton()->viewport_set_scenario(viewport,scenario); + VS::ViewportRect vr; + vr.x=0; + vr.y=0; + vr.width=128; + vr.height=128; + VS::get_singleton()->viewport_set_rect(viewport,vr); + + camera = VS::get_singleton()->camera_create(); + VS::get_singleton()->viewport_attach_camera(viewport,camera); + VS::get_singleton()->camera_set_transform(camera,Transform(Matrix3(),Vector3(0,0,3))); +// VS::get_singleton()->camera_set_perspective(camera,45,0.1,10); + VS::get_singleton()->camera_set_orthogonal(camera,1.0,0.01,1000.0); + + light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); + light_instance = VS::get_singleton()->instance_create2(light,scenario); + VS::get_singleton()->instance_set_transform(light_instance,Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); + + light2 = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); + VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_DIFFUSE,Color(0.7,0.7,0.7)); + VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_SPECULAR,Color(0.0,0.0,0.0)); + light_instance2 = VS::get_singleton()->instance_create2(light2,scenario); + + VS::get_singleton()->instance_set_transform(light_instance2,Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); + +// sphere = VS::get_singleton()->mesh_create(); + mesh_instance = VS::get_singleton()->instance_create(); + VS::get_singleton()->instance_set_scenario(mesh_instance,scenario); + + + +} + +EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() { + + //VS::get_singleton()->free(sphere); + VS::get_singleton()->free(mesh_instance); + VS::get_singleton()->free(viewport); + VS::get_singleton()->free(light); + VS::get_singleton()->free(light_instance); + VS::get_singleton()->free(light2); + VS::get_singleton()->free(light_instance2); + VS::get_singleton()->free(camera); + VS::get_singleton()->free(scenario); + +} diff --git a/tools/editor/plugins/editor_preview_plugins.h b/tools/editor/plugins/editor_preview_plugins.h new file mode 100644 index 0000000000..98071e2a0e --- /dev/null +++ b/tools/editor/plugins/editor_preview_plugins.h @@ -0,0 +1,88 @@ +#ifndef EDITORPREVIEWPLUGINS_H +#define EDITORPREVIEWPLUGINS_H + +#include "tools/editor/editor_resource_preview.h" + +class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorTexturePreviewPlugin(); +}; + + +class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator { + + Ref<Texture> _gen_from_imd(Ref<ResourceImportMetadata> p_imd); +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + virtual Ref<Texture> generate_from_path(const String& p_path); + + EditorPackedScenePreviewPlugin(); +}; + +class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator { + + RID scenario; + RID sphere; + RID sphere_instance; + RID viewport; + RID light; + RID light_instance; + RID light2; + RID light_instance2; + RID camera; +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorMaterialPreviewPlugin(); + ~EditorMaterialPreviewPlugin(); +}; + +class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator { +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorScriptPreviewPlugin(); +}; + + +class EditorSamplePreviewPlugin : public EditorResourcePreviewGenerator { +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorSamplePreviewPlugin(); +}; + + +class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator { + + RID scenario; + RID mesh_instance; + RID viewport; + RID light; + RID light_instance; + RID light2; + RID light_instance2; + RID camera; +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorMeshPreviewPlugin(); + ~EditorMeshPreviewPlugin(); +}; + + +#endif // EDITORPREVIEWPLUGINS_H diff --git a/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp b/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp index bf882857d9..757b5327dd 100644 --- a/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ b/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -411,6 +411,7 @@ void LightOccluder2DEditor::_bind_methods() { LightOccluder2DEditor::LightOccluder2DEditor(EditorNode *p_editor) { + node=NULL; canvas_item_editor=NULL; editor=p_editor; undo_redo = editor->get_undo_redo(); diff --git a/tools/editor/plugins/multimesh_editor_plugin.cpp b/tools/editor/plugins/multimesh_editor_plugin.cpp index d858f3b896..0df906117e 100644 --- a/tools/editor/plugins/multimesh_editor_plugin.cpp +++ b/tools/editor/plugins/multimesh_editor_plugin.cpp @@ -305,7 +305,7 @@ void MultiMeshEditor::edit(MultiMeshInstance *p_multimesh) { void MultiMeshEditor::_browse(bool p_source) { browsing_source=p_source; - std->get_tree()->set_marked(node,false); + std->get_scene_tree()->set_marked(node,false); std->popup_centered_ratio(); if (p_source) std->set_title("Select a Source Mesh:"); diff --git a/tools/editor/plugins/navigation_polygon_editor_plugin.cpp b/tools/editor/plugins/navigation_polygon_editor_plugin.cpp index bc15741d0f..fa1f614413 100644 --- a/tools/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/tools/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -459,7 +459,7 @@ void NavigationPolygonEditor::_bind_methods() { } NavigationPolygonEditor::NavigationPolygonEditor(EditorNode *p_editor) { - + node=NULL; canvas_item_editor=NULL; editor=p_editor; undo_redo = editor->get_undo_redo(); diff --git a/tools/editor/plugins/particles_2d_editor_plugin.cpp b/tools/editor/plugins/particles_2d_editor_plugin.cpp index 629b4fdc64..fdf534a3a8 100644 --- a/tools/editor/plugins/particles_2d_editor_plugin.cpp +++ b/tools/editor/plugins/particles_2d_editor_plugin.cpp @@ -172,14 +172,14 @@ Particles2DEditorPlugin::Particles2DEditorPlugin(EditorNode *p_node) { menu->get_popup()->add_item("Clear Emission Mask",MENU_CLEAR_EMISSION_MASK); menu->set_text("Particles"); - file = memnew(FileDialog); + file = memnew(EditorFileDialog); add_child(file); List<String> ext; ImageLoader::get_recognized_extensions(&ext); for(List<String>::Element *E=ext.front();E;E=E->next()) { file->add_filter("*."+E->get()+"; "+E->get().to_upper()); } - file->set_mode(FileDialog::MODE_OPEN_FILE); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); CanvasItemEditor::get_singleton()->add_control_to_menu_panel(menu); epoints = memnew( SpinBox ); epoints->set_min(1); diff --git a/tools/editor/plugins/particles_2d_editor_plugin.h b/tools/editor/plugins/particles_2d_editor_plugin.h index 0c355a8c8c..dba0bb4dae 100644 --- a/tools/editor/plugins/particles_2d_editor_plugin.h +++ b/tools/editor/plugins/particles_2d_editor_plugin.h @@ -48,7 +48,7 @@ class Particles2DEditorPlugin : public EditorPlugin { }; - FileDialog *file; + EditorFileDialog *file; EditorNode *editor; MenuButton *menu; diff --git a/tools/editor/plugins/particles_editor_plugin.cpp b/tools/editor/plugins/particles_editor_plugin.cpp index 3431220526..f6f01d82ca 100644 --- a/tools/editor/plugins/particles_editor_plugin.cpp +++ b/tools/editor/plugins/particles_editor_plugin.cpp @@ -394,7 +394,7 @@ ParticlesEditor::ParticlesEditor() { add_child(err_dialog); - emission_file_dialog = memnew( FileDialog ); + emission_file_dialog = memnew( EditorFileDialog ); add_child(emission_file_dialog); emission_file_dialog->connect("file_selected",this,"_resource_seleted"); emission_tree_dialog = memnew( SceneTreeDialog ); @@ -410,7 +410,7 @@ ParticlesEditor::ParticlesEditor() { emission_file_dialog->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); } - emission_file_dialog->set_mode(FileDialog::MODE_OPEN_FILE); + emission_file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); //options->set_anchor(MARGIN_LEFT,Control::ANCHOR_END); //options->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END); diff --git a/tools/editor/plugins/particles_editor_plugin.h b/tools/editor/plugins/particles_editor_plugin.h index cc13b4f2a9..92756af1f6 100644 --- a/tools/editor/plugins/particles_editor_plugin.h +++ b/tools/editor/plugins/particles_editor_plugin.h @@ -48,7 +48,7 @@ class ParticlesEditor : public Control { Particles *node; - FileDialog *emission_file_dialog; + EditorFileDialog *emission_file_dialog; SceneTreeDialog *emission_tree_dialog; ConfirmationDialog *err_dialog; diff --git a/tools/editor/plugins/resource_preloader_editor_plugin.cpp b/tools/editor/plugins/resource_preloader_editor_plugin.cpp index 39251be468..9cd20ac53a 100644 --- a/tools/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/tools/editor/plugins/resource_preloader_editor_plugin.cpp @@ -102,7 +102,7 @@ void ResourcePreloaderEditor::_load_pressed() { for(int i=0;i<extensions.size();i++) file->add_filter("*."+extensions[i]); - file->set_mode(FileDialog::MODE_OPEN_FILE); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); file->popup_centered_ratio(); @@ -310,7 +310,7 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() { paste->set_text("Paste"); hbc->add_child(paste); - file = memnew( FileDialog ); + file = memnew( EditorFileDialog ); add_child(file); diff --git a/tools/editor/plugins/resource_preloader_editor_plugin.h b/tools/editor/plugins/resource_preloader_editor_plugin.h index b3261bd182..88272bc603 100644 --- a/tools/editor/plugins/resource_preloader_editor_plugin.h +++ b/tools/editor/plugins/resource_preloader_editor_plugin.h @@ -49,7 +49,7 @@ class ResourcePreloaderEditor : public PanelContainer { bool loading_scene; - FileDialog *file; + EditorFileDialog *file; AcceptDialog *dialog; diff --git a/tools/editor/plugins/rich_text_editor_plugin.cpp b/tools/editor/plugins/rich_text_editor_plugin.cpp index 91eb0a7880..a0daad854f 100644 --- a/tools/editor/plugins/rich_text_editor_plugin.cpp +++ b/tools/editor/plugins/rich_text_editor_plugin.cpp @@ -111,10 +111,10 @@ RichTextEditor::RichTextEditor() { options->get_popup()->add_item("Clear",CLEAR); options->get_popup()->connect("item_pressed", this,"_menu_option"); - file_dialog = memnew( FileDialog ); + file_dialog = memnew( EditorFileDialog ); add_child(file_dialog); file_dialog->add_filter("*.txt"); - file_dialog->set_mode(FileDialog::MODE_OPEN_FILE); + file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); file_dialog->connect("file_selected",this,"_file_selected"); } diff --git a/tools/editor/plugins/rich_text_editor_plugin.h b/tools/editor/plugins/rich_text_editor_plugin.h index 653d756d8f..478dc0d308 100644 --- a/tools/editor/plugins/rich_text_editor_plugin.h +++ b/tools/editor/plugins/rich_text_editor_plugin.h @@ -53,7 +53,7 @@ class RichTextEditor : public Control { Panel *panel; MenuButton *options; RichTextLabel *node; - FileDialog *file_dialog; + EditorFileDialog *file_dialog; void _file_selected(const String& p_path); void _menu_option(int p_option); diff --git a/tools/editor/plugins/sample_editor_plugin.cpp b/tools/editor/plugins/sample_editor_plugin.cpp index 3219935688..31fa7246ae 100644 --- a/tools/editor/plugins/sample_editor_plugin.cpp +++ b/tools/editor/plugins/sample_editor_plugin.cpp @@ -98,6 +98,125 @@ void SampleEditor::generate_preview_texture(const Ref<Sample>& p_sample,Ref<Imag if (p_sample->get_format()==Sample::FORMAT_IMA_ADPCM) { + struct IMA_ADPCM_State { + + int16_t step_index; + int32_t predictor; + /* values at loop point */ + int16_t loop_step_index; + int32_t loop_predictor; + int32_t last_nibble; + int32_t loop_pos; + int32_t window_ofs; + const uint8_t *ptr; + } ima_adpcm; + + ima_adpcm.step_index=0; + ima_adpcm.predictor=0; + ima_adpcm.loop_step_index=0; + ima_adpcm.loop_predictor=0; + ima_adpcm.last_nibble=-1; + ima_adpcm.loop_pos=0x7FFFFFFF; + ima_adpcm.window_ofs=0; + ima_adpcm.ptr=NULL; + + + for(int i=0;i<w;i++) { + + float max[2]={-1e10,-1e10}; + float min[2]={1e10,1e10}; + int from = i*len/w; + int to = (i+1)*len/w; + if (to>=len) + to=len-1; + + for(int j=from;j<to;j++) { + + while(j>ima_adpcm.last_nibble) { + + static const int16_t _ima_adpcm_step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 + }; + + static const int8_t _ima_adpcm_index_table[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 + }; + + int16_t nibble,signed_nibble,diff,step; + + ima_adpcm.last_nibble++; + const uint8_t *src_ptr=sdata; + + nibble = (ima_adpcm.last_nibble&1)? + (src_ptr[ima_adpcm.last_nibble>>1]>>4):(src_ptr[ima_adpcm.last_nibble>>1]&0xF); + step=_ima_adpcm_step_table[ima_adpcm.step_index]; + + ima_adpcm.step_index += _ima_adpcm_index_table[nibble]; + if (ima_adpcm.step_index<0) + ima_adpcm.step_index=0; + if (ima_adpcm.step_index>88) + ima_adpcm.step_index=88; + + /* + signed_nibble = (nibble&7) * ((nibble&8)?-1:1); + diff = (2 * signed_nibble + 1) * step / 4; */ + + diff = step >> 3 ; + if (nibble & 1) + diff += step >> 2 ; + if (nibble & 2) + diff += step >> 1 ; + if (nibble & 4) + diff += step ; + if (nibble & 8) + diff = -diff ; + + ima_adpcm.predictor+=diff; + if (ima_adpcm.predictor<-0x8000) + ima_adpcm.predictor=-0x8000; + else if (ima_adpcm.predictor>0x7FFF) + ima_adpcm.predictor=0x7FFF; + + + /* store loop if there */ + if (ima_adpcm.last_nibble==ima_adpcm.loop_pos) { + + ima_adpcm.loop_step_index = ima_adpcm.step_index; + ima_adpcm.loop_predictor = ima_adpcm.predictor; + } + + } + + float v=ima_adpcm.predictor/32767.0; + if (v>max[0]) + max[0]=v; + if (v<min[0]) + min[0]=v; + } + + for(int j=0;j<h;j++) { + float v = (j/(float)h) * 2.0 - 1.0; + uint8_t* imgofs = &imgw[(j*w+i)*3]; + if (v>min[0] && v<max[0]) { + imgofs[0]=255; + imgofs[1]=150; + imgofs[2]=80; + } else { + imgofs[0]=0; + imgofs[1]=0; + imgofs[2]=0; + } + } + } } else { for(int i=0;i<w;i++) { // i trust gcc will optimize this loop diff --git a/tools/editor/plugins/sample_library_editor_plugin.cpp b/tools/editor/plugins/sample_library_editor_plugin.cpp index bb9d1f9dd0..cf9a6c41a4 100644 --- a/tools/editor/plugins/sample_library_editor_plugin.cpp +++ b/tools/editor/plugins/sample_library_editor_plugin.cpp @@ -350,13 +350,13 @@ SampleLibraryEditor::SampleLibraryEditor() { _delete = memnew( Button ); - file = memnew( FileDialog ); + file = memnew( EditorFileDialog ); add_child(file); List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("Sample",&extensions); for(int i=0;i<extensions.size();i++) file->add_filter("*."+extensions[i]); - file->set_mode(FileDialog::MODE_OPEN_FILES); + file->set_mode(EditorFileDialog::MODE_OPEN_FILES); _delete->set_pos(Point2( 65, 5 )); _delete->set_size( Size2(1,1 ) ); diff --git a/tools/editor/plugins/sample_library_editor_plugin.h b/tools/editor/plugins/sample_library_editor_plugin.h index 70c7fed068..2770ca2d9a 100644 --- a/tools/editor/plugins/sample_library_editor_plugin.h +++ b/tools/editor/plugins/sample_library_editor_plugin.h @@ -54,7 +54,7 @@ class SampleLibraryEditor : public Panel { Button *_delete; Tree *tree; - FileDialog *file; + EditorFileDialog *file; ConfirmationDialog *dialog; diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index f5ba6a08e6..71ce040b05 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -38,10 +38,12 @@ #include "os/file_access.h" #include "scene/main/viewport.h" #include "os/keyboard.h" -/*** SCRIPT EDITOR ****/ +#include "os/input.h" +/*** SCRIPT EDITOR ****/ +#define SORT_SCRIPT_LIST void ScriptEditorQuickOpen::popup(const Vector<String>& p_functions, bool p_dontclear) { @@ -118,6 +120,8 @@ void ScriptEditorQuickOpen::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { connect("confirmed",this,"_confirmed"); + + } } @@ -286,8 +290,19 @@ void ScriptTextEditor::reload_text() { ERR_FAIL_COND(script.is_null()) ; - get_text_edit()->set_text(script->get_source_code()); - get_text_edit()->clear_undo_history(); + TextEdit *te = get_text_edit(); + int column = te->cursor_get_column(); + int row = te->cursor_get_line(); + int h = te->get_h_scroll(); + int v = te->get_v_scroll(); + + te->set_text(script->get_source_code()); + te->clear_undo_history(); + te->cursor_set_line(row); + te->cursor_set_column(column); + te->set_h_scroll(h); + te->set_v_scroll(v); + _line_col_changed(); } @@ -296,12 +311,11 @@ void ScriptTextEditor::_notification(int p_what) { if (p_what==NOTIFICATION_READY) { - _update_name(); + //emit_signal("name_changed"); } } -void ScriptTextEditor::_update_name() { - +String ScriptTextEditor::get_name() { String name; if (script->get_path().find("local://")==-1 && script->get_path().find("::")==-1) { @@ -314,21 +328,20 @@ void ScriptTextEditor::_update_name() { else name=script->get_type()+"("+itos(script->get_instance_ID())+")"; + return name; - if (name!=String(get_name())) { +} - set_name(name); +Ref<Texture> ScriptTextEditor::get_icon() { + if (get_parent_control() && get_parent_control()->has_icon(script->get_type(),"EditorIcons")) { + return get_parent_control()->get_icon(script->get_type(),"EditorIcons"); } - if (!has_meta("_tab_icon")) { - if (get_parent_control() && get_parent_control()->has_icon(script->get_type(),"EditorIcons")) { - set_meta("_tab_icon",get_parent_control()->get_icon(script->get_type(),"EditorIcons")); - } - } + return Ref<Texture>(); +} -} void ScriptTextEditor::set_edited_script(const Ref<Script>& p_script) { @@ -344,8 +357,7 @@ void ScriptTextEditor::set_edited_script(const Ref<Script>& p_script) { get_text_edit()->tag_saved_version(); - _update_name(); - + emit_signal("name_changed"); _line_col_changed(); } @@ -384,7 +396,7 @@ void ScriptTextEditor::_validate_script() { te->set_line_as_marked(i,line==i); } - _update_name(); + emit_signal("name_changed"); } @@ -418,6 +430,10 @@ void ScriptTextEditor::_code_complete_script(const String& p_code, List<String>* } } +void ScriptTextEditor::_bind_methods() { + + ADD_SIGNAL(MethodInfo("name_changed")); +} ScriptTextEditor::ScriptTextEditor() { @@ -492,11 +508,15 @@ void ScriptEditor::_close_current_tab() { memdelete(current); if (idx>=tab_container->get_child_count()) idx=tab_container->get_child_count()-1; - if (idx>=0) + if (idx>=0) { tab_container->set_current_tab(idx); + //script_list->select(idx); + } - _update_window_menu(); - _save_files_state(); + + + _update_script_names(); + EditorNode::get_singleton()->save_layout(); } @@ -587,10 +607,10 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource>& p_res) { ste->get_text_edit()->tag_saved_version(); } - ste->_update_name(); - } + _update_script_names(); + } bool ScriptEditor::_test_script_times_on_disk() { @@ -1045,7 +1065,7 @@ void ScriptEditor::_menu_option(int p_option) { if (text != "") editor->emit_signal("request_help", text); } break; - case WINDOW_CLOSE: { + case FILE_CLOSE: { if (current->get_text_edit()->get_version()!=current->get_text_edit()->get_saved_version()) { erase_tab_confirm->set_text("Close and save changes?\n\""+current->get_name()+"\""); erase_tab_confirm->popup_centered_minsize(); @@ -1057,16 +1077,18 @@ void ScriptEditor::_menu_option(int p_option) { if (tab_container->get_current_tab()>0) { tab_container->call_deferred("set_current_tab",tab_container->get_current_tab()-1); + script_list->call_deferred("select",tab_container->get_current_tab()-1); tab_container->move_child(current,tab_container->get_current_tab()-1); - _update_window_menu(); + _update_script_names(); } } break; case WINDOW_MOVE_RIGHT: { if (tab_container->get_current_tab()<tab_container->get_child_count()-1) { tab_container->call_deferred("set_current_tab",tab_container->get_current_tab()+1); + script_list->call_deferred("select",tab_container->get_current_tab()+1); tab_container->move_child(current,tab_container->get_current_tab()+1); - _update_window_menu(); + _update_script_names(); } @@ -1076,6 +1098,8 @@ void ScriptEditor::_menu_option(int p_option) { if (p_option>=WINDOW_SELECT_BASE) { tab_container->set_current_tab(p_option-WINDOW_SELECT_BASE); + script_list->select(p_option-WINDOW_SELECT_BASE); + } } } @@ -1096,6 +1120,8 @@ void ScriptEditor::_notification(int p_what) { editor->connect("stop_pressed",this,"_editor_stop"); editor->connect("script_add_function_request",this,"_add_callback"); editor->connect("resource_saved",this,"_res_saved_callback"); + script_list->connect("item_selected",this,"_script_selected"); + script_split->connect("dragged",this,"_script_split_dragged"); autosave_timer->connect("timeout",this,"_autosave_scripts"); { float autosave_time = EditorSettings::get_singleton()->get("text_editor/autosave_interval_secs"); @@ -1113,7 +1139,8 @@ void ScriptEditor::_notification(int p_what) { } if (p_what==NOTIFICATION_READY) { - _update_window_menu(); + + get_tree()->connect("tree_changed",this,"_tree_changed"); } if (p_what==NOTIFICATION_EXIT_TREE) { @@ -1153,10 +1180,11 @@ static const Node * _find_node_with_script(const Node* p_node, const RefPtr & p_ Dictionary ScriptEditor::get_state() const { - apply_scripts(); - Dictionary state; +// apply_scripts(); + Dictionary state; +#if 0 Array paths; int open=-1; @@ -1189,12 +1217,12 @@ Dictionary ScriptEditor::get_state() const { if (open!=-1) state["current"]=open; - +#endif return state; } void ScriptEditor::set_state(const Dictionary& p_state) { - +#if 0 print_line("attempt set state: "+String(Variant(p_state))); if (!p_state.has("sources")) @@ -1231,6 +1259,7 @@ void ScriptEditor::set_state(const Dictionary& p_state) { if (p_state.has("current")) { tab_container->set_current_tab(p_state["current"]); } +#endif } void ScriptEditor::clear() { @@ -1254,68 +1283,17 @@ void ScriptEditor::clear() { int idx = tab_container->get_current_tab(); if (idx>=tab_container->get_child_count()) idx=tab_container->get_child_count()-1; - if (idx>=0) + if (idx>=0) { tab_container->set_current_tab(idx); - - _update_window_menu(); - - -} - -void ScriptEditor::_save_files_state() { - - return; //no thank you - - String rpath="_open_scripts_"+Globals::get_singleton()->get_resource_path(); - rpath=rpath.replace("\\","_-_"); - rpath=rpath.replace("/","_-_"); - rpath=rpath.replace(":","_"); - - Vector<String> scripts; - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); - if (!ste) - continue; - - - Ref<Script> script = ste->get_edited_script(); - if (script->get_path()!="" && script->get_path().find("local://")==-1 && script->get_path().find("::")==-1) { - - - scripts.push_back(script->get_path()); - } + script_list->select( script_list->find_metadata(idx) ); } - EditorSettings::get_singleton()->set(rpath,scripts); - EditorSettings::get_singleton()->save(); - -} - -void ScriptEditor::_load_files_state() { - return; - - String rpath="_open_scripts_"+Globals::get_singleton()->get_resource_path(); - rpath=rpath.replace("\\","_-_"); - rpath=rpath.replace("/","_-_"); - rpath=rpath.replace(":","_"); - - if (EditorSettings::get_singleton()->has(rpath)) { - - Vector<String> open_files=EditorSettings::get_singleton()->get("rpath"); - for(int i=0;i<open_files.size();i++) { - Ref<Script> scr = ResourceLoader::load(open_files[i]); - if (!scr.is_valid()) - continue; - editor->edit_resource(scr); - } - } } + void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) { for(int i=0;i<tab_container->get_child_count();i++) { @@ -1360,11 +1338,18 @@ void ScriptEditor::_bind_methods() { ObjectTypeDB::bind_method("_get_debug_tooltip",&ScriptEditor::_get_debug_tooltip); ObjectTypeDB::bind_method("_autosave_scripts",&ScriptEditor::_autosave_scripts); ObjectTypeDB::bind_method("_editor_settings_changed",&ScriptEditor::_editor_settings_changed); + ObjectTypeDB::bind_method("_update_script_names",&ScriptEditor::_update_script_names); + ObjectTypeDB::bind_method("_tree_changed",&ScriptEditor::_tree_changed); + ObjectTypeDB::bind_method("_script_selected",&ScriptEditor::_script_selected); + ObjectTypeDB::bind_method("_script_split_dragged",&ScriptEditor::_script_split_dragged); } void ScriptEditor::ensure_focus_current() { + if (!is_inside_tree()) + return; + int cidx = tab_container->get_current_tab(); if (cidx<0 || cidx>=tab_container->get_tab_count()); Control *c = tab_container->get_child(cidx)->cast_to<Control>(); @@ -1376,6 +1361,13 @@ void ScriptEditor::ensure_focus_current() { ste->get_text_edit()->grab_focus(); } +void ScriptEditor::_script_selected(int p_idx) { + + grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing + tab_container->set_current_tab(script_list->get_item_metadata(p_idx)); + grab_focus_block=false; +} + void ScriptEditor::ensure_select_current() { @@ -1386,8 +1378,66 @@ void ScriptEditor::ensure_select_current() { return; Ref<Script> script = ste->get_edited_script(); - ste->get_text_edit()->grab_focus(); + if (!grab_focus_block && is_inside_tree()) + ste->get_text_edit()->grab_focus(); + } + + +} + +void ScriptEditor::_find_scripts(Node* p_base, Node* p_current, Set<Ref<Script> > &used) { + if (p_current!=p_base && p_current->get_owner()!=p_base) + return; + + if (p_current->get_script_instance()) { + Ref<Script> scr = p_current->get_script(); + if (scr.is_valid()) + used.insert(scr); + } + + for(int i=0;i<p_current->get_child_count();i++) { + _find_scripts(p_base,p_current->get_child(i),used); + } + +} + + +void ScriptEditor::_update_script_names() { + + waiting_update_names=false; + Set<Ref<Script> > used; + Node* edited = EditorNode::get_singleton()->get_edited_scene(); + if (edited) { + _find_scripts(edited,edited,used); + } + + script_list->clear(); + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); + if (!ste) + continue; + + String script = ste->get_name(); + Ref<Texture> icon = ste->get_icon(); + String path = ste->get_edited_script()->get_path(); + script_list->add_item(script,icon); + + int index = script_list->get_item_count()-1; + + script_list->set_item_tooltip(index,path); + script_list->set_item_metadata(index,i); + if (used.has(ste->get_edited_script())) { + + script_list->set_item_custom_bg_color(index,Color(88/255.0,88/255.0,60/255.0)); + } + if (tab_container->get_current_tab()==index) { + script_list->select(index); + } } + + script_list->sort_items_by_text(); + } void ScriptEditor::edit(const Ref<Script>& p_script) { @@ -1425,9 +1475,13 @@ void ScriptEditor::edit(const Ref<Script>& p_script) { if (ste->get_edited_script()==p_script) { - if (tab_container->get_current_tab()!=i) - tab_container->set_current_tab(i); - ste->get_text_edit()->grab_focus(); + if (!EditorNode::get_singleton()->is_changing_scene()) { + if (tab_container->get_current_tab()!=i) { + tab_container->set_current_tab(i); + script_list->select( script_list->find_metadata(i) ); + } + ste->get_text_edit()->grab_focus(); + } return; } } @@ -1440,9 +1494,13 @@ void ScriptEditor::edit(const Ref<Script>& p_script) { tab_container->add_child(ste); tab_container->set_current_tab(tab_container->get_tab_count()-1); - _update_window_menu(); - _save_files_state(); + + _update_script_names(); + ste->connect("name_changed",this,"_update_script_names"); + if (!restoring_layout) { + EditorNode::get_singleton()->save_layout(); + } } void ScriptEditor::save_external_data() { @@ -1502,51 +1560,6 @@ void ScriptEditor::_editor_stop() { debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true ); } -void ScriptEditor::_update_window_menu() { - - int idx=0; - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); - if (!ste) - continue; - idx++; - } - - if (idx==0) { - window_menu->set_disabled(true); - edit_menu->set_disabled(true); - search_menu->set_disabled(true); - return; - } else { - - window_menu->set_disabled(false); - edit_menu->set_disabled(false); - search_menu->set_disabled(false); - } - - window_menu->get_popup()->clear(); - window_menu->get_popup()->add_item("Close",WINDOW_CLOSE,KEY_MASK_CMD|KEY_W); - window_menu->get_popup()->add_separator(); - window_menu->get_popup()->add_item("Move Left",WINDOW_MOVE_LEFT,KEY_MASK_CMD|KEY_MASK_ALT|KEY_LEFT); - window_menu->get_popup()->add_item("Move Right",WINDOW_MOVE_RIGHT,KEY_MASK_CMD|KEY_MASK_ALT|KEY_RIGHT); - window_menu->get_popup()->add_separator(); - - idx=0; - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); - if (!ste) - continue; - String n = ste->get_name(); - uint32_t accel=0; - if (idx<9) { - accel=KEY_MASK_ALT|KEY_MASK_CMD|(KEY_1+idx); - } - window_menu->get_popup()->add_item(n,WINDOW_SELECT_BASE+idx,accel); - idx++; - } -} void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const StringArray& p_args) { @@ -1582,6 +1595,8 @@ void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const ste->get_text_edit()->cursor_set_line(pos); ste->get_text_edit()->cursor_set_column(1); + script_list->select( script_list->find_metadata(i) ); + break; } @@ -1607,8 +1622,80 @@ void ScriptEditor::_autosave_scripts() { save_external_data(); } +void ScriptEditor::_tree_changed() { + + if (waiting_update_names) + return; + + waiting_update_names=true; + call_deferred("_update_script_names"); +} + +void ScriptEditor::_script_split_dragged(float) { + + EditorNode::get_singleton()->save_layout(); +} + +void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) { + + if (!bool(EDITOR_DEF("text_editor/restore_scripts_on_load",true))) { + return; + } + + if (!p_layout->has_section_key("ScriptEditor","open_scripts")) + return; + + Array scripts = p_layout->get_value("ScriptEditor","open_scripts"); + + restoring_layout=true; + + for(int i=0;i<scripts.size();i++) { + + String path = scripts[i]; + Ref<Script> scr = ResourceLoader::load(path); + if (scr.is_valid()) { + edit(scr); + } + } + + if (p_layout->has_section_key("ScriptEditor","split_offset")) { + script_split->set_split_offset(p_layout->get_value("ScriptEditor","split_offset")); + } + + + restoring_layout=false; + +} + +void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) { + + Array scripts; + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); + if (!ste) + continue; + + String path = ste->get_edited_script()->get_path(); + if (!path.is_resource_file()) + continue; + + scripts.push_back(path); + + } + + p_layout->set_value("ScriptEditor","open_scripts",scripts); + p_layout->set_value("ScriptEditor","split_offset",script_split->get_split_offset()); + +} + + + ScriptEditor::ScriptEditor(EditorNode *p_editor) { + restoring_layout=false; + waiting_update_names=false; editor=p_editor; menu_hb = memnew( HBoxContainer ); @@ -1618,17 +1705,31 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { add_child(v_split); v_split->set_v_size_flags(SIZE_EXPAND_FILL); + script_split = memnew( HSplitContainer ); + v_split->add_child(script_split); + script_split->set_v_size_flags(SIZE_EXPAND_FILL); + + script_list = memnew( ItemList ); + script_split->add_child(script_list); + script_list->set_custom_minimum_size(Size2(140,0)); + tab_container = memnew( TabContainer ); - v_split->add_child(tab_container); - tab_container->set_v_size_flags(SIZE_EXPAND_FILL); + tab_container->set_tabs_visible(false); + script_split->add_child(tab_container); + + + tab_container->set_h_size_flags(SIZE_EXPAND_FILL); file_menu = memnew( MenuButton ); menu_hb->add_child(file_menu); file_menu->set_text("File"); file_menu->get_popup()->add_item("Open",FILE_OPEN); + file_menu->get_popup()->add_separator(); file_menu->get_popup()->add_item("Save",FILE_SAVE,KEY_MASK_ALT|KEY_MASK_CMD|KEY_S); file_menu->get_popup()->add_item("Save As..",FILE_SAVE_AS); file_menu->get_popup()->add_item("Save All",FILE_SAVE_ALL,KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_S); + file_menu->get_popup()->add_separator(); + file_menu->get_popup()->add_item("Close",FILE_CLOSE,KEY_MASK_CMD|KEY_W); file_menu->get_popup()->connect("item_pressed", this,"_menu_option"); edit_menu = memnew( MenuButton ); @@ -1690,6 +1791,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true ); +#if 0 window_menu = memnew( MenuButton ); menu_hb->add_child(window_menu); window_menu->set_text("Window"); @@ -1700,6 +1802,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { window_menu->get_popup()->add_separator(); window_menu->get_popup()->connect("item_pressed", this,"_menu_option"); +#endif + help_menu = memnew( MenuButton ); menu_hb->add_child(help_menu); help_menu->set_text("Help"); @@ -1762,6 +1866,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { autosave_timer->set_one_shot(false); add_child(autosave_timer); + grab_focus_block=false; + // debugger_gui->hide(); } @@ -1826,20 +1932,24 @@ void ScriptEditorPlugin::apply_changes() { void ScriptEditorPlugin::restore_global_state() { - if (bool(EDITOR_DEF("text_editor/restore_scripts_on_load",true))) { - script_editor->_load_files_state(); - } } void ScriptEditorPlugin::save_global_state() { - if (bool(EDITOR_DEF("text_editor/restore_scripts_on_load",true))) { - script_editor->_save_files_state(); - } +} +void ScriptEditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) { + + script_editor->set_window_layout(p_layout); } +void ScriptEditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){ + + script_editor->get_window_layout(p_layout); +} + + void ScriptEditorPlugin::get_breakpoints(List<String> *p_breakpoints) { diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h index acfdd1e966..635db40c2f 100644 --- a/tools/editor/plugins/script_editor_plugin.h +++ b/tools/editor/plugins/script_editor_plugin.h @@ -38,7 +38,7 @@ #include "script_language.h" #include "tools/editor/code_editor.h" #include "scene/gui/split_container.h" - +#include "scene/gui/item_list.h" class ScriptEditorQuickOpen : public ConfirmationDialog { @@ -88,6 +88,7 @@ protected: virtual void _code_complete_script(const String& p_code, List<String>* r_options); virtual void _load_theme_settings(); void _notification(int p_what); + static void _bind_methods(); public: @@ -97,7 +98,8 @@ public: Vector<String> get_functions() ; void set_edited_script(const Ref<Script>& p_script); void reload_text(); - void _update_name(); + String get_name() ; + Ref<Texture> get_icon() ; ScriptTextEditor(); @@ -115,6 +117,7 @@ class ScriptEditor : public VBoxContainer { FILE_SAVE, FILE_SAVE_AS, FILE_SAVE_ALL, + FILE_CLOSE, EDIT_UNDO, EDIT_REDO, EDIT_CUT, @@ -123,12 +126,12 @@ class ScriptEditor : public VBoxContainer { EDIT_SELECT_ALL, EDIT_COMPLETE, EDIT_AUTO_INDENT, - EDIT_TOGGLE_COMMENT, - EDIT_MOVE_LINE_UP, - EDIT_MOVE_LINE_DOWN, - EDIT_INDENT_RIGHT, - EDIT_INDENT_LEFT, - EDIT_CLONE_DOWN, + EDIT_TOGGLE_COMMENT, + EDIT_MOVE_LINE_UP, + EDIT_MOVE_LINE_DOWN, + EDIT_INDENT_RIGHT, + EDIT_INDENT_LEFT, + EDIT_CLONE_DOWN, SEARCH_FIND, SEARCH_FIND_NEXT, SEARCH_REPLACE, @@ -140,8 +143,7 @@ class ScriptEditor : public VBoxContainer { DEBUG_BREAK, DEBUG_CONTINUE, DEBUG_SHOW, - HELP_CONTEXTUAL, - WINDOW_CLOSE, + HELP_CONTEXTUAL, WINDOW_MOVE_LEFT, WINDOW_MOVE_RIGHT, WINDOW_SELECT_BASE=100 @@ -151,12 +153,13 @@ class ScriptEditor : public VBoxContainer { MenuButton *file_menu; MenuButton *edit_menu; MenuButton *search_menu; - MenuButton *window_menu; MenuButton *debug_menu; MenuButton *help_menu; Timer *autosave_timer; uint64_t idle; + ItemList *script_list; + HSplitContainer *script_split; TabContainer *tab_container; FindReplaceDialog *find_replace_dialog; GotoLineDialog *goto_line_dialog; @@ -171,6 +174,8 @@ class ScriptEditor : public VBoxContainer { VSplitContainer *v_split; + bool restoring_layout; + String _get_debug_tooltip(const String&p_text,Node *_ste); void _resave_scripts(const String& p_str); @@ -180,6 +185,8 @@ class ScriptEditor : public VBoxContainer { void _close_current_tab(); + bool grab_focus_block; + ScriptEditorQuickOpen *quick_open; @@ -199,6 +206,18 @@ class ScriptEditor : public VBoxContainer { void _editor_settings_changed(); void _autosave_scripts(); + void _update_script_names(); + + void _script_selected(int p_idx); + + void _find_scripts(Node* p_base, Node* p_current,Set<Ref<Script> >& used); + + void _tree_changed(); + + void _script_split_dragged(float); + + bool waiting_update_names; + static ScriptEditor *script_editor; protected: void _notification(int p_what); @@ -206,9 +225,6 @@ protected: public: static ScriptEditor *get_singleton() { return script_editor; } - void _save_files_state(); - void _load_files_state(); - void ensure_focus_current(); void apply_scripts() const; @@ -222,10 +238,13 @@ public: void get_breakpoints(List<String> *p_breakpoints); - void swap_lines(TextEdit *tx, int line1, int line2); + void swap_lines(TextEdit *tx, int line1, int line2); void save_external_data(); + void set_window_layout(Ref<ConfigFile> p_layout); + void get_window_layout(Ref<ConfigFile> p_layout); + ScriptEditor(EditorNode *p_editor); }; @@ -254,6 +273,9 @@ public: virtual void restore_global_state(); virtual void save_global_state(); + virtual void set_window_layout(Ref<ConfigFile> p_layout); + virtual void get_window_layout(Ref<ConfigFile> p_layout); + virtual void get_breakpoints(List<String> *p_breakpoints); diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp index 0b3f3e0626..77663f39c0 100644 --- a/tools/editor/plugins/spatial_editor_plugin.cpp +++ b/tools/editor/plugins/spatial_editor_plugin.cpp @@ -2216,6 +2216,14 @@ void SpatialEditorViewport::reset() { SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) { + _edit.mode=TRANSFORM_NONE; + _edit.plane=TRANSFORM_VIEW; + _edit.edited_gizmo=0; + _edit.snap=1; + _edit.gizmo_handle=0; + + + index=p_index; editor=p_editor; editor_selection=editor->get_editor_selection();; @@ -3615,6 +3623,8 @@ void SpatialEditor::_default_light_angle_input(const InputEvent& p_event) { SpatialEditor::SpatialEditor(EditorNode *p_editor) { + gizmo.visible=true; + gizmo.scale=1.0; viewport_environment = Ref<Environment>( memnew( Environment ) ); undo_redo=p_editor->get_undo_redo(); diff --git a/tools/editor/plugins/spatial_editor_plugin.h b/tools/editor/plugins/spatial_editor_plugin.h index b890f285ee..ff8912fca8 100644 --- a/tools/editor/plugins/spatial_editor_plugin.h +++ b/tools/editor/plugins/spatial_editor_plugin.h @@ -239,7 +239,7 @@ public: void set_state(const Dictionary& p_state); Dictionary get_state() const; void reset(); - + Viewport *get_viewport_node() { return viewport; } SpatialEditorViewport(SpatialEditor *p_spatial_editor,EditorNode *p_editor,int p_index); @@ -422,6 +422,7 @@ private: HBoxContainer *hbc_menu; + // // void _generate_selection_box(); @@ -514,6 +515,11 @@ public: void set_can_preview(Camera* p_preview); + SpatialEditorViewport *get_editor_viewport(int p_idx) { + ERR_FAIL_INDEX_V(p_idx,4,NULL); + return viewports[p_idx]; + } + Camera *get_camera() { return NULL; } void edit(Spatial *p_spatial); void clear(); diff --git a/tools/editor/plugins/sprite_frames_editor_plugin.cpp b/tools/editor/plugins/sprite_frames_editor_plugin.cpp index 7fdfac2578..e90087efda 100644 --- a/tools/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/tools/editor/plugins/sprite_frames_editor_plugin.cpp @@ -115,7 +115,7 @@ void SpriteFramesEditor::_load_pressed() { for(int i=0;i<extensions.size();i++) file->add_filter("*."+extensions[i]); - file->set_mode(FileDialog::MODE_OPEN_FILES); + file->set_mode(EditorFileDialog::MODE_OPEN_FILES); file->popup_centered_ratio(); @@ -435,7 +435,7 @@ SpriteFramesEditor::SpriteFramesEditor() { _delete = memnew( Button ); hbc->add_child(_delete); - file = memnew( FileDialog ); + file = memnew( EditorFileDialog ); add_child(file); diff --git a/tools/editor/plugins/sprite_frames_editor_plugin.h b/tools/editor/plugins/sprite_frames_editor_plugin.h index ffd35f3755..969d7b1ce3 100644 --- a/tools/editor/plugins/sprite_frames_editor_plugin.h +++ b/tools/editor/plugins/sprite_frames_editor_plugin.h @@ -54,7 +54,7 @@ class SpriteFramesEditor : public PanelContainer { int sel; - FileDialog *file; + EditorFileDialog *file; AcceptDialog *dialog; diff --git a/tools/editor/plugins/theme_editor_plugin.cpp b/tools/editor/plugins/theme_editor_plugin.cpp index 128ff949e1..55e8f164d6 100644 --- a/tools/editor/plugins/theme_editor_plugin.cpp +++ b/tools/editor/plugins/theme_editor_plugin.cpp @@ -408,7 +408,7 @@ void ThemeEditor::_theme_menu_cbk(int p_option) { if (p_option==POPUP_CREATE_TEMPLATE) { - file_dialog->set_mode(FileDialog::MODE_SAVE_FILE); + file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); file_dialog->set_current_path("custom.theme"); file_dialog->popup_centered_ratio(); return; @@ -734,7 +734,7 @@ ThemeEditor::ThemeEditor() { fd_button->set_text("Open File Dialog"); panel->add_child(fd_button); - test_file_dialog = memnew( FileDialog ); + test_file_dialog = memnew( EditorFileDialog ); panel->add_child(test_file_dialog); fd_button->connect("pressed", this,"_open_file_dialog"); @@ -804,7 +804,7 @@ ThemeEditor::ThemeEditor() { add_del_dialog->get_ok()->connect("pressed", this,"_dialog_cbk"); - file_dialog = memnew( FileDialog ); + file_dialog = memnew( EditorFileDialog ); file_dialog->add_filter("*.theme ; Theme File"); add_child(file_dialog); file_dialog->connect("file_selected",this,"_save_template_cbk"); diff --git a/tools/editor/plugins/theme_editor_plugin.h b/tools/editor/plugins/theme_editor_plugin.h index 37f5ad6129..40c7ad8186 100644 --- a/tools/editor/plugins/theme_editor_plugin.h +++ b/tools/editor/plugins/theme_editor_plugin.h @@ -48,7 +48,7 @@ class ThemeEditor : public Control { VBoxContainer *main_vb; Ref<Theme> theme; - FileDialog *file_dialog; + EditorFileDialog *file_dialog; double time_left; diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 5c82973da4..017a26441d 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -71,22 +71,19 @@ void TileMapEditor::_canvas_mouse_exit() { } int TileMapEditor::get_selected_tile() const { - - TreeItem *item = palette->get_selected(); - if (!item) + int item = palette->get_current(); + if (item==-1) return TileMap::INVALID_CELL; - return item->get_metadata(0); + return palette->get_item_metadata(item); } void TileMapEditor::set_selected_tile(int p_tile) { - TreeItem *item = palette->get_root()->get_children(); - while (item) { - if ((int)item->get_metadata(0) == p_tile) { - item->select(0); - palette->ensure_cursor_is_visible(); + for (int i = 0; i < palette->get_item_count(); i++) { + if (palette->get_item_metadata(i).operator int() == p_tile) { + palette->select(i,true); + palette->ensure_current_is_visible(); break; } - item = item->get_next(); } } @@ -95,7 +92,7 @@ void TileMapEditor::_set_cell_shortened(const Point2& p_pos,int p_value,bool p_f ERR_FAIL_COND(!node); node->set_cell(floor(p_pos.x), floor(p_pos.y), p_value, p_flip_h, p_flip_v, p_transpose); } - + void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) { ERR_FAIL_COND(!node); @@ -120,42 +117,78 @@ void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bo } +void TileMapEditor::_set_display_mode(int p_mode) { + if (display_mode == p_mode) { + return; + } + + switch (p_mode) { + case DISPLAY_THUMBNAIL: { + button_thumbnail->set_pressed(true); + button_list->set_pressed(false); + } break; + case DISPLAY_LIST: { + button_thumbnail->set_pressed(false); + button_list->set_pressed(true); + } break; + } + + display_mode = p_mode; + + _update_palette(); +} + void TileMapEditor::_update_palette() { if (!node) return; - palette->clear();; + palette->clear(); Ref<TileSet> tileset=node->get_tileset(); if (!tileset.is_valid()) return; - - TreeItem *root = palette->create_item(); - palette->set_hide_root(true); List<int> tiles; tileset->get_tile_list(&tiles); - for(List<int>::Element *E=tiles.front();E;E=E->next()) { + if (display_mode == DISPLAY_THUMBNAIL) { + palette->set_max_columns(0); + palette->set_icon_mode(ItemList::ICON_MODE_TOP); + } else if (display_mode == DISPLAY_LIST) { + palette->set_max_columns(1); + palette->set_icon_mode(ItemList::ICON_MODE_LEFT); + } - TreeItem *tile = palette->create_item(root); + palette->set_max_text_lines(2); + + for(List<int>::Element *E=tiles.front();E;E=E->next()) { + palette->add_item(""); - tile->set_icon_max_width(0,64); Ref<Texture> tex = tileset->tile_get_texture(E->get()); + if (tex.is_valid()) { - tile->set_icon(0,tex); Rect2 region = tileset->tile_get_region(E->get()); - if (region!=Rect2()) - tile->set_icon_region(0,region); - } else if (tileset->tile_get_name(E->get())!="") - tile->set_text(0,tileset->tile_get_name(E->get())); - else - tile->set_text(0,"#"+itos(E->get())); + if (!region.has_no_area()) { + Image data = VS::get_singleton()->texture_get_data(tex->get_rid()); + + Ref<ImageTexture> img = memnew( ImageTexture ); + img->create_from_image(data.get_rect(region)); + + palette->set_item_icon(palette->get_item_count()-1, img); + } else { + palette->set_item_icon(palette->get_item_count()-1,tex); + } + } - tile->set_metadata(0,E->get()); + if (tileset->tile_get_name(E->get())!="") { + palette->set_item_text(palette->get_item_count()-1, tileset->tile_get_name(E->get())); + } else { + palette->set_item_text(palette->get_item_count()-1, "#"+itos(E->get())); + } + palette->set_item_metadata(palette->get_item_count()-1, E->get()); } } @@ -387,7 +420,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { } if (tool==TOOL_ERASING) { - Point2i local =over_tile; + Point2i local =over_tile; if (!paint_undo.has(over_tile)) { paint_undo[over_tile]=_get_op_from_cell(over_tile); } @@ -641,7 +674,7 @@ void TileMapEditor::_canvas_draw() { Ref<Texture> t = ts->tile_get_texture(st); if (t.is_valid()) { Vector2 from = node->map_to_world(over_tile)+node->get_cell_draw_offset(); - Rect2 r = ts->tile_get_region(st); + Rect2 r = ts->tile_get_region(st); Size2 sc = xform.get_scale(); if (mirror_x->is_pressed()) sc.x*=-1.0; @@ -755,7 +788,7 @@ void TileMapEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed); ObjectTypeDB::bind_method(_MD("_update_transform_buttons"),&TileMapEditor::_update_transform_buttons); ObjectTypeDB::bind_method(_MD("_set_cell_shortened","pos","tile","flip_x","flip_y","transpose"),&TileMapEditor::_set_cell_shortened,DEFVAL(false),DEFVAL(false),DEFVAL(false)); - + ObjectTypeDB::bind_method(_MD("_set_display_mode","mode"),&TileMapEditor::_set_display_mode); } TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos) @@ -777,7 +810,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) { //ERR_FAIL_NULL(p_button); ToolButton *b=p_button->cast_to<ToolButton>(); //ERR_FAIL_COND(!b); - + mirror_x->set_block_signals(true); mirror_y->set_block_signals(true); transpose->set_block_signals(true); @@ -785,7 +818,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) { rotate_90->set_block_signals(true); rotate_180->set_block_signals(true); rotate_270->set_block_signals(true); - + if (b == rotate_0) { mirror_x->set_pressed(false); mirror_y->set_pressed(false); @@ -806,7 +839,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) { mirror_y->set_pressed(true); transpose->set_pressed(true); } - + rotate_0->set_pressed(!mirror_x->is_pressed() && !mirror_y->is_pressed() && !transpose->is_pressed()); rotate_90->set_pressed(mirror_x->is_pressed() && !mirror_y->is_pressed() && transpose->is_pressed()); rotate_180->set_pressed(mirror_x->is_pressed() && mirror_y->is_pressed() && !transpose->is_pressed()); @@ -833,8 +866,27 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { ec->set_custom_minimum_size(Size2(mw,0)); add_child(ec); + HBoxContainer *hb = memnew( HBoxContainer ); + add_child(hb); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + hb->add_spacer(true); + + button_thumbnail = memnew( ToolButton ); + button_thumbnail->set_toggle_mode(true); + button_thumbnail->set_pressed(true); + button_thumbnail->set_icon(p_editor->get_gui_base()->get_icon("FileThumbnail","EditorIcons")); + hb->add_child(button_thumbnail); + button_thumbnail->connect("pressed", this, "_set_display_mode", varray(DISPLAY_THUMBNAIL)); + + button_list = memnew( ToolButton ); + button_list->set_toggle_mode(true); + button_list->set_pressed(false); + button_list->set_icon(p_editor->get_gui_base()->get_icon("FileList","EditorIcons")); + hb->add_child(button_list); + button_list->connect("pressed", this, "_set_display_mode", varray(DISPLAY_LIST)); + // Add tile palette - palette = memnew( Tree ); + palette = memnew( ItemList ); palette->set_v_size_flags(SIZE_EXPAND_FILL); add_child(palette); @@ -886,7 +938,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270)); canvas_item_editor_hb->add_child(rotate_270); canvas_item_editor_hb->hide(); - + rotate_0->set_pressed(true); tool=TOOL_NONE; selection_active=false; diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index eaa5c256d7..74d1573d0f 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -55,10 +55,18 @@ class TileMapEditor : public VBoxContainer { TOOL_PICKING }; + enum DisplayMode { + DISPLAY_THUMBNAIL, + DISPLAY_LIST + }; + Tool tool; Control *canvas_item_editor; - Tree *palette; + int display_mode; + ItemList *palette; + ToolButton *button_thumbnail; + ToolButton *button_list; EditorNode *editor; Panel *panel; TileMap *node; @@ -95,6 +103,7 @@ class TileMapEditor : public VBoxContainer { int get_selected_tile() const; void set_selected_tile(int p_tile); + void _set_display_mode(int p_mode); void _update_palette(); void _canvas_draw(); void _menu_option(int p_option); diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp index 374dda852b..e38c672a3e 100644 --- a/tools/editor/project_export.cpp +++ b/tools/editor/project_export.cpp @@ -563,7 +563,7 @@ void ProjectExportDialog::_update_group_list() { TreeItem *ti = groups->create_item(r); ti->set_text(0,E->get()); - ti->add_button(0,get_icon("Del","EditorIcons")); + ti->add_button(0,get_icon("Remove","EditorIcons")); if (E->get()==current) { ti->select(0); } @@ -1342,9 +1342,9 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) { expopt="--,Export,Bundle"; - file_export = memnew( FileDialog ); + file_export = memnew( EditorFileDialog ); add_child(file_export); - file_export->set_access(FileDialog::ACCESS_FILESYSTEM); + file_export->set_access(EditorFileDialog::ACCESS_FILESYSTEM); file_export->set_current_dir( EditorSettings::get_singleton()->get("global/default_project_export_path") ); file_export->set_title("Export Project"); @@ -1361,8 +1361,8 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) { file_export_password->set_editable(false); file_export->get_vbox()->add_margin_child("Password:",file_export_password); - pck_export = memnew( FileDialog ); - pck_export->set_access(FileDialog::ACCESS_FILESYSTEM); + pck_export = memnew( EditorFileDialog ); + pck_export->set_access(EditorFileDialog::ACCESS_FILESYSTEM); pck_export->set_current_dir( EditorSettings::get_singleton()->get("global/default_project_export_path") ); pck_export->set_title("Export Project PCK"); pck_export->connect("file_selected", this,"_export_action_pck"); @@ -1653,7 +1653,7 @@ Error ProjectExport::export_project(const String& p_preset) { if (saver.is_null()) { memdelete(d); - ERR_EXPLAIN("Preset '"+preset+"' references unexisting saver: "+type); + ERR_EXPLAIN("Preset '"+preset+"' references nonexistent saver: "+type); ERR_FAIL_COND_V(saver.is_null(),ERR_INVALID_DATA); } diff --git a/tools/editor/project_export.h b/tools/editor/project_export.h index 08d19e1751..c88233ae01 100644 --- a/tools/editor/project_export.h +++ b/tools/editor/project_export.h @@ -33,7 +33,7 @@ #include "scene/gui/control.h" #include "scene/gui/tree.h" #include "scene/gui/label.h" -#include "scene/gui/file_dialog.h" +#include "tools/editor/editor_file_dialog.h" #include "scene/gui/button.h" #include "scene/gui/dialogs.h" #include "scene/gui/tab_container.h" @@ -80,8 +80,8 @@ private: Tree * tree; - FileDialog *pck_export; - FileDialog *file_export; + EditorFileDialog *pck_export; + EditorFileDialog *file_export; CheckButton *file_export_check; LineEdit *file_export_password; diff --git a/tools/editor/project_settings.cpp b/tools/editor/project_settings.cpp index 08a1191f41..fea9c705ef 100644 --- a/tools/editor/project_settings.cpp +++ b/tools/editor/project_settings.cpp @@ -415,7 +415,7 @@ void ProjectSettings::_update_actions() { item->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); item->set_text(0,name); item->add_button(0,get_icon("Add","EditorIcons"),1); - item->add_button(0,get_icon("Del","EditorIcons"),2); + item->add_button(0,get_icon("Remove","EditorIcons"),2); item->set_custom_bg_color(0,get_color("prop_subsection","Editor")); item->set_editable(0,true); item->set_checked(0,pi.usage&PROPERTY_USAGE_CHECKED); @@ -483,7 +483,7 @@ void ProjectSettings::_update_actions() { action->set_icon(0,get_icon("JoyAxis","EditorIcons")); } break; } - action->add_button(0,get_icon("Del","EditorIcons"),2); + action->add_button(0,get_icon("Remove","EditorIcons"),2); action->set_metadata(0,i); } } @@ -1450,9 +1450,9 @@ ProjectSettings::ProjectSettings(EditorData *p_data) { translation_list->set_v_size_flags(SIZE_EXPAND_FILL); tmc->add_child(translation_list); - translation_file_open=memnew( FileDialog ); + translation_file_open=memnew( EditorFileDialog ); add_child(translation_file_open); - translation_file_open->set_mode(FileDialog::MODE_OPEN_FILE); + translation_file_open->set_mode(EditorFileDialog::MODE_OPEN_FILE); translation_file_open->connect("file_selected",this,"_translation_add"); } @@ -1477,9 +1477,9 @@ ProjectSettings::ProjectSettings(EditorData *p_data) { tmc->add_child(translation_remap); translation_remap->connect("button_pressed",this,"_translation_res_delete"); - translation_res_file_open=memnew( FileDialog ); + translation_res_file_open=memnew( EditorFileDialog ); add_child(translation_res_file_open); - translation_res_file_open->set_mode(FileDialog::MODE_OPEN_FILE); + translation_res_file_open->set_mode(EditorFileDialog::MODE_OPEN_FILE); translation_res_file_open->connect("file_selected",this,"_translation_res_add"); thb = memnew( HBoxContainer); @@ -1507,9 +1507,9 @@ ProjectSettings::ProjectSettings(EditorData *p_data) { translation_remap_options->connect("item_edited",this,"_translation_res_option_changed"); translation_remap_options->connect("button_pressed",this,"_translation_res_option_delete"); - translation_res_option_file_open=memnew( FileDialog ); + translation_res_option_file_open=memnew( EditorFileDialog ); add_child(translation_res_option_file_open); - translation_res_option_file_open->set_mode(FileDialog::MODE_OPEN_FILE); + translation_res_option_file_open->set_mode(EditorFileDialog::MODE_OPEN_FILE); translation_res_option_file_open->connect("file_selected",this,"_translation_res_option_add"); } @@ -1548,9 +1548,9 @@ ProjectSettings::ProjectSettings(EditorData *p_data) { autoload_list->set_v_size_flags(SIZE_EXPAND_FILL); avb->add_margin_child("List:",autoload_list,true); - autoload_file_open=memnew( FileDialog ); + autoload_file_open=memnew( EditorFileDialog ); add_child(autoload_file_open); - autoload_file_open->set_mode(FileDialog::MODE_OPEN_FILE); + autoload_file_open->set_mode(EditorFileDialog::MODE_OPEN_FILE); autoload_file_open->connect("file_selected",this,"_autoload_file_callback"); autoload_list->set_columns(2); diff --git a/tools/editor/project_settings.h b/tools/editor/project_settings.h index 8e40407d3e..7c91254764 100644 --- a/tools/editor/project_settings.h +++ b/tools/editor/project_settings.h @@ -67,19 +67,19 @@ class ProjectSettings : public AcceptDialog { InputEvent last_wait_for_key; - FileDialog *translation_file_open; + EditorFileDialog *translation_file_open; Tree *translation_list; Button *translation_res_option_add_button; - FileDialog *translation_res_file_open; - FileDialog *translation_res_option_file_open; + EditorFileDialog *translation_res_file_open; + EditorFileDialog *translation_res_option_file_open; Tree *translation_remap; Tree *translation_remap_options; Tree *autoload_list; - FileDialog *autoload_file_open; + EditorFileDialog *autoload_file_open; LineEdit *autoload_add_name; LineEdit *autoload_add_path; diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 1c6e57beaa..2fa8b98ff1 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -83,7 +83,7 @@ void CustomPropertyEditor::_menu_option(int p_which) { switch(p_which) { case OBJ_MENU_LOAD: { - file->set_mode(FileDialog::MODE_OPEN_FILE); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); List<String> extensions; String type=(hint==PROPERTY_HINT_RESOURCE_TYPE)?hint_text:String(); @@ -908,11 +908,11 @@ void CustomPropertyEditor::_action_pressed(int p_which) { if (p_which==0) { if (hint==PROPERTY_HINT_FILE) - file->set_access(FileDialog::ACCESS_RESOURCES); + file->set_access(EditorFileDialog::ACCESS_RESOURCES); else - file->set_access(FileDialog::ACCESS_FILESYSTEM); + file->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - file->set_mode(FileDialog::MODE_OPEN_FILE); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); file->clear_filters(); file->clear_filters(); @@ -946,10 +946,10 @@ void CustomPropertyEditor::_action_pressed(int p_which) { if (p_which==0) { if (hint==PROPERTY_HINT_DIR) - file->set_access(FileDialog::ACCESS_RESOURCES); + file->set_access(EditorFileDialog::ACCESS_RESOURCES); else - file->set_access(FileDialog::ACCESS_FILESYSTEM); - file->set_mode(FileDialog::MODE_OPEN_DIR); + file->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + file->set_mode(EditorFileDialog::MODE_OPEN_DIR); file->clear_filters(); file->popup_centered_ratio(); } else { @@ -1001,8 +1001,8 @@ void CustomPropertyEditor::_action_pressed(int p_which) { } } else if (p_which==1) { - file->set_access(FileDialog::ACCESS_RESOURCES); - file->set_mode(FileDialog::MODE_OPEN_FILE); + file->set_access(EditorFileDialog::ACCESS_RESOURCES); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); List<String> extensions; String type=(hint==PROPERTY_HINT_RESOURCE_TYPE)?hint_text:String(); @@ -1081,8 +1081,8 @@ void CustomPropertyEditor::_action_pressed(int p_which) { } else if (p_which==1) { - file->set_access(FileDialog::ACCESS_RESOURCES); - file->set_mode(FileDialog::MODE_OPEN_FILE); + file->set_access(EditorFileDialog::ACCESS_RESOURCES); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); List<String> extensions; ImageLoader::get_recognized_extensions(&extensions); @@ -1612,7 +1612,7 @@ CustomPropertyEditor::CustomPropertyEditor() { color_picker->connect("color_changed",this,"_color_changed"); set_as_toplevel(true); - file = memnew ( FileDialog ); + file = memnew ( EditorFileDialog ); add_child(file); file->hide(); @@ -1633,7 +1633,7 @@ CustomPropertyEditor::CustomPropertyEditor() { scene_tree = memnew( SceneTreeDialog ); add_child(scene_tree); scene_tree->connect("selected", this,"_node_path_selected"); - scene_tree->get_tree()->set_show_enabled_subscene(true); + scene_tree->get_scene_tree()->set_show_enabled_subscene(true); texture_preview = memnew( TextureFrame ); add_child( texture_preview); @@ -1915,6 +1915,7 @@ void PropertyEditor::_notification(int p_what) { } if (p_what==NOTIFICATION_EXIT_TREE) { + get_tree()->disconnect("node_removed",this,"_node_removed"); edit(NULL); } @@ -2629,7 +2630,12 @@ void PropertyEditor::update_tree() { if (keying) { - item->add_button(1,get_icon("Key","EditorIcons"),2); + if (p.hint==PROPERTY_HINT_SPRITE_FRAME) { + + item->add_button(1,get_icon("KeyNext","EditorIcons"),5); + } else { + item->add_button(1,get_icon("Key","EditorIcons"),2); + } } if (get_instanced_node()) { @@ -2904,6 +2910,16 @@ void PropertyEditor::edit(Object* p_object) { } +void PropertyEditor::_set_range_def(Object *p_item, String prop,float p_frame) { + + TreeItem *ti = p_item->cast_to<TreeItem>(); + ERR_FAIL_COND(!ti); + + ti->call_deferred("set_range",1, p_frame); + obj->call_deferred("set",prop,p_frame); + +} + void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) { TreeItem *ti = p_item->cast_to<TreeItem>(); ERR_FAIL_COND(!ti); @@ -2915,7 +2931,15 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) { if (!d.has("name")) return; String prop=d["name"]; - emit_signal("property_keyed",prop,obj->get(prop)); + emit_signal("property_keyed",prop,obj->get(prop),false); + } else if (p_button==5) { + print_line("PB5"); + if (!d.has("name")) + return; + String prop=d["name"]; + emit_signal("property_keyed",prop,obj->get(prop),true); + //set_range(p_column, ti->get_range(p_column)+1.0 ); + call_deferred("_set_range_def",ti,prop,ti->get_range(p_column)+1.0); } else if (p_button==3) { if (!get_instanced_node()) @@ -3046,6 +3070,7 @@ void PropertyEditor::_bind_methods() { ObjectTypeDB::bind_method( "_edit_button",&PropertyEditor::_edit_button); ObjectTypeDB::bind_method( "_changed_callback",&PropertyEditor::_changed_callbacks); ObjectTypeDB::bind_method( "_draw_flags",&PropertyEditor::_draw_flags); + ObjectTypeDB::bind_method( "_set_range_def",&PropertyEditor::_set_range_def); ADD_SIGNAL( MethodInfo("property_toggled",PropertyInfo( Variant::STRING, "property"),PropertyInfo( Variant::BOOL, "value"))); ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) ); diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index 7a7354c88e..de5cac8711 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -32,7 +32,7 @@ #include "scene/gui/tree.h" #include "scene/gui/button.h" #include "scene/gui/label.h" -#include "scene/gui/file_dialog.h" +#include "tools/editor/editor_file_dialog.h" #include "scene/gui/dialogs.h" #include "scene/gui/color_picker.h" #include "scene/gui/menu_button.h" @@ -75,7 +75,7 @@ class CustomPropertyEditor : public Popup { PopupMenu *menu; SceneTreeDialog *scene_tree; - FileDialog *file; + EditorFileDialog *file; ConfirmationDialog *error; String name; Variant::Type type; @@ -187,6 +187,7 @@ class PropertyEditor : public Control { Node *get_instanced_node(); void _refresh_item(TreeItem *p_item); + void _set_range_def(Object *p_item, String prop, float p_frame); UndoRedo *undo_redo; protected: diff --git a/tools/editor/reparent_dialog.cpp b/tools/editor/reparent_dialog.cpp index d35316f67f..6d0c5b867e 100644 --- a/tools/editor/reparent_dialog.cpp +++ b/tools/editor/reparent_dialog.cpp @@ -41,6 +41,11 @@ void ReparentDialog::_notification(int p_what) { connect("confirmed", this,"_reparent"); } + if (p_what==NOTIFICATION_EXIT_TREE) { + + disconnect("confirmed", this,"_reparent"); + } + if (p_what==NOTIFICATION_DRAW) { //RID ci = get_canvas_item(); diff --git a/tools/editor/resources_dock.cpp b/tools/editor/resources_dock.cpp index 33ec1f2054..b69eec4a51 100644 --- a/tools/editor/resources_dock.cpp +++ b/tools/editor/resources_dock.cpp @@ -152,7 +152,7 @@ void ResourcesDock::save_resource_as(const Ref<Resource>& p_resource) { List<String> extensions; ResourceSaver::get_recognized_extensions(res,&extensions); - file->set_mode(FileDialog::MODE_SAVE_FILE); + file->set_mode(EditorFileDialog::MODE_SAVE_FILE); if (p_resource->get_path()!="" && p_resource->get_path().find("::")==-1) { @@ -396,7 +396,7 @@ ResourcesDock::ResourcesDock(EditorNode *p_editor) { accept = memnew (AcceptDialog); add_child(accept); - file = memnew( FileDialog ); + file = memnew( EditorFileDialog ); add_child(file); file->connect("file_selected",this,"_file_action"); diff --git a/tools/editor/resources_dock.h b/tools/editor/resources_dock.h index a94579240e..933b457b29 100644 --- a/tools/editor/resources_dock.h +++ b/tools/editor/resources_dock.h @@ -38,6 +38,7 @@ #include "scene/gui/menu_button.h" #include "scene/gui/file_dialog.h" #include "create_dialog.h" +#include "editor_file_dialog.h" class EditorNode; @@ -68,7 +69,7 @@ class ResourcesDock : public VBoxContainer { CreateDialog *create_dialog; AcceptDialog *accept; - FileDialog *file; + EditorFileDialog *file; Tree *resources; bool block_add; int current_action; diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 87a13ee9ce..49cbebdb43 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -171,7 +171,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (!_validate_no_foreign()) break; - file->set_mode(FileDialog::MODE_OPEN_FILE); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); List<String> extensions; ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); file->clear_filters(); @@ -471,8 +471,18 @@ void SceneTreeDock::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_TREE: { + case NOTIFICATION_READY: { + + if (!first_enter) + break; + first_enter=false; + CanvasItemEditorPlugin *canvas_item_plugin = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>(); + if (canvas_item_plugin) { + canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree"); + canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree"); + scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update"); + } static const char* button_names[TOOL_BUTTON_MAX]={ "New", "Add", @@ -484,22 +494,15 @@ void SceneTreeDock::_notification(int p_what) { "MoveDown", "Duplicate", "Reparent", - "Del", + "Remove", }; + + for(int i=0;i<TOOL_BUTTON_MAX;i++) tool_buttons[i]->set_icon(get_icon(button_names[i],"EditorIcons")); } break; - case NOTIFICATION_READY: { - - CanvasItemEditorPlugin *canvas_item_plugin = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>(); - if (canvas_item_plugin) { - canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree"); - canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree"); - scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update"); - } - } break; } } @@ -1355,7 +1358,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec accept = memnew( AcceptDialog ); add_child(accept); - file = memnew( FileDialog ); + file = memnew( EditorFileDialog ); add_child(file); file->connect("file_selected",this,"instance"); set_process_unhandled_key_input(true); @@ -1367,7 +1370,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec add_child(import_subscene_dialog); import_subscene_dialog->connect("subscene_selected",this,"_import_subscene"); - + first_enter=true; } diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index e1a4a10e58..f0bbbad6be 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -87,9 +87,10 @@ class SceneTreeDock : public VBoxContainer { ConfirmationDialog *delete_dialog; ReparentDialog *reparent_dialog; - FileDialog *file; + EditorFileDialog *file; EditorSubScene *import_subscene_dialog; + bool first_enter; void _create(); Node *scene_root; @@ -133,6 +134,7 @@ public: void set_selected(Node *p_node, bool p_emit_selected=false); void fill_path_renames(Node* p_node, Node *p_new_parent, List<Pair<NodePath,NodePath> > *p_renames); void perform_node_renames(Node* p_base,List<Pair<NodePath,NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims=NULL); + SceneTreeEditor *get_tree_editor() { return scene_tree; } SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelection *p_editor_selection,EditorData &p_editor_data); }; diff --git a/tools/editor/scene_tree_editor.cpp b/tools/editor/scene_tree_editor.cpp index 94eea969fe..fd841028a2 100644 --- a/tools/editor/scene_tree_editor.cpp +++ b/tools/editor/scene_tree_editor.cpp @@ -498,6 +498,7 @@ void SceneTreeEditor::_notification(int p_what) { get_tree()->disconnect("tree_changed",this,"_tree_changed"); get_tree()->disconnect("node_removed",this,"_node_removed"); + tree->disconnect("item_collapsed",this,"_cell_collapsed"); _update_tree(); } @@ -810,6 +811,11 @@ void SceneTreeDialog::_notification(int p_what) { connect("confirmed", this,"_select"); } + + if (p_what==NOTIFICATION_EXIT_TREE) { + disconnect("confirmed", this,"_select"); + + } if (p_what==NOTIFICATION_DRAW) { RID ci = get_canvas_item(); diff --git a/tools/editor/scene_tree_editor.h b/tools/editor/scene_tree_editor.h index 3e57ffb497..b05a52a2da 100644 --- a/tools/editor/scene_tree_editor.h +++ b/tools/editor/scene_tree_editor.h @@ -125,6 +125,9 @@ public: void update_tree() { _update_tree(); } + + Tree* get_scene_tree() { return tree; } + SceneTreeEditor(bool p_label=true,bool p_can_rename=false, bool p_can_open_instance=false); ~SceneTreeEditor(); @@ -150,7 +153,7 @@ protected: static void _bind_methods(); public: - SceneTreeEditor *get_tree() { return tree; } + SceneTreeEditor *get_scene_tree() { return tree; } SceneTreeDialog(); ~SceneTreeDialog(); diff --git a/tools/editor/script_create_dialog.cpp b/tools/editor/script_create_dialog.cpp index 35f7798ed5..bdfb66f0f2 100644 --- a/tools/editor/script_create_dialog.cpp +++ b/tools/editor/script_create_dialog.cpp @@ -184,7 +184,7 @@ void ScriptCreateDialog::_built_in_pressed() { void ScriptCreateDialog::_browse_path() { - file_browse->set_mode(FileDialog::MODE_SAVE_FILE); + file_browse->set_mode(EditorFileDialog::MODE_SAVE_FILE); file_browse->clear_filters(); List<String> extensions; @@ -365,7 +365,7 @@ ScriptCreateDialog::ScriptCreateDialog() { set_hide_on_ok(false); set_title("Create Script for Node..");; - file_browse = memnew( FileDialog ); + file_browse = memnew( EditorFileDialog ); file_browse->connect("file_selected",this,"_file_selected"); add_child(file_browse); get_ok()->set_text("Create"); diff --git a/tools/editor/script_create_dialog.h b/tools/editor/script_create_dialog.h index 61f5df4341..59fde8fbd5 100644 --- a/tools/editor/script_create_dialog.h +++ b/tools/editor/script_create_dialog.h @@ -32,7 +32,7 @@ #include "scene/gui/dialogs.h" #include "scene/gui/line_edit.h" #include "scene/gui/option_button.h" -#include "scene/gui/file_dialog.h" +#include "tools/editor/editor_file_dialog.h" #include "scene/gui/check_button.h" class ScriptCreateDialog : public ConfirmationDialog { @@ -44,7 +44,7 @@ class ScriptCreateDialog : public ConfirmationDialog { LineEdit *parent_name; OptionButton *language_menu; LineEdit *file_path; - FileDialog *file_browse; + EditorFileDialog *file_browse; CheckButton *internal; VBoxContainer *path_vb; AcceptDialog *alert; |