diff options
Diffstat (limited to 'scene')
28 files changed, 775 insertions, 592 deletions
diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index da49f1b420..77ace0348a 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -27,6 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "particles_2d.h" +#include "scene/scene_string_names.h" @@ -227,21 +228,10 @@ ParticleAttractor2D::ParticleAttractor2D() { /****************************************/ -_FORCE_INLINE_ static float _rand_from_seed(uint32_t *seed) { +_FORCE_INLINE_ static float _rand_from_seed(uint64_t *seed) { - uint32_t k; - uint32_t s = (*seed); - if (s == 0) - s = 0x12345987; - k = s / 127773; - s = 16807 * (s - k * 127773) - 2836 * k; - if (s < 0) - s += 2147483647; - (*seed) = s; - - float v=((float)((*seed) & 0xFFFFF))/(float)0xFFFFF; - v=v*2.0-1.0; - return v; + uint32_t r = Math::rand_from_seed(seed); + return 2.0f * (float)r / (float)Math::RANDOM_MAX - 1.0f; } void Particles2D::_process_particles(float p_delta) { @@ -348,7 +338,7 @@ void Particles2D::_process_particles(float p_delta) { } } p.seed=Math::rand() % 12345678; - uint32_t rand_seed=p.seed*(i+1); + uint64_t rand_seed=p.seed*(i+1); float angle = Math::deg2rad(param[PARAM_DIRECTION]+_rand_from_seed(&rand_seed)*param[PARAM_SPREAD]); @@ -377,7 +367,7 @@ void Particles2D::_process_particles(float p_delta) { if (!p.active) continue; - uint32_t rand_seed=p.seed*(i+1); + uint64_t rand_seed=p.seed*(i+1); Vector2 force; @@ -451,8 +441,9 @@ void Particles2D::_process_particles(float p_delta) { time=Math::fmod( time+frame_time, lifetime ); if (!emitting && active_count==0) { + emit_signal(SceneStringNames::get_singleton()->emission_finished); set_process(false); - + set_fixed_process(false); } update(); @@ -470,6 +461,11 @@ void Particles2D::_notification(int p_what) { _process_particles( get_process_delta_time() ); } break; + case NOTIFICATION_FIXED_PROCESS: { + + _process_particles( get_fixed_process_delta_time() ); + } break; + case NOTIFICATION_ENTER_TREE: { float ppt=preprocess; @@ -530,7 +526,7 @@ void Particles2D::_notification(int p_what) { else ptime=(1.0-ptime)+time_pos; - uint32_t rand_seed=p.seed*(i+1); + uint64_t rand_seed=p.seed*(i+1); Color color; @@ -695,7 +691,8 @@ void Particles2D::set_emitting(bool p_emitting) { if (active_count==0) time=0; - set_process(true); + set_process(process_mode==PROCESS_IDLE); + set_fixed_process(process_mode==PROCESS_FIXED); time_to_live = emit_timeout; }; emitting=p_emitting; @@ -707,6 +704,19 @@ bool Particles2D::is_emitting() const { return emitting; } +void Particles2D::set_process_mode(ProcessMode p_mode) { + + process_mode=p_mode; + const bool should_process=emitting || active_count!=0; + set_process(should_process && process_mode==PROCESS_IDLE); + set_fixed_process(should_process && process_mode==PROCESS_FIXED); +} + +Particles2D::ProcessMode Particles2D::get_process_mode() const { + + return process_mode; +} + void Particles2D::set_amount(int p_amount) { ERR_FAIL_INDEX(p_amount,1024+1); @@ -918,15 +928,6 @@ Vector2 Particles2D::get_emission_half_extents() const { return extents; } -void Particles2D::testee(int a, int b, int c, int d, int e) { - - print_line(itos(a)); - print_line(itos(b)); - print_line(itos(c)); - print_line(itos(d)); - print_line(itos(e)); -} - void Particles2D::set_initial_velocity(const Vector2& p_velocity) { @@ -1020,6 +1021,9 @@ void Particles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emitting","active"),&Particles2D::set_emitting); ClassDB::bind_method(D_METHOD("is_emitting"),&Particles2D::is_emitting); + ClassDB::bind_method(D_METHOD("set_process_mode","mode"),&Particles2D::set_process_mode); + ClassDB::bind_method(D_METHOD("get_process_mode"),&Particles2D::get_process_mode); + ClassDB::bind_method(D_METHOD("set_amount","amount"),&Particles2D::set_amount); ClassDB::bind_method(D_METHOD("get_amount"),&Particles2D::get_amount); @@ -1092,12 +1096,15 @@ void Particles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emission_points","points"),&Particles2D::set_emission_points); ClassDB::bind_method(D_METHOD("get_emission_points"),&Particles2D::get_emission_points); + ADD_SIGNAL(MethodInfo("emission_finished")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"config/amount",PROPERTY_HINT_EXP_RANGE,"1,1024"),"set_amount","get_amount") ; ADD_PROPERTY(PropertyInfo(Variant::REAL,"config/lifetime",PROPERTY_HINT_EXP_RANGE,"0.1,3600,0.1"),"set_lifetime","get_lifetime") ; ADD_PROPERTYNO(PropertyInfo(Variant::REAL,"config/time_scale",PROPERTY_HINT_EXP_RANGE,"0.01,128,0.01"),"set_time_scale","get_time_scale") ; ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"config/preprocess",PROPERTY_HINT_EXP_RANGE,"0.1,3600,0.1"),"set_pre_process_time","get_pre_process_time") ; ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"config/emit_timeout",PROPERTY_HINT_RANGE,"0,3600,0.1"),"set_emit_timeout","get_emit_timeout") ; ADD_PROPERTYNO(PropertyInfo(Variant::BOOL,"config/emitting"),"set_emitting","is_emitting") ; + ADD_PROPERTY(PropertyInfo(Variant::INT,"config/process_mode",PROPERTY_HINT_ENUM, "Fixed,Idle"),"set_process_mode","get_process_mode"); ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"config/offset"),"set_emissor_offset","get_emissor_offset"); ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"config/half_extents"),"set_emission_half_extents","get_emission_half_extents"); ADD_PROPERTYNO(PropertyInfo(Variant::BOOL,"config/local_space"),"set_use_local_space","is_using_local_space"); @@ -1180,6 +1187,7 @@ Particles2D::Particles2D() { particles.resize(32); active_count=-1; set_emitting(true); + process_mode=PROCESS_IDLE; local_space=true; preprocess=0; time_scale=1.0; diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h index 91f42c5222..c6ababe3be 100644 --- a/scene/2d/particles_2d.h +++ b/scene/2d/particles_2d.h @@ -111,6 +111,11 @@ public: MAX_COLOR_PHASES=4 }; + enum ProcessMode { + PROCESS_FIXED, + PROCESS_IDLE, + }; + private: float param[PARAM_MAX]; @@ -122,7 +127,7 @@ private: Vector2 velocity; float rot; float frame; - uint32_t seed; + uint64_t seed; Particle() { active=false; seed=123465789; rot=0; frame=0;} }; @@ -153,6 +158,8 @@ private: Vector2 extents; PoolVector<Vector2> emission_points; + ProcessMode process_mode; + float time; int active_count; @@ -162,7 +169,6 @@ private: Color default_color; Ref<ColorRamp> color_ramp; - void testee(int a, int b, int c, int d, int e); void _process_particles(float p_delta); friend class ParticleAttractor2D; @@ -178,6 +184,9 @@ public: void set_emitting(bool p_emitting); bool is_emitting() const; + void set_process_mode(ProcessMode p_mode); + ProcessMode get_process_mode() const; + void set_amount(int p_amount); int get_amount() const; @@ -254,6 +263,7 @@ public: Particles2D(); }; +VARIANT_ENUM_CAST( Particles2D::ProcessMode ); VARIANT_ENUM_CAST( Particles2D::Parameter ); #endif // PARTICLES_FRAME_H diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp index efe23e67f2..4b607e9261 100644 --- a/scene/2d/screen_button.cpp +++ b/scene/2d/screen_button.cpp @@ -308,12 +308,14 @@ void TouchScreenButton::_release(bool p_exiting_tree) { if (action_id!=-1) { Input::get_singleton()->action_release(action); - InputEvent ie; - ie.type=InputEvent::ACTION; - ie.ID=0; - ie.action.action=action_id; - ie.action.pressed=false; - get_tree()->input_event(ie); + if (!p_exiting_tree) { + InputEvent ie; + ie.type=InputEvent::ACTION; + ie.ID=0; + ie.action.action=action_id; + ie.action.pressed=false; + get_tree()->input_event(ie); + } } if (!p_exiting_tree) { diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 5de0b93ed9..15fbec4441 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -730,6 +730,7 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bo c.transpose=p_transpose; _make_quadrant_dirty(Q); + used_size_cache_dirty=true; } @@ -818,6 +819,7 @@ void TileMap::clear() { _clear_quadrants(); tile_map.clear(); + used_size_cache_dirty=true; } void TileMap::_set_tile_data(const PoolVector<int>& p_data) { @@ -1159,6 +1161,28 @@ Array TileMap::get_used_cells() const { return a; } +Rect2 TileMap::get_used_rect() { // Not const because of cache + + if (used_size_cache_dirty) { + if(tile_map.size() > 0) { + used_size_cache = Rect2(tile_map.front()->key().x, tile_map.front()->key().y, 0, 0); + + for (Map<PosKey,Cell>::Element *E=tile_map.front();E;E=E->next()) { + used_size_cache.expand_to(Vector2(E->key().x, E->key().y)); + } + + used_size_cache.size += Vector2(1,1); + } else { + used_size_cache = Rect2(); + } + + used_size_cache_dirty = false; + } + + return used_size_cache; +} + + void TileMap::set_occluder_light_mask(int p_mask) { occluder_light_mask=p_mask; @@ -1251,6 +1275,7 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("clear"),&TileMap::clear); ClassDB::bind_method(D_METHOD("get_used_cells"),&TileMap::get_used_cells); + ClassDB::bind_method(D_METHOD("get_used_rect"),&TileMap::get_used_rect); ClassDB::bind_method(D_METHOD("map_to_world","mappos","ignore_half_ofs"),&TileMap::map_to_world,DEFVAL(false)); ClassDB::bind_method(D_METHOD("world_to_map","worldpos"),&TileMap::world_to_map); @@ -1305,6 +1330,7 @@ TileMap::TileMap() { rect_cache_dirty=true; + used_size_cache_dirty=true; pending_update=false; quadrant_order_dirty=false; quadrant_size=16; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index ba6de62f8e..c581aa8056 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -141,6 +141,8 @@ private: Rect2 rect_cache; bool rect_cache_dirty; + Rect2 used_size_cache; + bool used_size_cache_dirty; bool quadrant_order_dirty; bool y_sort_mode; float fp_adjust; @@ -176,8 +178,6 @@ private: _FORCE_INLINE_ Vector2 _map_to_world(int p_x,int p_y,bool p_ignore_ofs=false) const; - Array get_used_cells() const; - protected: @@ -252,6 +252,9 @@ public: void set_y_sort_mode(bool p_enable); bool is_y_sort_mode_enabled() const; + Array get_used_cells() const; + Rect2 get_used_rect(); // Not const because of cache + void set_occluder_light_mask(int p_mask); int get_occluder_light_mask() const; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index dabdde8ece..e9f1904fe9 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -588,35 +588,26 @@ void AnimationPlayer::_animation_process2(float p_delta) { Playback &c=playback; - float prev_blend=1.0; accum_pass++; - int pop_count=1; - int pop=0; // if >0, then amount of elements to pop from the back + _animation_process_data(c.current,p_delta,1.0f); - - for (List<Blend>::Element *E=c.blend.back();E;E=E->prev(),pop_count++) { + List<Blend>::Element *prev = NULL; + for (List<Blend>::Element *E=c.blend.back();E;E=prev) { Blend& b=E->get(); - _animation_process_data(b.data,p_delta,prev_blend); - - prev_blend=1.0-b.blend_left/b.blend_time; + float blend=b.blend_left/b.blend_time; + _animation_process_data(b.data,p_delta,blend); b.blend_left-=Math::absf(speed_scale*p_delta); + prev = E->prev(); if (b.blend_left<0) { - pop=pop_count; + c.blend.erase(E); } } - - while(pop--) { - - c.blend.pop_back(); - } - - - _animation_process_data(c.current,p_delta,prev_blend); + } diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index ed4ec23d54..d7e98ddd2b 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -711,7 +711,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode else rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_time*tsn->scale,false,p_fallback_weight,p_weights); if (tsn->scale == 0) - return INFINITY; + return Math_INF; else return rem / tsn->scale; diff --git a/scene/animation/tween_interpolaters.cpp b/scene/animation/tween_interpolaters.cpp index 5ba9673014..25a27252f5 100644 --- a/scene/animation/tween_interpolaters.cpp +++ b/scene/animation/tween_interpolaters.cpp @@ -262,7 +262,8 @@ namespace cubic { static real_t out(real_t t, real_t b, real_t c, real_t d) { - return c * ((t = t / d - 1) * t * t + 1) + b; + t = t / d - 1; + return c * (t * t * t + 1) + b; } static real_t in_out(real_t t, real_t b, real_t c, real_t d) diff --git a/scene/gui/button_array.cpp b/scene/gui/button_array.cpp index c05b787bf5..2fd5f0df83 100644 --- a/scene/gui/button_array.cpp +++ b/scene/gui/button_array.cpp @@ -58,9 +58,10 @@ bool ButtonArray::_set(const StringName& p_name, const Variant& p_value) { int idx=what.to_int(); ERR_FAIL_INDEX_V(idx,buttons.size(),false); String f = n.get_slicec('/',2); - if (f=="text") + if (f=="text") { buttons[idx].text=p_value; - else if (f=="tooltip") + buttons[idx].xl_text=XL_MESSAGE(p_value); + } else if (f=="tooltip") buttons[idx].tooltip=p_value; else if (f=="icon") buttons[idx].icon=p_value; @@ -146,7 +147,7 @@ Size2 ButtonArray::get_minimum_size() const { Ref<Font> f = i==selected ? font_selected : font_normal; Size2 ms; - ms = f->get_string_size(buttons[i].text); + ms = f->get_string_size(buttons[i].xl_text); if (buttons[i].icon.is_valid()) { Size2 bs = buttons[i].icon->get_size(); @@ -275,7 +276,7 @@ void ButtonArray::_notification(int p_what) { c=color_normal; } - Size2 ssize = f->get_string_size(buttons[i].text); + Size2 ssize = f->get_string_size(buttons[i].xl_text); if (buttons[i].icon.is_valid()) { ssize.x+=buttons[i].icon->get_width(); @@ -287,7 +288,7 @@ void ButtonArray::_notification(int p_what) { text_ofs.x+=buttons[i].icon->get_width()+icon_sep; } - draw_string(f,text_ofs+r.pos,buttons[i].text,c); + draw_string(f,text_ofs+r.pos,buttons[i].xl_text,c); buttons[i]._pos_cache=ofs; buttons[i]._size_cache=s; @@ -404,6 +405,7 @@ void ButtonArray::add_button(const String& p_text,const String& p_tooltip) { Button button; button.text=p_text; + button.xl_text=XL_MESSAGE(p_text); button.tooltip=p_tooltip; buttons.push_back(button); update(); @@ -418,6 +420,7 @@ void ButtonArray::add_icon_button(const Ref<Texture>& p_icon,const String& p_tex Button button; button.text=p_text; + button.xl_text=XL_MESSAGE(p_text); button.icon=p_icon; button.tooltip=p_tooltip; buttons.push_back(button); @@ -432,6 +435,7 @@ void ButtonArray::set_button_text(int p_button, const String& p_text) { ERR_FAIL_INDEX(p_button,buttons.size()); buttons[p_button].text=p_text; + buttons[p_button].xl_text=XL_MESSAGE(p_text); update(); minimum_size_changed(); diff --git a/scene/gui/button_array.h b/scene/gui/button_array.h index 37533695c9..4865ef0373 100644 --- a/scene/gui/button_array.h +++ b/scene/gui/button_array.h @@ -50,6 +50,7 @@ private: struct Button { String text; + String xl_text; String tooltip; Ref<Texture> icon; mutable int _ms_cache; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index cffe2ce218..4161725ad5 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2421,8 +2421,6 @@ void Control::get_argument_options(const StringName& p_function,int p_idx,List<S Theme::get_default()->get_font_list(get_class(),&sn); } else if (pf=="add_constant_override" || pf=="has_constant" || pf=="has_constant_override" || pf=="get_constant") { Theme::get_default()->get_constant_list(get_class(),&sn); - } else if (pf=="add_color_override" || pf=="has_color" || pf=="has_color_override" || pf=="get_color") { - Theme::get_default()->get_color_list(get_class(),&sn); } sn.sort_custom<StringName::AlphCompare>(); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 72d3f0e8f8..e889d1acd3 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -33,76 +33,145 @@ void WindowDialog::_post_popup() { - dragging=false; //just in case + drag_type = DRAG_NONE; // just in case } bool WindowDialog::has_point(const Point2& p_point) const { + Rect2 r(Point2(), get_size()); - int extra = get_constant("titlebar_height","WindowDialog"); - Rect2 r( Point2(), get_size() ); - r.pos.y-=extra; - r.size.y+=extra; - return r.has_point(p_point); + // Enlarge upwards for title bar. + int titlebar_height = get_constant("titlebar_height", "WindowDialog"); + r.pos.y -= titlebar_height; + r.size.y += titlebar_height; + + // Inflate by the resizable border thickness. + if (resizable) { + int scaleborder_size = get_constant("scaleborder_size", "WindowDialog"); + r.pos.x -= scaleborder_size; + r.size.width += scaleborder_size * 2; + r.pos.y -= scaleborder_size; + r.size.height += scaleborder_size * 2; + } + return r.has_point(p_point); } void WindowDialog::_gui_input(const InputEvent& p_event) { - if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_LEFT) { - - if (p_event.mouse_button.pressed && p_event.mouse_button.y < 0) - dragging=true; - else if (dragging && !p_event.mouse_button.pressed) - dragging=false; + if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == BUTTON_LEFT) { + + if (p_event.mouse_button.pressed) { + // Begin a possible dragging operation. + drag_type = _drag_hit_test(Point2(p_event.mouse_button.x, p_event.mouse_button.y)); + if (drag_type != DRAG_NONE) + drag_offset = get_global_mouse_pos() - get_pos(); + drag_offset_far = get_pos() + get_size() - get_global_mouse_pos(); + } else if (drag_type != DRAG_NONE && !p_event.mouse_button.pressed) { + // End a dragging operation. + drag_type = DRAG_NONE; + } } - - if (p_event.type == InputEvent::MOUSE_MOTION && dragging) { - - Point2 rel( p_event.mouse_motion.relative_x, p_event.mouse_motion.relative_y ); - Point2 pos = get_pos(); - - pos+=rel; - - if (pos.y<0) - pos.y=0; - - set_pos(pos); + if (p_event.type == InputEvent::MOUSE_MOTION) { + + if (drag_type == DRAG_NONE) { + // Update the cursor while moving along the borders. + CursorShape cursor = CURSOR_ARROW; + if (resizable) { + int preview_drag_type = _drag_hit_test(Point2(p_event.mouse_button.x, p_event.mouse_button.y)); + switch (preview_drag_type) { + case DRAG_RESIZE_TOP: + case DRAG_RESIZE_BOTTOM: + cursor = CURSOR_VSIZE; + break; + case DRAG_RESIZE_LEFT: + case DRAG_RESIZE_RIGHT: + cursor = CURSOR_HSIZE; + break; + case DRAG_RESIZE_TOP + DRAG_RESIZE_LEFT: + case DRAG_RESIZE_BOTTOM + DRAG_RESIZE_RIGHT: + cursor = CURSOR_FDIAGSIZE; + break; + case DRAG_RESIZE_TOP + DRAG_RESIZE_RIGHT: + case DRAG_RESIZE_BOTTOM + DRAG_RESIZE_LEFT: + cursor = CURSOR_BDIAGSIZE; + break; + } + } + if (get_cursor_shape() != cursor) + set_default_cursor_shape(cursor); + } else { + // Update while in a dragging operation. + Point2 global_pos = get_global_mouse_pos(); + global_pos.y = MAX(global_pos.y, 0); // Ensure title bar stays visible. + + Rect2 rect = get_rect(); + Size2 min_size = get_minimum_size(); + + if (drag_type == DRAG_MOVE) { + rect.pos = global_pos - drag_offset; + } else { + if (drag_type & DRAG_RESIZE_TOP) { + int bottom = rect.pos.y + rect.size.height; + int max_y = bottom - min_size.height; + rect.pos.y = MIN(global_pos.y - drag_offset.y, max_y); + rect.size.height = bottom - rect.pos.y; + } else if (drag_type & DRAG_RESIZE_BOTTOM) { + rect.size.height = global_pos.y - rect.pos.y + drag_offset_far.y; + } + if (drag_type & DRAG_RESIZE_LEFT) { + int right = rect.pos.x + rect.size.width; + int max_x = right - min_size.width; + rect.pos.x = MIN(global_pos.x - drag_offset.x, max_x); + rect.size.width = right - rect.pos.x; + } else if (drag_type & DRAG_RESIZE_RIGHT) { + rect.size.width = global_pos.x - rect.pos.x + drag_offset_far.x; + } + } + + set_size(rect.size); + set_pos(rect.pos); + } } } void WindowDialog::_notification(int p_what) { - switch(p_what) { - + switch (p_what) { case NOTIFICATION_DRAW: { - RID ci = get_canvas_item(); - Size2 s = get_size(); - Ref<StyleBox> st = get_stylebox("panel","WindowDialog"); - st->draw(ci,Rect2(Point2(),s)); - int th = get_constant("title_height","WindowDialog"); - Color tc = get_color("title_color","WindowDialog"); - Ref<Font> font = get_font("title_font","WindowDialog"); - int ofs = (s.width-font->get_string_size(title).width)/2; - //int ofs = st->get_margin(MARGIN_LEFT); - draw_string(font,Point2(ofs,-th+font->get_ascent()),title,tc,s.width - st->get_minimum_size().width); + RID canvas = get_canvas_item(); + Size2 size = get_size(); + + Ref<StyleBox> panel = get_stylebox("panel", "WindowDialog"); + panel->draw(canvas, Rect2(Point2(), size)); + int title_height = get_constant("title_height", "WindowDialog"); + Color title_color = get_color("title_color", "WindowDialog"); + Ref<Font> font = get_font("title_font", "WindowDialog"); + int ofs = (size.width - font->get_string_size(title).width) / 2; + draw_string(font, Point2(ofs, -title_height + font->get_ascent()), title, title_color, size.width - panel->get_minimum_size().width); } break; + case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_ENTER_TREE: { + close_button->set_normal_texture(get_icon("close", "WindowDialog")); + close_button->set_pressed_texture(get_icon("close", "WindowDialog")); + close_button->set_hover_texture(get_icon("close_hilite", "WindowDialog")); + close_button->set_anchor(MARGIN_LEFT, ANCHOR_END); + close_button->set_begin(Point2(get_constant("close_h_ofs", "WindowDialog"), -get_constant("close_v_ofs", "WindowDialog"))); + } break; - close_button->set_normal_texture( get_icon("close","WindowDialog")); - close_button->set_pressed_texture( get_icon("close","WindowDialog")); - close_button->set_hover_texture( get_icon("close_hilite","WindowDialog")); - close_button->set_anchor(MARGIN_LEFT,ANCHOR_END); - close_button->set_begin( Point2( get_constant("close_h_ofs","WindowDialog"), -get_constant("close_v_ofs","WindowDialog") )); - + case NOTIFICATION_MOUSE_EXIT: { + // Reset the mouse cursor when leaving the resizable window border. + if (resizable && !drag_type) { + if (get_default_cursor_shape() != CURSOR_ARROW) + set_default_cursor_shape(CURSOR_ARROW); + } } break; } - } void WindowDialog::_closed() { @@ -111,11 +180,48 @@ void WindowDialog::_closed() { hide(); } +int WindowDialog::_drag_hit_test(const Point2& pos) const { + int drag_type = DRAG_NONE; + + if (resizable) { + int titlebar_height = get_constant("titlebar_height", "WindowDialog"); + int scaleborder_size = get_constant("scaleborder_size", "WindowDialog"); + + Rect2 rect = get_rect(); + + if (pos.y < (-titlebar_height + scaleborder_size)) + drag_type = DRAG_RESIZE_TOP; + else if (pos.y >= (rect.size.height - scaleborder_size)) + drag_type = DRAG_RESIZE_BOTTOM; + if (pos.x < scaleborder_size) + drag_type |= DRAG_RESIZE_LEFT; + else if (pos.x >= (rect.size.width - scaleborder_size)) + drag_type |= DRAG_RESIZE_RIGHT; + } + + if (drag_type == DRAG_NONE && pos.y < 0) + drag_type = DRAG_MOVE; + + return drag_type; +} + void WindowDialog::set_title(const String& p_title) { title=XL_MESSAGE(p_title); update(); } +String WindowDialog::get_title() const { + + return title; +} + +void WindowDialog::set_resizable(bool p_resizable) { + resizable = p_resizable; +} +bool WindowDialog::get_resizable() const { + return resizable; +} + Size2 WindowDialog::get_minimum_size() const { @@ -127,11 +233,6 @@ Size2 WindowDialog::get_minimum_size() const { } -String WindowDialog::get_title() const { - - return title; -} - TextureButton *WindowDialog::get_close_button() { @@ -144,19 +245,23 @@ void WindowDialog::_bind_methods() { ClassDB::bind_method( D_METHOD("_gui_input"),&WindowDialog::_gui_input); ClassDB::bind_method( D_METHOD("set_title","title"),&WindowDialog::set_title); ClassDB::bind_method( D_METHOD("get_title"),&WindowDialog::get_title); + ClassDB::bind_method( D_METHOD("set_resizable","resizable"),&WindowDialog::set_resizable); + ClassDB::bind_method( D_METHOD("get_resizable"), &WindowDialog::get_resizable); ClassDB::bind_method( D_METHOD("_closed"),&WindowDialog::_closed); ClassDB::bind_method( D_METHOD("get_close_button:TextureButton"),&WindowDialog::get_close_button); ADD_PROPERTY( PropertyInfo(Variant::STRING,"window_title",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT_INTL),"set_title","get_title"); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"resizable",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT_INTL),"set_resizable","get_resizable"); } WindowDialog::WindowDialog() { //title="Hello!"; - dragging=false; - close_button = memnew( TextureButton ); + drag_type = DRAG_NONE; + resizable = false; + close_button = memnew(TextureButton); add_child(close_button); - close_button->connect("pressed",this,"_closed"); + close_button->connect("pressed", this, "_closed"); } @@ -186,7 +291,7 @@ PopupDialog::~PopupDialog() { } -// +// AcceptDialog void AcceptDialog::_post_popup() { @@ -201,7 +306,7 @@ void AcceptDialog::_notification(int p_what) { if (p_what==NOTIFICATION_MODAL_CLOSE) { cancel_pressed(); - } if (p_what==NOTIFICATION_RESIZED) { + } else if (p_what==NOTIFICATION_RESIZED) { _update_child_rects(); } diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index 6650c5eb5d..845ac69cd5 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -44,12 +44,26 @@ class WindowDialog : public Popup { GDCLASS(WindowDialog,Popup); + enum DRAG_TYPE { + DRAG_NONE = 0, + DRAG_MOVE = 1, + DRAG_RESIZE_TOP = 1 << 1, + DRAG_RESIZE_RIGHT = 1 << 2, + DRAG_RESIZE_BOTTOM = 1 << 3, + DRAG_RESIZE_LEFT = 1 << 4 + }; + TextureButton *close_button; String title; - bool dragging; + int drag_type; + Point2 drag_offset; + Point2 drag_offset_far; + bool resizable; void _gui_input(const InputEvent& p_event); void _closed(); + int _drag_hit_test(const Point2& pos) const; + protected: virtual void _post_popup(); @@ -63,6 +77,8 @@ public: void set_title(const String& p_title); String get_title() const; + void set_resizable(bool p_resizable); + bool get_resizable() const; Size2 get_minimum_size() const; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index a35df53e52..91bd16ee0b 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -314,7 +314,7 @@ void ItemList::move_item(int p_item,int p_to_pos) { if (current<0) { //do none - } if (p_item==current) { + } else if (p_item==current) { current=p_to_pos; } else if (p_to_pos>p_item && current>p_item && current<p_to_pos) { current--; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index b06cde1e91..17ec71f4a4 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1214,6 +1214,28 @@ void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline) } +void RichTextLabel::_remove_item(Item* p_item, const int p_line, const int p_subitem_line) { + + + int size = p_item->subitems.size(); + if (size == 0) { + p_item->parent->subitems.erase(p_item); + if (p_item->type == ITEM_NEWLINE) { + current_frame->lines.remove(p_line); + for (int i = p_subitem_line; i < current->subitems.size(); i++) { + if (current->subitems[i]->line > 0) + current->subitems[i]->line--; + } + } + } + else { + for (int i = 0; i < size; i++) { + _remove_item(p_item->subitems.front()->get(), p_line, p_subitem_line); + } + } + +} + void RichTextLabel::add_image(const Ref<Texture>& p_image) { if (current->type==ITEM_TABLE) @@ -1238,6 +1260,26 @@ void RichTextLabel::add_newline() { } +bool RichTextLabel::remove_line(const int p_line) { + + if (p_line >= current_frame->lines.size() || p_line < 0) + return false; + + int lines = p_line * 2; + + if (current->subitems[lines]->type != ITEM_NEWLINE) + _remove_item(current->subitems[lines], current->subitems[lines]->line, lines); + + _remove_item(current->subitems[lines], current->subitems[lines]->line, lines); + + if (p_line == 0) { + main->lines[0].from = main; + } + + main->first_invalid_line = 0; + return true; +} + void RichTextLabel::push_font(const Ref<Font>& p_font) { ERR_FAIL_COND(current->type==ITEM_TABLE); @@ -1906,6 +1948,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("add_text","text"),&RichTextLabel::add_text); ClassDB::bind_method(D_METHOD("add_image","image:Texture"),&RichTextLabel::add_image); ClassDB::bind_method(D_METHOD("newline"),&RichTextLabel::add_newline); + ClassDB::bind_method(D_METHOD("remove_line"),&RichTextLabel::remove_line); ClassDB::bind_method(D_METHOD("push_font","font"),&RichTextLabel::push_font); ClassDB::bind_method(D_METHOD("push_color","color"),&RichTextLabel::push_color); ClassDB::bind_method(D_METHOD("push_align","align"),&RichTextLabel::push_align); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 39032185f8..3bdd2cd7e3 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -173,7 +173,7 @@ private: struct ItemNewline : public Item { - int line; + int line; // FIXME: Overriding base's line ? ItemNewline() { type=ITEM_NEWLINE; } }; @@ -217,6 +217,7 @@ private: void _validate_line_caches(ItemFrame *p_frame); void _add_item(Item *p_item, bool p_enter=false,bool p_ensure_newline=false); + void _remove_item(Item *p_item, const int p_line, const int p_subitem_line); @@ -284,6 +285,7 @@ public: void add_text(const String& p_text); void add_image(const Ref<Texture>& p_image); void add_newline(); + bool remove_line(const int p_line); void push_font(const Ref<Font>& p_font); void push_color(const Color& p_color); void push_underline(); diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index a15c9f5e42..1707676da2 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -31,368 +31,322 @@ #include "message_queue.h" - int TabContainer::_get_top_margin() const { + if (!tabs_visible) + return 0; + + // Respect the minimum tab height. Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); - Ref<Font> font = get_font("font"); + Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); - int h = MAX( tab_bg->get_minimum_size().height,tab_fg->get_minimum_size().height); + int tab_height = MAX(MAX(tab_bg->get_minimum_size().height, tab_fg->get_minimum_size().height), tab_disabled->get_minimum_size().height); - int ch = font->get_height(); - for(int i=0;i<get_child_count();i++) { + // Font height or higher icon wins. + Ref<Font> font = get_font("font"); + int content_height = font->get_height(); - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + Vector<Control*> tabs = _get_tabs(); + for (int i = 0; i < tabs.size(); i++) { + + Control *c = tabs[i]; if (!c->has_meta("_tab_icon")) continue; Ref<Texture> tex = c->get_meta("_tab_icon"); if (!tex.is_valid()) continue; - ch = MAX( ch, tex->get_size().height ); + content_height = MAX(content_height, tex->get_size().height); } - h+=ch; - - return h; - + return tab_height + content_height; } void TabContainer::_gui_input(const InputEvent& p_event) { - if (p_event.type==InputEvent::MOUSE_BUTTON && - p_event.mouse_button.pressed && - p_event.mouse_button.button_index==BUTTON_LEFT) { + if (p_event.type == InputEvent::MOUSE_BUTTON + && p_event.mouse_button.pressed + && p_event.mouse_button.button_index == BUTTON_LEFT) { - // clicks - Point2 pos( p_event.mouse_button.x, p_event.mouse_button.y ); + Point2 pos(p_event.mouse_button.x, p_event.mouse_button.y); + Size2 size = get_size(); - int top_margin = _get_top_margin(); - if (pos.y>top_margin) - return; // no click (too far down) - - if (pos.x<tabs_ofs_cache) - return; // no click (too far left) + // Click must be on tabs in the tab header area. + if (pos.x < tabs_ofs_cache || pos.y > _get_top_margin()) + return; - Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); - Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); - Ref<Font> font = get_font("font"); - Ref<Texture> incr = get_icon("increment"); - Ref<Texture> decr = get_icon("decrement"); + // Handle menu button. Ref<Texture> menu = get_icon("menu"); - Ref<Texture> menu_hl = get_icon("menu_hl"); - - if (popup && pos.x>get_size().width-menu->get_width()) { - - + if (popup && pos.x > size.width - menu->get_width()) { emit_signal("pre_popup_pressed"); - Vector2 pp_pos = get_global_pos(); - pp_pos.x+=get_size().width; - pp_pos.x-=popup->get_size().width; - pp_pos.y+=menu->get_height(); - popup->set_global_pos( pp_pos ); + Vector2 popup_pos = get_global_pos(); + popup_pos.x += size.width - popup->get_size().width; + popup_pos.y += menu->get_height(); + + popup->set_global_pos(popup_pos); popup->popup(); return; } - pos.x-=tabs_ofs_cache; - - int idx=0; - int found=-1; - bool rightroom=false; - - for(int i=0;i<get_child_count();i++) { - - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; - - if (idx<tab_display_ofs) { - idx++; - continue; - } - - if (idx>last_tab_cache) { - rightroom=true; - break; - } - - String s = c->has_meta("_tab_name")?String(XL_MESSAGE(String(c->get_meta("_tab_name")))):String(c->get_name()); - int tab_width=font->get_string_size(s).width; - if (c->has_meta("_tab_icon")) { - Ref<Texture> icon = c->get_meta("_tab_icon"); - if (icon.is_valid()) { - tab_width+=icon->get_width(); - if (s!="") - tab_width+=get_constant("hseparation"); - - } - } - - if (idx==current) { - - tab_width+=tab_fg->get_minimum_size().width; - } else { - tab_width+=tab_bg->get_minimum_size().width; - } - - if (pos.x < tab_width) { - - found=idx; - break; - } - - pos.x-=tab_width; - idx++; - } + Vector<Control*> tabs = _get_tabs(); + // Handle navigation buttons. if (buttons_visible_cache) { - - if (p_event.mouse_button.x>get_size().width-incr->get_width()) { - if (rightroom) { - tab_display_ofs+=1; + Ref<Texture> increment = get_icon("increment"); + Ref<Texture> decrement = get_icon("decrement"); + if (pos.x > size.width - increment->get_width()) { + if (last_tab_cache < tabs.size() - 1) { + first_tab_cache += 1; update(); } - } else if (p_event.mouse_button.x>get_size().width-incr->get_width()-decr->get_width()) { - - if (tab_display_ofs>0) { - tab_display_ofs-=1; + return; + } else if (pos.x > size.width - increment->get_width() - decrement->get_width()) { + if (first_tab_cache > 0) { + first_tab_cache -= 1; update(); } - + return; } } - - if (found!=-1) { - - set_current_tab(found); + // Activate the clicked tab. + pos.x -= tabs_ofs_cache; + for (int i = first_tab_cache; i <= last_tab_cache; i++) { + int tab_width = _get_tab_width(i); + if (pos.x < tab_width) { + if (!get_tab_disabled(i)) { + set_current_tab(i); + } + break; + } + pos.x -= tab_width; } } - } void TabContainer::_notification(int p_what) { - - switch(p_what) { - + switch (p_what) { case NOTIFICATION_DRAW: { - RID ci = get_canvas_item(); - Ref<StyleBox> panel = get_stylebox("panel"); + RID canvas = get_canvas_item(); Size2 size = get_size(); + // Draw only the tab area if the header is hidden. + Ref<StyleBox> panel = get_stylebox("panel"); if (!tabs_visible) { - - panel->draw(ci, Rect2( 0, 0, size.width, size.height)); + panel->draw(canvas, Rect2(0, 0, size.width, size.height)); return; } - - + Vector<Control*> tabs = _get_tabs(); Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); - Ref<Texture> incr = get_icon("increment"); - Ref<Texture> decr = get_icon("decrement"); + Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); + Ref<Texture> increment = get_icon("increment"); + Ref<Texture> decrement = get_icon("decrement"); Ref<Texture> menu = get_icon("menu"); Ref<Texture> menu_hl = get_icon("menu_hl"); Ref<Font> font = get_font("font"); - Color color_fg = get_color("font_color_fg"); - Color color_bg = get_color("font_color_bg"); - + Color font_color_fg = get_color("font_color_fg"); + Color font_color_bg = get_color("font_color_bg"); + Color font_color_disabled = get_color("font_color_disabled"); int side_margin = get_constant("side_margin"); - int top_margin = _get_top_margin(); - - - Size2 top_size = Size2( size.width, top_margin ); - - - - int w=0; - int idx=0; - Vector<int> offsets; - Vector<Control*> controls; - int from=0; - int limit=get_size().width; - if (popup) { - top_size.width-=menu->get_width(); - limit-=menu->get_width(); - } - - bool notdone=false; - last_tab_cache=-1; - - for(int i=0;i<get_child_count();i++) { - - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; - if (idx<tab_display_ofs) { - idx++; - from=idx; - continue; - } - - if (w>=get_size().width) { - buttons_visible_cache=true; - notdone=true; + int icon_text_distance = get_constant("hseparation"); + + // Find out start and width of the header area. + int header_x = side_margin; + int header_width = size.width - side_margin * 2; + int header_height = _get_top_margin(); + if (popup) + header_width -= menu->get_width(); + + // Check if all tabs would fit into the header area. + int all_tabs_width = 0; + for (int i = 0; i < tabs.size(); i++) { + int tab_width = _get_tab_width(i); + all_tabs_width += tab_width; + + if (all_tabs_width > header_width) { + // Not all tabs are visible at the same time - reserve space for navigation buttons. + buttons_visible_cache = true; + header_width -= decrement->get_width() + increment->get_width(); break; - } - - offsets.push_back(w); - controls.push_back(c); - - String s = c->has_meta("_tab_name")?String(XL_MESSAGE(String(c->get_meta("_tab_name")))):String(c->get_name()); - w+=font->get_string_size(s).width; - if (c->has_meta("_tab_icon")) { - Ref<Texture> icon = c->get_meta("_tab_icon"); - if (icon.is_valid()) { - w+=icon->get_width(); - if (s!="") - w+=get_constant("hseparation"); - - } - } - - if (idx==current) { - - w+=tab_fg->get_minimum_size().width; } else { - w+=tab_bg->get_minimum_size().width; + buttons_visible_cache = false; } - - if (idx<tab_display_ofs) { - - } - last_tab_cache=idx; - - idx++; + } + // With buttons, a right side margin does not need to be respected. + if (popup || buttons_visible_cache) { + header_width += side_margin; } + // Go through the visible tabs to find the width they occupy. + all_tabs_width = 0; + Vector<int> tab_widths; + for (int i = first_tab_cache; i < tabs.size(); i++) { + int tab_width = _get_tab_width(i); + if (all_tabs_width + tab_width > header_width && tab_widths.size() > 0) + break; + all_tabs_width += tab_width; + tab_widths.push_back(tab_width); + } - int ofs; - - switch(align) { - - case ALIGN_LEFT: ofs = side_margin; break; - case ALIGN_CENTER: ofs = (int(limit) - w)/2; break; - case ALIGN_RIGHT: ofs = int(limit) - w - side_margin; break; - }; - - tab_display_ofs=0; - - - tabs_ofs_cache=ofs; - idx=0; - - - - for(int i=0;i<controls.size();i++) { - - idx=i+from; - if (current>=from && current<from+controls.size()-1) { - //current is visible! draw it last. - if (i==controls.size()-1) { - idx=current; - } else if (idx>=current) { - idx+=1; - } - } - - Control *c = controls[idx-from]; - - String s = c->has_meta("_tab_name")?String(c->get_meta("_tab_name")):String(c->get_name()); - int w=font->get_string_size(s).width; - Ref<Texture> icon; - if (c->has_meta("_tab_icon")) { - icon = c->get_meta("_tab_icon"); - if (icon.is_valid()) { - - w+=icon->get_width(); - if (s!="") - w+=get_constant("hseparation"); - - } - } - - - Ref<StyleBox> sb; - Color col; - - if (idx==current) { + // Find the offset at which to draw tabs, according to the alignment. + switch (align) { + case ALIGN_LEFT: + tabs_ofs_cache = header_x; + break; + case ALIGN_CENTER: + tabs_ofs_cache = header_x + (header_width / 2) - (all_tabs_width / 2); + break; + case ALIGN_RIGHT: + tabs_ofs_cache = header_x + header_width - all_tabs_width; + break; + } - sb=tab_fg; - col=color_fg; + // Draw all visible tabs. + int x = 0; + for (int i = 0; i < tab_widths.size(); i++) { + Ref<StyleBox> tab_style; + Color font_color; + if (get_tab_disabled(i + first_tab_cache)) { + tab_style = tab_disabled; + font_color = font_color_disabled; + } else if (i + first_tab_cache == current) { + tab_style = tab_fg; + font_color = font_color_fg; } else { - sb=tab_bg; - col=color_bg; + tab_style = tab_bg; + font_color = font_color_bg; } - int lofs = ofs + offsets[idx-from]; - - Size2i sb_ms = sb->get_minimum_size(); - Rect2 sb_rect = Rect2( lofs, 0, w+sb_ms.width, top_margin); + // Draw the tab background. + int tab_width = tab_widths[i]; + Rect2 tab_rect(tabs_ofs_cache + x, 0, tab_width, header_height); + tab_style->draw(canvas, tab_rect); + // Draw the tab contents. + Control *control = tabs[i + first_tab_cache]->cast_to<Control>(); + String text = control->has_meta("_tab_name") + ? String(XL_MESSAGE(String(control->get_meta("_tab_name")))) + : String(control->get_name()); - sb->draw(ci, sb_rect ); - - Point2i lpos = sb_rect.pos; - lpos.x+=sb->get_margin(MARGIN_LEFT); - if (icon.is_valid()) { - - icon->draw(ci, Point2i( lpos.x, sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-icon->get_height())/2 ) ); - if (s!="") - lpos.x+=icon->get_width()+get_constant("hseparation"); + int x_content = tab_rect.pos.x + tab_style->get_margin(MARGIN_LEFT); + int top_margin = tab_style->get_margin(MARGIN_TOP); + int y_center = top_margin + (tab_rect.size.y - tab_style->get_minimum_size().y) / 2; + // Draw the tab icon. + if (control->has_meta("_tab_icon")) { + Ref<Texture> icon = control->get_meta("_tab_icon"); + if (icon.is_valid()) { + int y = y_center - (icon->get_height() / 2); + icon->draw(canvas, Point2i(x_content, y)); + if (text != "") + x_content += icon->get_width() + icon_text_distance; + } } - font->draw(ci, Point2i( lpos.x, sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-font->get_height())/2+font->get_ascent() ), s, col ); + // Draw the tab text. + Point2i text_pos(x_content, y_center - (font->get_height() / 2) + font->get_ascent()); + font->draw(canvas, text_pos, text, font_color); - idx++; + x += tab_width; + last_tab_cache = i + first_tab_cache; } + // Draw the popup menu. + x = get_size().width; + if (popup) { + x -= menu->get_width(); + if (mouse_x_cache > x) + menu_hl->draw(get_canvas_item(), Size2(x, 0)); + else + menu->draw(get_canvas_item(), Size2(x, 0)); + } + // Draw the navigation buttons. if (buttons_visible_cache) { + int y_center = header_height / 2; - int vofs = (top_margin-incr->get_height())/2; - decr->draw(ci,Point2(limit,vofs),Color(1,1,1,tab_display_ofs==0?0.5:1.0)); - incr->draw(ci,Point2(limit+incr->get_width(),vofs),Color(1,1,1,notdone?1.0:0.5)); - } - - if (popup) { - int from = get_size().width-menu->get_width(); + x -= increment->get_width(); + increment->draw(canvas, + Point2(x, y_center - (increment->get_height() / 2)), + Color(1, 1, 1, last_tab_cache < tabs.size() - 1 ? 1.0 : 0.5)); - if (mouse_x_cache > from) - menu_hl->draw(get_canvas_item(),Size2(from,0)); - else - menu->draw(get_canvas_item(),Size2(from,0)); + x -= decrement->get_width(); + decrement->draw(canvas, + Point2(x, y_center - (decrement->get_height() / 2)), + Color(1, 1, 1, first_tab_cache > 0 ? 1.0 : 0.5)); } - panel->draw(ci, Rect2( 0, top_size.height, size.width, size.height-top_size.height)); - + // Draw the tab area. + panel->draw(canvas, Rect2(0, header_height, size.width, size.height - header_height)); } break; case NOTIFICATION_THEME_CHANGED: { if (get_tab_count() > 0) { - call_deferred("set_current_tab",get_current_tab()); //wait until all changed theme + call_deferred("set_current_tab", get_current_tab()); //wait until all changed theme } } break; } } +int TabContainer::_get_tab_width(int p_index) const { + Control *control = _get_tabs()[p_index]->cast_to<Control>(); + if (!control || control->is_set_as_toplevel()) + return 0; + + // Get the width of the text displayed on the tab. + Ref<Font> font = get_font("font"); + String text = control->has_meta("_tab_name") + ? String(XL_MESSAGE(String(control->get_meta("_tab_name")))) + : String(control->get_name()); + int width = font->get_string_size(text).width; + + // Add space for a tab icon. + if (control->has_meta("_tab_icon")) { + Ref<Texture> icon = control->get_meta("_tab_icon"); + if (icon.is_valid()) { + width += icon->get_width(); + if (text != "") + width += get_constant("hseparation"); + } + } + + // Respect a minimum size. + Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); + Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); + Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); + if (get_tab_disabled(p_index)) { + width += tab_disabled->get_minimum_size().width; + } else if (p_index == current) { + width += tab_fg->get_minimum_size().width; + } else { + width += tab_bg->get_minimum_size().width; + } + + return width; +} + +Vector<Control*> TabContainer::_get_tabs() const { + + Vector<Control*> controls; + for (int i = 0; i < get_child_count(); i++) { + + Control *control = get_child(i)->cast_to<Control>(); + if (!control || control->is_toplevel_control()) + continue; + + controls.push_back(control); + } + return controls; +} + void TabContainer::_child_renamed_callback() { update(); @@ -408,78 +362,62 @@ void TabContainer::add_child_notify(Node *p_child) { if (c->is_set_as_toplevel()) return; - bool first=false; + bool first = false; - if (get_tab_count()!=1) + if (get_tab_count() != 1) c->hide(); else { c->show(); //call_deferred("set_current_tab",0); - first=true; - current=0; + first = true; + current = 0; } c->set_area_as_parent_rect(); if (tabs_visible) - c->set_margin(MARGIN_TOP,_get_top_margin()); + c->set_margin(MARGIN_TOP, _get_top_margin()); Ref<StyleBox> sb = get_stylebox("panel"); - for(int i=0;i<4;i++) - c->set_margin(Margin(i),c->get_margin(Margin(i))+sb->get_margin(Margin(i))); + for (int i = 0; i < 4; i++) + c->set_margin(Margin(i), c->get_margin(Margin(i)) + sb->get_margin(Margin(i))); update(); - p_child->connect("renamed", this,"_child_renamed_callback"); - if(first) - emit_signal("tab_changed",current); + p_child->connect("renamed", this, "_child_renamed_callback"); + if (first) + emit_signal("tab_changed", current); } int TabContainer::get_tab_count() const { - int count=0; - - for(int i=0;i<get_child_count();i++) { - - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; - count++; - } - - return count; + return _get_tabs().size(); } void TabContainer::set_current_tab(int p_current) { - ERR_FAIL_INDEX( p_current, get_tab_count() ); - - current=p_current; + ERR_FAIL_INDEX(p_current, get_tab_count()); - int idx=0; + current = p_current; - Ref<StyleBox> sb=get_stylebox("panel"); - for(int i=0;i<get_child_count();i++) { + Ref<StyleBox> sb = get_stylebox("panel"); + Vector<Control*> tabs = _get_tabs(); + for (int i = 0; i < tabs.size(); i++) { - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; - if (idx==current) { + Control *c = tabs[i]; + if (i == current) { c->show(); c->set_area_as_parent_rect(); if (tabs_visible) - c->set_margin(MARGIN_TOP,_get_top_margin()); - for(int i=0;i<4;i++) - c->set_margin(Margin(i),c->get_margin(Margin(i))+sb->get_margin(Margin(i))); + c->set_margin(MARGIN_TOP, _get_top_margin()); + for (int i = 0; i < 4; i++) + c->set_margin(Margin(i), c->get_margin(Margin(i)) + sb->get_margin(Margin(i))); } else c->hide(); - idx++; } _change_notify("current_tab"); - emit_signal("tab_changed",current); + emit_signal("tab_changed", current); update(); } @@ -490,45 +428,19 @@ int TabContainer::get_current_tab() const { Control* TabContainer::get_tab_control(int p_idx) const { - int idx=0; - - - for(int i=0;i<get_child_count();i++) { - - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; - if (idx==p_idx) { - return c; - - } - idx++; - } - - return NULL; + Vector<Control*> tabs = _get_tabs(); + if (p_idx >= 0 && p_idx < tabs.size()) + return tabs[p_idx]; + else + return NULL; } Control* TabContainer::get_current_tab_control() const { - int idx=0; - - - for(int i=0;i<get_child_count();i++) { - - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; - if (idx==current) { - return c; - - } - idx++; - } - - return NULL; + Vector<Control*> tabs = _get_tabs(); + if (current >= 0 && current < tabs.size()) + return tabs[current]; + else + return NULL; } void TabContainer::remove_child_notify(Node *p_child) { @@ -536,24 +448,24 @@ void TabContainer::remove_child_notify(Node *p_child) { Control::remove_child_notify(p_child); int tc = get_tab_count(); - if (current==tc-1) { + if (current == tc - 1) { current--; - if (current<0) - current=0; + if (current < 0) + current = 0; else { - call_deferred("set_current_tab",current); + call_deferred("set_current_tab", current); } } - p_child->disconnect("renamed", this,"_child_renamed_callback"); + p_child->disconnect("renamed", this, "_child_renamed_callback"); update(); } void TabContainer::set_tab_align(TabAlign p_align) { - ERR_FAIL_INDEX(p_align,3); - align=p_align; + ERR_FAIL_INDEX(p_align, 3); + align = p_align; update(); _change_notify("tab_align"); @@ -565,20 +477,19 @@ TabContainer::TabAlign TabContainer::get_tab_align() const { void TabContainer::set_tabs_visible(bool p_visibe) { - if (p_visibe==tabs_visible) + if (p_visibe == tabs_visible) return; - tabs_visible=p_visibe; + tabs_visible = p_visibe; - for(int i=0;i<get_child_count();i++) { + Vector<Control*> tabs = _get_tabs(); + for (int i = 0; i < tabs.size(); i++) { - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; + Control *c = tabs[i]; if (p_visibe) - c->set_margin(MARGIN_TOP,_get_top_margin()); + c->set_margin(MARGIN_TOP, _get_top_margin()); else - c->set_margin(MARGIN_TOP,0); + c->set_margin(MARGIN_TOP, 0); } update(); @@ -593,36 +504,22 @@ bool TabContainer::are_tabs_visible() const { Control *TabContainer::_get_tab(int p_idx) const { - int idx=0; - - for(int i=0;i<get_child_count();i++) { - - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; - if (idx==p_idx) - return c; - idx++; - - } - return NULL; + return get_tab_control(p_idx); } -void TabContainer::set_tab_title(int p_tab,const String& p_title) { +void TabContainer::set_tab_title(int p_tab, const String& p_title) { Control *child = _get_tab(p_tab); ERR_FAIL_COND(!child); - child->set_meta("_tab_name",p_title); + child->set_meta("_tab_name", p_title); } -String TabContainer::get_tab_title(int p_tab) const{ +String TabContainer::get_tab_title(int p_tab) const { Control *child = _get_tab(p_tab); - ERR_FAIL_COND_V(!child,""); + ERR_FAIL_COND_V(!child, ""); if (child->has_meta("_tab_name")) return child->get_meta("_tab_name"); else @@ -630,39 +527,53 @@ String TabContainer::get_tab_title(int p_tab) const{ } -void TabContainer::set_tab_icon(int p_tab,const Ref<Texture>& p_icon){ +void TabContainer::set_tab_icon(int p_tab, const Ref<Texture>& p_icon) { Control *child = _get_tab(p_tab); ERR_FAIL_COND(!child); - child->set_meta("_tab_icon",p_icon); + child->set_meta("_tab_icon", p_icon); } -Ref<Texture> TabContainer::get_tab_icon(int p_tab) const{ +Ref<Texture> TabContainer::get_tab_icon(int p_tab) const { Control *child = _get_tab(p_tab); - ERR_FAIL_COND_V(!child,Ref<Texture>()); + ERR_FAIL_COND_V(!child, Ref<Texture>()); if (child->has_meta("_tab_icon")) return child->get_meta("_tab_icon"); else return Ref<Texture>(); } +void TabContainer::set_tab_disabled(int p_tab, bool p_enabled) { + + Control *child = _get_tab(p_tab); + ERR_FAIL_COND(!child); + child->set_meta("_tab_disabled", p_enabled); + update(); +} +bool TabContainer::get_tab_disabled(int p_tab) const { + + Control *child = _get_tab(p_tab); + ERR_FAIL_COND_V(!child, false); + if (child->has_meta("_tab_disabled")) + return child->get_meta("_tab_disabled"); + else + return false; +} + void TabContainer::get_translatable_strings(List<String> *p_strings) const { - for(int i=0;i<get_child_count();i++) { + Vector<Control*> tabs = _get_tabs(); + for (int i = 0; i < tabs.size(); i++) { - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + Control *c = tabs[i]; if (!c->has_meta("_tab_name")) continue; String name = c->get_meta("_tab_name"); - if (name!="") + if (name != "") p_strings->push_back(name); } } @@ -672,38 +583,36 @@ Size2 TabContainer::get_minimum_size() const { Size2 ms; - for(int i=0;i<get_child_count();i++) { + Vector<Control*> tabs = _get_tabs(); + for (int i = 0; i < tabs.size(); i++) { - Control *c = get_child(i)->cast_to<Control>(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + Control *c = tabs[i]; if (!c->is_visible_in_tree()) continue; Size2 cms = c->get_combined_minimum_size(); - ms.x=MAX(ms.x,cms.x); - ms.y=MAX(ms.y,cms.y); + ms.x = MAX(ms.x, cms.x); + ms.y = MAX(ms.y, cms.y); } Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); + Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); Ref<Font> font = get_font("font"); - ms.y+=MAX(tab_bg->get_minimum_size().y,tab_fg->get_minimum_size().y); - ms.y+=font->get_height(); + ms.y += MAX(MAX(tab_bg->get_minimum_size().y, tab_fg->get_minimum_size().y), tab_disabled->get_minimum_size().y); + ms.y += font->get_height(); Ref<StyleBox> sb = get_stylebox("panel"); - ms+=sb->get_minimum_size(); + ms += sb->get_minimum_size(); return ms; } void TabContainer::set_popup(Node *p_popup) { ERR_FAIL_NULL(p_popup); - popup=p_popup->cast_to<Popup>(); + popup = p_popup->cast_to<Popup>(); update(); } @@ -714,43 +623,45 @@ Popup* TabContainer::get_popup() const { void TabContainer::_bind_methods() { - ClassDB::bind_method(D_METHOD("_gui_input"),&TabContainer::_gui_input); - ClassDB::bind_method(D_METHOD("get_tab_count"),&TabContainer::get_tab_count); - ClassDB::bind_method(D_METHOD("set_current_tab","tab_idx"),&TabContainer::set_current_tab); - ClassDB::bind_method(D_METHOD("get_current_tab"),&TabContainer::get_current_tab); - ClassDB::bind_method(D_METHOD("get_current_tab_control:Control"),&TabContainer::get_current_tab_control); - ClassDB::bind_method(D_METHOD("get_tab_control:Control","idx"),&TabContainer::get_tab_control); - ClassDB::bind_method(D_METHOD("set_tab_align","align"),&TabContainer::set_tab_align); - ClassDB::bind_method(D_METHOD("get_tab_align"),&TabContainer::get_tab_align); - ClassDB::bind_method(D_METHOD("set_tabs_visible","visible"),&TabContainer::set_tabs_visible); - ClassDB::bind_method(D_METHOD("are_tabs_visible"),&TabContainer::are_tabs_visible); - ClassDB::bind_method(D_METHOD("set_tab_title","tab_idx","title"),&TabContainer::set_tab_title); - ClassDB::bind_method(D_METHOD("get_tab_title","tab_idx"),&TabContainer::get_tab_title); - ClassDB::bind_method(D_METHOD("set_tab_icon","tab_idx","icon:Texture"),&TabContainer::set_tab_icon); - ClassDB::bind_method(D_METHOD("get_tab_icon:Texture","tab_idx"),&TabContainer::get_tab_icon); - ClassDB::bind_method(D_METHOD("set_popup","popup:Popup"),&TabContainer::set_popup); - ClassDB::bind_method(D_METHOD("get_popup:Popup"),&TabContainer::get_popup); - - ClassDB::bind_method(D_METHOD("_child_renamed_callback"),&TabContainer::_child_renamed_callback); - - ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab"))); + ClassDB::bind_method(D_METHOD("_gui_input"), &TabContainer::_gui_input); + ClassDB::bind_method(D_METHOD("get_tab_count"), &TabContainer::get_tab_count); + ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &TabContainer::set_current_tab); + ClassDB::bind_method(D_METHOD("get_current_tab"), &TabContainer::get_current_tab); + ClassDB::bind_method(D_METHOD("get_current_tab_control:Control"), &TabContainer::get_current_tab_control); + ClassDB::bind_method(D_METHOD("get_tab_control:Control", "idx"), &TabContainer::get_tab_control); + ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &TabContainer::set_tab_align); + ClassDB::bind_method(D_METHOD("get_tab_align"), &TabContainer::get_tab_align); + ClassDB::bind_method(D_METHOD("set_tabs_visible", "visible"), &TabContainer::set_tabs_visible); + ClassDB::bind_method(D_METHOD("are_tabs_visible"), &TabContainer::are_tabs_visible); + ClassDB::bind_method(D_METHOD("set_tab_title", "tab_idx", "title"), &TabContainer::set_tab_title); + ClassDB::bind_method(D_METHOD("get_tab_title", "tab_idx"), &TabContainer::get_tab_title); + ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon:Texture"), &TabContainer::set_tab_icon); + ClassDB::bind_method(D_METHOD("get_tab_icon:Texture", "tab_idx"), &TabContainer::get_tab_icon); + ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &TabContainer::set_tab_disabled); + ClassDB::bind_method(D_METHOD("get_tab_disabled", "tab_idx"), &TabContainer::get_tab_disabled); + ClassDB::bind_method(D_METHOD("set_popup", "popup:Popup"), &TabContainer::set_popup); + ClassDB::bind_method(D_METHOD("get_popup:Popup"), &TabContainer::get_popup); + + ClassDB::bind_method(D_METHOD("_child_renamed_callback"), &TabContainer::_child_renamed_callback); + + ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab"))); ADD_SIGNAL(MethodInfo("pre_popup_pressed")); - ADD_PROPERTY( PropertyInfo(Variant::INT, "tab_align", PROPERTY_HINT_ENUM,"Left,Center,Right"), "set_tab_align", "get_tab_align") ; - ADD_PROPERTY( PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE,"-1,4096,1",PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab") ; - ADD_PROPERTY( PropertyInfo(Variant::BOOL, "tabs_visible"), "set_tabs_visible", "are_tabs_visible") ; + ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_align", "get_tab_align"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tabs_visible"), "set_tabs_visible", "are_tabs_visible"); } TabContainer::TabContainer() { - tab_display_ofs=0; - buttons_visible_cache=false; - tabs_ofs_cache=0; - current=0; - mouse_x_cache=0; - align=ALIGN_CENTER; - tabs_visible=true; - popup=NULL; + first_tab_cache = 0; + buttons_visible_cache = false; + tabs_ofs_cache = 0; + current = 0; + mouse_x_cache = 0; + align = ALIGN_CENTER; + tabs_visible = true; + popup = NULL; -} +}
\ No newline at end of file diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index 8b6ca7704e..67f631f866 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -46,7 +46,7 @@ public: private: int mouse_x_cache; - int tab_display_ofs; + int first_tab_cache; int tabs_ofs_cache; int last_tab_cache; int current; @@ -57,6 +57,8 @@ private: int _get_top_margin() const; Popup *popup; + Vector<Control*> _get_tabs() const; + int _get_tab_width(int p_index) const; protected: @@ -83,6 +85,9 @@ public: void set_tab_icon(int p_tab,const Ref<Texture>& p_icon); Ref<Texture> get_tab_icon(int p_tab) const; + void set_tab_disabled(int p_tab, bool p_disabled); + bool get_tab_disabled(int p_tab) const; + int get_tab_count() const; void set_current_tab(int p_current); int get_current_tab() const; diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index ae282165c2..4e07a495ed 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -34,9 +34,10 @@ Size2 Tabs::get_minimum_size() const { Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); + Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); Ref<Font> font = get_font("font"); - Size2 ms(0, MAX(tab_bg->get_minimum_size().height, tab_fg->get_minimum_size().height)+font->get_height()); + Size2 ms(0, MAX(MAX(tab_bg->get_minimum_size().height, tab_fg->get_minimum_size().height), tab_disabled->get_minimum_size().height)+font->get_height()); for(int i=0;i<tabs.size();i++) { @@ -49,7 +50,9 @@ Size2 Tabs::get_minimum_size() const { ms.width+=font->get_string_size(tabs[i].text).width; - if (current==i) + if (tabs[i].disabled) + ms.width += tab_disabled->get_minimum_size().width; + else if (current==i) ms.width+=tab_fg->get_minimum_size().width; else ms.width+=tab_bg->get_minimum_size().width; @@ -111,7 +114,7 @@ void Tabs::_gui_input(const InputEvent& p_event) { hover_buttons = i; break; } - else if (tabs[i].cb_rect.has_point(pos)) { + else if (!tabs[i].disabled && tabs[i].cb_rect.has_point(pos)) { cb_hover=i; rb_hover=-1; hover_buttons = i; @@ -206,7 +209,9 @@ void Tabs::_gui_input(const InputEvent& p_event) { } if (pos.x >=tabs[i].ofs_cache && pos.x<tabs[i].ofs_cache+tabs[i].size_cache) { - found=i; + if (!tabs[i].disabled) { + found = i; + } break; } } @@ -242,9 +247,11 @@ void Tabs::_notification(int p_what) { Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); + Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); Ref<Font> font = get_font("font"); Color color_fg = get_color("font_color_fg"); Color color_bg = get_color("font_color_bg"); + Color color_disabled = get_color("font_color_disabled"); Ref<Texture> close=get_icon("close"); int h = get_size().height; @@ -301,7 +308,10 @@ void Tabs::_notification(int p_what) { Ref<StyleBox> sb; Color col; - if (i==current) { + if (tabs[i].disabled) { + sb = tab_disabled; + col = color_disabled; + } else if (i == current) { sb=tab_fg; col=color_fg; } else { @@ -366,7 +376,7 @@ void Tabs::_notification(int p_what) { cb_rect.pos.x=w; cb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(cb_rect.size.y))/2; - if (cb_hover==i) { + if (!tabs[i].disabled && cb_hover == i) { if (cb_pressing) get_stylebox("button_pressed")->draw(ci,cb_rect); else @@ -463,6 +473,18 @@ Ref<Texture> Tabs::get_tab_icon(int p_tab) const{ } +void Tabs::set_tab_disabled(int p_tab, bool p_disabled) { + + ERR_FAIL_INDEX(p_tab, tabs.size()); + tabs[p_tab].disabled = p_disabled; + update(); +} +bool Tabs::get_tab_disabled(int p_tab) const { + + ERR_FAIL_INDEX_V(p_tab, tabs.size(), false); + return tabs[p_tab].disabled; +} + void Tabs::set_tab_right_button(int p_tab,const Ref<Texture>& p_right_button){ ERR_FAIL_INDEX(p_tab,tabs.size()); @@ -484,6 +506,7 @@ void Tabs::add_tab(const String& p_str,const Ref<Texture>& p_icon) { Tab t; t.text=p_str; t.icon=p_icon; + t.disabled = false; tabs.push_back(t); @@ -534,6 +557,7 @@ int Tabs::get_tab_width(int p_idx) const { Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); + Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); Ref<Font> font = get_font("font"); @@ -549,7 +573,9 @@ int Tabs::get_tab_width(int p_idx) const { x+=font->get_string_size(tabs[p_idx].text).width; - if (current==p_idx) + if (tabs[p_idx].disabled) + x += tab_disabled->get_minimum_size().width; + else if (current==p_idx) x+=tab_fg->get_minimum_size().width; else x+=tab_bg->get_minimum_size().width; @@ -657,6 +683,8 @@ void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tab_title","tab_idx"),&Tabs::get_tab_title); ClassDB::bind_method(D_METHOD("set_tab_icon","tab_idx","icon:Texture"),&Tabs::set_tab_icon); ClassDB::bind_method(D_METHOD("get_tab_icon:Texture","tab_idx"),&Tabs::get_tab_icon); + ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &Tabs::set_tab_disabled); + ClassDB::bind_method(D_METHOD("get_tab_disabled", "tab_idx"), &Tabs::get_tab_disabled); ClassDB::bind_method(D_METHOD("remove_tab","tab_idx"),&Tabs::remove_tab); ClassDB::bind_method(D_METHOD("add_tab","title","icon:Texture"),&Tabs::add_tab); ClassDB::bind_method(D_METHOD("set_tab_align","align"),&Tabs::set_tab_align); diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index 9ba32297dc..83dcce2613 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -57,6 +57,7 @@ private: String text; Ref<Texture> icon; int ofs_cache; + bool disabled; int size_cache; int x_cache; int x_size_cache; @@ -105,6 +106,9 @@ public: void set_tab_icon(int p_tab,const Ref<Texture>& p_icon); Ref<Texture> get_tab_icon(int p_tab) const; + + void set_tab_disabled(int p_tab, bool p_disabled); + bool get_tab_disabled(int p_tab) const; void set_tab_right_button(int p_tab,const Ref<Texture>& p_right_button); Ref<Texture> get_tab_right_button(int p_tab) const; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 3f2eab8bef..f1b061c506 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -4267,7 +4267,7 @@ void TextEdit::_update_completion_candidates() { //no completion here //print_line("cancel!"); cancel=true; - } if (inquote && first_quote!=-1) { + } else if (inquote && first_quote!=-1) { s=l.substr(first_quote,cofs-first_quote); //print_line("s: 1"+s); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 7bfc24079b..cd93c13c99 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -848,6 +848,7 @@ void Tree::update_cache() { cache.title_button_color = get_color("title_button_color"); v_scroll->set_custom_step(cache.font->get_height()); + cache.click_item=get_selected(); } diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 488256970f..a189702894 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2288,7 +2288,7 @@ int Node::get_position_in_parent() const { -Node *Node::_duplicate(bool p_use_instancing) const { +Node *Node::_duplicate(int p_flags) const { Node *node=NULL; @@ -2302,7 +2302,7 @@ Node *Node::_duplicate(bool p_use_instancing) const { nip->set_instance_path( ip->get_instance_path() ); node=nip; - } else if (p_use_instancing && get_filename()!=String()) { + } else if ((p_flags&DUPLICATE_USE_INSTANCING) && get_filename()!=String()) { Ref<PackedScene> res = ResourceLoader::load(get_filename()); ERR_FAIL_COND_V(res.is_null(),NULL); @@ -2335,20 +2335,26 @@ Node *Node::_duplicate(bool p_use_instancing) const { if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) continue; String name = E->get().name; + if (!(p_flags&DUPLICATE_SCRIPTS) && name=="script/script") + continue; + node->set( name, get(name) ); } node->set_name(get_name()); - List<GroupInfo> gi; - get_groups(&gi); - for (List<GroupInfo>::Element *E=gi.front();E;E=E->next()) { + if (p_flags & DUPLICATE_GROUPS) { + List<GroupInfo> gi; + get_groups(&gi); + for (List<GroupInfo>::Element *E=gi.front();E;E=E->next()) { - node->add_to_group(E->get().name, E->get().persistent); + node->add_to_group(E->get().name, E->get().persistent); + } } - _duplicate_signals(this, node); + if (p_flags & DUPLICATE_SIGNALS) + _duplicate_signals(this, node); for(int i=0;i<get_child_count();i++) { @@ -2357,7 +2363,7 @@ Node *Node::_duplicate(bool p_use_instancing) const { if (instanced && get_child(i)->data.owner==this) continue; //part of instance - Node *dup = get_child(i)->duplicate(p_use_instancing); + Node *dup = get_child(i)->duplicate(p_flags); if (!dup) { memdelete(node); @@ -2371,11 +2377,11 @@ Node *Node::_duplicate(bool p_use_instancing) const { return node; } -Node *Node::duplicate(bool p_use_instancing) const { +Node *Node::duplicate(int p_flags) const { - Node* dupe = _duplicate(p_use_instancing); + Node* dupe = _duplicate(p_flags); - if (dupe) { + if (dupe && (p_flags&DUPLICATE_SIGNALS)) { _duplicate_signals(this,dupe); } @@ -2968,7 +2974,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tree:SceneTree"),&Node::get_tree); - ClassDB::bind_method(D_METHOD("duplicate:Node","use_instancing"),&Node::duplicate,DEFVAL(false)); + ClassDB::bind_method(D_METHOD("duplicate:Node","flags"),&Node::duplicate,DEFVAL(DUPLICATE_USE_INSTANCING|DUPLICATE_SIGNALS|DUPLICATE_GROUPS|DUPLICATE_SCRIPTS)); ClassDB::bind_method(D_METHOD("replace_by","node:Node","keep_data"),&Node::replace_by,DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_scene_instance_load_placeholder","load_placeholder"),&Node::set_scene_instance_load_placeholder); @@ -3058,6 +3064,10 @@ void Node::_bind_methods() { BIND_CONSTANT( PAUSE_MODE_STOP ); BIND_CONSTANT( PAUSE_MODE_PROCESS ); + BIND_CONSTANT( DUPLICATE_SIGNALS ); + BIND_CONSTANT( DUPLICATE_GROUPS ); + BIND_CONSTANT( DUPLICATE_SCRIPTS ); + ADD_SIGNAL( MethodInfo("renamed") ); ADD_SIGNAL( MethodInfo("tree_entered") ); ADD_SIGNAL( MethodInfo("tree_exited") ); diff --git a/scene/main/node.h b/scene/main/node.h index 93b250ab0f..b042cabb6f 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -54,6 +54,14 @@ public: PAUSE_MODE_PROCESS }; + enum DuplicateFlags { + + DUPLICATE_SIGNALS=1, + DUPLICATE_GROUPS=2, + DUPLICATE_SCRIPTS=4, + DUPLICATE_USE_INSTANCING=8 + }; + enum NetworkMode { NETWORK_MODE_INHERIT, @@ -177,7 +185,7 @@ private: void _duplicate_signals(const Node* p_original,Node* p_copy) const; void _duplicate_and_reown(Node* p_new_parent, const Map<Node*,Node*>& p_reown_map) const; - Node *_duplicate(bool p_use_instancing) const; + Node *_duplicate(int p_flags) const; Array _get_children() const; Array _get_groups() const; @@ -332,7 +340,7 @@ public: int get_position_in_parent() const; - Node *duplicate(bool p_use_instancing=false) const; + Node *duplicate(int p_flags=DUPLICATE_GROUPS|DUPLICATE_SIGNALS|DUPLICATE_SCRIPTS) const; Node *duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const; //Node *clone_tree() const; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 50c6a6c725..dbe0f3e33e 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -583,24 +583,19 @@ void fill_default_theme(Ref<Theme>& t, const Ref<Font> & default_font, const Ref // WindowDialog - Ref<StyleBoxTexture> style_pp_win = sb_expand(make_stylebox( popup_window_png,10,30,10,8),8,26,8,4); - /*for(int i=0;i<4;i++) - style_pp_win->set_expand_margin_size((Margin)i,3); - style_pp_win->set_expand_margin_size(MARGIN_TOP,26);*/ + Ref<StyleBoxTexture> style_pp_win = sb_expand(make_stylebox(popup_window_png, 10, 26, 10, 8), 8, 24, 8, 6); + t->set_stylebox("panel", "WindowDialog", style_pp_win); + t->set_constant("titlebar_height", "WindowDialog", 20 * scale); + t->set_constant("scaleborder_size", "WindowDialog", 4); - t->set_stylebox("panel","WindowDialog", style_pp_win ); + t->set_font("title_font", "WindowDialog", large_font); + t->set_color("title_color", "WindowDialog", Color(0, 0, 0)); + t->set_constant("title_height", "WindowDialog", 18 * scale); - t->set_icon("close","WindowDialog", make_icon( close_png ) ); - t->set_icon("close_hilite","WindowDialog", make_icon( close_hl_png ) ); - - t->set_font("title_font","WindowDialog", large_font ); - - t->set_color("title_color","WindowDialog", Color(0,0,0) ); - - t->set_constant("close_h_ofs","WindowDialog", 22 *scale); - t->set_constant("close_v_ofs","WindowDialog", 20 *scale); - t->set_constant("titlebar_height","WindowDialog", 18 *scale); - t->set_constant("title_height","WindowDialog", 20 *scale); + t->set_icon("close", "WindowDialog", make_icon(close_png)); + t->set_icon("close_hilite", "WindowDialog", make_icon(close_hl_png)); + t->set_constant("close_h_ofs", "WindowDialog", 18 * scale); + t->set_constant("close_v_ofs", "WindowDialog", 18 * scale); // File Dialog @@ -750,6 +745,7 @@ void fill_default_theme(Ref<Theme>& t, const Ref<Font> & default_font, const Ref t->set_stylebox("tab_fg","TabContainer", sb_expand( make_stylebox( tab_current_png,4,4,4,1,16,4,16,4),2,2,2,2) ); t->set_stylebox("tab_bg","TabContainer", sb_expand( make_stylebox( tab_behind_png,5,5,5,1,16,6,16,4),3,0,3,3) ); + t->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); t->set_stylebox("panel","TabContainer", tc_sb ); t->set_icon("increment","TabContainer",make_icon( scroll_button_right_png)); @@ -763,6 +759,7 @@ void fill_default_theme(Ref<Theme>& t, const Ref<Font> & default_font, const Ref t->set_color("font_color_fg","TabContainer", control_font_color_hover ); t->set_color("font_color_bg","TabContainer", control_font_color_low ); + t->set_color("font_color_disabled", "TabContainer", control_font_color_disabled); t->set_constant("side_margin","TabContainer", 8 *scale); t->set_constant("top_margin","TabContainer", 24 *scale); @@ -776,6 +773,7 @@ void fill_default_theme(Ref<Theme>& t, const Ref<Font> & default_font, const Ref t->set_stylebox("tab_fg","Tabs", sb_expand( make_stylebox( tab_current_png,4,3,4,1,16,3,16,2),2,2,2,2) ); t->set_stylebox("tab_bg","Tabs", sb_expand( make_stylebox( tab_behind_png,5,4,5,1,16,5,16,2),3,3,3,3) ); + t->set_stylebox("tab_disabled", "Tabs", sb_expand(make_stylebox(tab_disabled_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3)); t->set_stylebox("panel","Tabs",tc_sb ); t->set_stylebox("button_pressed","Tabs", make_stylebox( button_pressed_png,4,4,4,4) ); t->set_stylebox("button","Tabs", make_stylebox( button_normal_png,4,4,4,4) ); @@ -790,6 +788,7 @@ void fill_default_theme(Ref<Theme>& t, const Ref<Font> & default_font, const Ref t->set_color("font_color_fg","Tabs", control_font_color_hover ); t->set_color("font_color_bg","Tabs", control_font_color_low ); + t->set_color("font_color_disabled", "Tabs", control_font_color_disabled); t->set_constant("top_margin","Tabs", 24 *scale); t->set_constant("label_valign_fg","Tabs", 0 *scale); @@ -982,7 +981,7 @@ void make_default_theme(bool p_hidpi,Ref<Font> p_font) { Ref<BitmapFont> default_font; if (p_font.is_valid()) { default_font=p_font; - } if (p_hidpi) { + } else if (p_hidpi) { default_font=make_font2(_hidpi_font_height,_hidpi_font_ascent,_hidpi_font_charcount,&_hidpi_font_charrects[0][0],_hidpi_font_kerning_pair_count,&_hidpi_font_kerning_pairs[0][0],_hidpi_font_img_width,_hidpi_font_img_height,_hidpi_font_img_data); } else { default_font=make_font2(_lodpi_font_height,_lodpi_font_ascent,_lodpi_font_charcount,&_lodpi_font_charrects[0][0],_lodpi_font_kerning_pair_count,&_lodpi_font_kerning_pairs[0][0],_lodpi_font_img_width,_lodpi_font_img_height,_lodpi_font_img_data); diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 5b5868ba14..394cfaf424 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -458,6 +458,10 @@ static const unsigned char tab_current_png[]={ 0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x3,0x0,0x0,0x0,0x28,0x2d,0xf,0x53,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1,0x8f,0xb,0xfc,0x61,0x5,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a,0x26,0x0,0x0,0x80,0x84,0x0,0x0,0xfa,0x0,0x0,0x0,0x80,0xe8,0x0,0x0,0x75,0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x70,0x9c,0xba,0x51,0x3c,0x0,0x0,0x0,0x9c,0x50,0x4c,0x54,0x45,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0x3d,0x48,0x5b,0x58,0x66,0x5b,0x57,0x65,0x57,0x54,0x62,0x55,0x53,0x62,0x4a,0x46,0x52,0x46,0x41,0x4e,0x45,0x41,0x4d,0x55,0x52,0x60,0x44,0x41,0x4c,0x53,0x50,0x5e,0x43,0x40,0x4b,0x52,0x4e,0x5d,0x41,0x3e,0x4a,0x4f,0x4d,0x5a,0x3f,0x3d,0x48,0x4e,0x4b,0x59,0x3e,0x3c,0x47,0x4d,0x4a,0x58,0x3d,0x3b,0x46,0x4b,0x49,0x54,0x3c,0x3a,0x44,0x4b,0x47,0x54,0x3b,0x39,0x43,0x3b,0x39,0x42,0x3b,0x38,0x43,0x3b,0x38,0x42,0x3a,0x37,0x41,0x39,0x37,0x41,0x3a,0x38,0x41,0x39,0x36,0x3f,0x38,0x36,0x3f,0x39,0x36,0x40,0x38,0x36,0x40,0x37,0x35,0x3e,0x37,0x34,0x3e,0x36,0x35,0x3d,0x35,0x32,0x3b,0x59,0xdd,0xd3,0xff,0x0,0x0,0x0,0x11,0x74,0x52,0x4e,0x53,0x4,0xa,0x11,0x19,0x1f,0x22,0x24,0x15,0x25,0x34,0x3f,0x46,0x47,0x48,0x77,0xef,0xef,0xa3,0x31,0x6b,0xc2,0x0,0x0,0x0,0x1,0x62,0x4b,0x47,0x44,0x33,0x37,0xd5,0x7c,0x5e,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x6,0x16,0x12,0x2b,0x5,0x39,0x1a,0x32,0x39,0x0,0x0,0x0,0xa2,0x49,0x44,0x41,0x54,0x18,0xd3,0x45,0xcd,0xd9,0x12,0x82,0x30,0xc,0x40,0xd1,0x0,0x2d,0x4b,0x5b,0x36,0x59,0x44,0x44,0x44,0xa4,0x68,0x59,0x54,0xfc,0xff,0x8f,0x33,0x30,0x4c,0x3d,0x93,0xa7,0x3b,0x93,0x4,0xc0,0x30,0x2d,0x42,0x6d,0x44,0x89,0x65,0x1a,0x0,0x86,0xe3,0x7a,0x8c,0xb,0xdf,0x17,0x9c,0x79,0xae,0x63,0x80,0xe9,0x6,0x61,0x7c,0xd8,0xc4,0x61,0xe0,0x9a,0x60,0x79,0x51,0x92,0x66,0x9b,0x34,0x89,0x3c,0xb,0x8,0xcb,0xb3,0xe3,0x2e,0xcb,0x19,0x1,0xca,0x8b,0x93,0x56,0x70,0xa,0xb6,0x28,0xcf,0x5a,0x29,0x6c,0xb0,0xfd,0xea,0xa2,0x55,0xfe,0x1a,0xea,0xab,0x56,0xaf,0x41,0x34,0x37,0xad,0xc1,0x15,0xca,0xdb,0xbb,0xd6,0xe2,0x51,0xc2,0xba,0x7f,0xe8,0xf0,0x2d,0x6,0x29,0xfb,0x5e,0xca,0xc7,0x53,0xca,0x3d,0xa8,0x61,0x50,0xc3,0xa8,0xc6,0x41,0xed,0x61,0x9a,0xa6,0x19,0xbd,0xe6,0xf7,0x1e,0x3e,0xcb,0x82,0x83,0xbe,0x18,0x7e,0xa1,0xe5,0x17,0x1f,0xcf,0x5d,0x82,0x6b,0x0,0x0,0x0,0x25,0x74,0x45,0x58,0x74,0x64,0x61,0x74,0x65,0x3a,0x63,0x72,0x65,0x61,0x74,0x65,0x0,0x32,0x30,0x31,0x36,0x2d,0x30,0x36,0x2d,0x32,0x32,0x54,0x32,0x30,0x3a,0x33,0x39,0x3a,0x32,0x36,0x2b,0x30,0x32,0x3a,0x30,0x30,0xc9,0xad,0xc8,0x52,0x0,0x0,0x0,0x25,0x74,0x45,0x58,0x74,0x64,0x61,0x74,0x65,0x3a,0x6d,0x6f,0x64,0x69,0x66,0x79,0x0,0x32,0x30,0x31,0x36,0x2d,0x30,0x36,0x2d,0x32,0x32,0x54,0x32,0x30,0x3a,0x33,0x39,0x3a,0x32,0x36,0x2b,0x30,0x32,0x3a,0x30,0x30,0xb8,0xf0,0x70,0xee,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; +static const unsigned char tab_disabled_png[] = { +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x12,0x0,0x0,0xb,0x12,0x1,0xd2,0xdd,0x7e,0xfc,0x0,0x0,0x0,0xd2,0x49,0x44,0x41,0x54,0x38,0xcb,0xd5,0x90,0x51,0xa,0xc2,0x30,0xc,0x86,0xd3,0x2e,0xdb,0x4,0x1f,0xb6,0x57,0x75,0x77,0xd9,0x1d,0x3c,0x8d,0x47,0xd8,0x69,0xbc,0x81,0xf,0xbb,0xcb,0xf0,0x6d,0xa8,0xa0,0xa0,0x6b,0xd7,0x9a,0x40,0x26,0xa,0xdb,0x98,0x22,0x88,0x81,0xf,0x92,0xf2,0xe7,0x4f,0x13,0x5,0x0,0x48,0x44,0x44,0x4c,0xcc,0x24,0xf,0x8,0xd,0xaf,0xe1,0x88,0x96,0x68,0x88,0x2b,0x71,0xe3,0xbc,0x6b,0x9e,0x13,0x29,0x91,0x48,0xce,0x66,0x4a,0xe0,0xf0,0x2,0x37,0x5d,0x88,0x13,0x71,0x4,0x99,0xce,0xe2,0x34,0xcf,0xf3,0x75,0xb6,0xcc,0xa,0xd3,0x1a,0x18,0x8b,0x30,0x8,0xa1,0xda,0x57,0x9b,0xb2,0x2c,0xb7,0x54,0x5a,0x94,0x6f,0x27,0xab,0xc5,0xaa,0xa8,0xf,0x35,0x58,0x6b,0xc1,0x7b,0xdf,0xdb,0xac,0x94,0x2,0x44,0x4,0xd6,0x52,0xb9,0x23,0xce,0x8f,0x15,0x1a,0xdb,0x80,0x31,0xe3,0xd3,0xd9,0x98,0x35,0xac,0x95,0x55,0x23,0x2d,0x7,0x8b,0x87,0xa6,0xe,0x19,0xc9,0xea,0x1,0xca,0xb5,0x15,0x3f,0x4e,0x35,0x11,0x1d,0x1f,0x58,0x63,0xb7,0xde,0x87,0x6,0x80,0xcf,0x8f,0x6f,0x1a,0xc0,0x77,0xd,0x9c,0x73,0x93,0xd,0x58,0xdb,0x85,0xee,0x73,0xfd,0xcd,0xa,0xff,0x6b,0x70,0x7,0xd6,0xd5,0x90,0x3b,0x10,0xe9,0x51,0x80,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + static const unsigned char tab_menu_png[]={ 0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x6f,0x49,0x44,0x41,0x54,0x38,0x8d,0x63,0x60,0x18,0x5,0xa3,0x80,0x81,0x81,0x11,0x5d,0xe0,0xc1,0x83,0x7,0xff,0xf1,0x69,0x50,0x50,0x50,0x40,0xd1,0xc3,0x44,0xa9,0xb,0xa8,0x6f,0x0,0x23,0x23,0x63,0x3c,0x3,0x3,0xc3,0x57,0x2c,0x6a,0xbf,0x33,0x32,0x32,0xa6,0x63,0xa8,0xc7,0x66,0xea,0xfd,0xfb,0xf7,0x35,0x18,0x18,0x18,0x56,0x31,0x32,0x32,0xea,0x42,0x85,0x6e,0x30,0x33,0x33,0x87,0xc9,0xca,0xca,0x5e,0x26,0xca,0x0,0x6,0x6,0x6,0x86,0x17,0x2f,0x5e,0x70,0xff,0xfc,0xf9,0x73,0xa,0x3,0x3,0x3,0x3,0x3b,0x3b,0x7b,0x8e,0x84,0x84,0x4,0x36,0x57,0xd,0x2,0x0,0x0,0x67,0xf2,0x14,0xc2,0xc2,0xbe,0xf5,0xb5,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index ffa35a93d8..d3a913680b 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -51,6 +51,7 @@ SceneStringNames::SceneStringNames() { sleeping_state_changed=StaticCString::create("sleeping_state_changed"); finished=StaticCString::create("finished"); + emission_finished=StaticCString::create("emission_finished"); animation_finished=StaticCString::create("animation_finished"); animation_changed=StaticCString::create("animation_changed"); animation_started=StaticCString::create("animation_started"); @@ -115,6 +116,7 @@ SceneStringNames::SceneStringNames() { _area_enter_tree = StaticCString::create("_area_enter_tree"); _area_exit_tree = StaticCString::create("_area_exit_tree"); + _input = StaticCString::create("_input"); _input_event=StaticCString::create("_input_event"); gui_input=StaticCString::create("gui_input"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 125d391294..624a9147d5 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -80,6 +80,7 @@ public: StringName sort_children; StringName finished; + StringName emission_finished; StringName animation_finished; StringName animation_changed; StringName animation_started; |