diff options
Diffstat (limited to 'scene')
| -rw-r--r-- | scene/2d/physics_body_2d.cpp | 6 | ||||
| -rw-r--r-- | scene/2d/ray_cast_2d.cpp | 2 | ||||
| -rw-r--r-- | scene/3d/physics_body.cpp | 6 | ||||
| -rw-r--r-- | scene/3d/ray_cast.cpp | 2 | ||||
| -rw-r--r-- | scene/animation/tween.cpp | 13 | ||||
| -rw-r--r-- | scene/audio/stream_player.cpp | 4 | ||||
| -rw-r--r-- | scene/gui/control.cpp | 7 | ||||
| -rw-r--r-- | scene/gui/menu_button.cpp | 18 | ||||
| -rw-r--r-- | scene/gui/popup_menu.cpp | 26 | ||||
| -rw-r--r-- | scene/gui/popup_menu.h | 2 | ||||
| -rw-r--r-- | scene/gui/progress_bar.cpp | 4 | ||||
| -rw-r--r-- | scene/gui/text_edit.cpp | 222 | ||||
| -rw-r--r-- | scene/gui/text_edit.h | 16 | ||||
| -rw-r--r-- | scene/main/timer.cpp | 26 | ||||
| -rw-r--r-- | scene/main/timer.h | 4 | ||||
| -rw-r--r-- | scene/scene_string_names.cpp | 1 | ||||
| -rw-r--r-- | scene/scene_string_names.h | 1 |
17 files changed, 272 insertions, 88 deletions
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index cc2e5c0d72..dc038f010c 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -544,7 +544,10 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { set_global_transform(state->get_transform()); linear_velocity=state->get_linear_velocity(); angular_velocity=state->get_angular_velocity(); - sleeping=state->is_sleeping(); + if(sleeping!=state->is_sleeping()) { + sleeping=state->is_sleeping(); + emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); + } if (get_script_instance()) get_script_instance()->call("_integrate_forces",state); set_block_transform_notify(false); // want it back @@ -934,6 +937,7 @@ void RigidBody2D::_bind_methods() { ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"local_shape"))); ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body"))); ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body"))); + ADD_SIGNAL( MethodInfo("sleeping_state_changed")); BIND_CONSTANT( MODE_STATIC ); BIND_CONSTANT( MODE_KINEMATIC ); diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 4a774b0198..6cda52fa4e 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -33,7 +33,7 @@ void RayCast2D::set_cast_to(const Vector2& p_point) { cast_to=p_point; - if (is_inside_tree() && get_tree()->is_editor_hint()) + if (is_inside_tree() && (get_tree()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) update(); } diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 1a2665b6ad..bc637eed44 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -419,7 +419,10 @@ void RigidBody::_direct_state_changed(Object *p_state) { set_global_transform(state->get_transform()); linear_velocity=state->get_linear_velocity(); angular_velocity=state->get_angular_velocity(); - sleeping=state->is_sleeping(); + if(sleeping!=state->is_sleeping()) { + sleeping=state->is_sleeping(); + emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); + } if (get_script_instance()) get_script_instance()->call("_integrate_forces",state); set_ignore_transform_notification(false); @@ -811,6 +814,7 @@ void RigidBody::_bind_methods() { ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"local_shape"))); ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body"))); ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body"))); + ADD_SIGNAL( MethodInfo("sleeping_state_changed")); BIND_CONSTANT( MODE_STATIC ); BIND_CONSTANT( MODE_KINEMATIC ); diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp index ab2c4fc8dc..29813597fa 100644 --- a/scene/3d/ray_cast.cpp +++ b/scene/3d/ray_cast.cpp @@ -33,7 +33,7 @@ void RayCast::set_cast_to(const Vector3& p_point) { cast_to=p_point; - if (is_inside_tree() && get_tree()->is_editor_hint()) + if (is_inside_tree() && (get_tree()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) update_gizmo(); } diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 7edd57603b..6f6f5d3aff 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -1045,6 +1045,7 @@ bool Tween::interpolate_property(Object *p_object if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); ERR_FAIL_COND_V(p_object == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_initial_val.get_type() != p_final_val.get_type(), false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); @@ -1104,6 +1105,7 @@ bool Tween::interpolate_method(Object *p_object if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); ERR_FAIL_COND_V(p_object == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_initial_val.get_type() != p_final_val.get_type(), false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); @@ -1154,7 +1156,9 @@ bool Tween::interpolate_callback(Object *p_object ); return true; } + ERR_FAIL_COND_V(p_object == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_times_in_sec < 0, false); ERR_EXPLAIN("Object has no callback named: %s" + p_callback); @@ -1219,6 +1223,7 @@ bool Tween::interpolate_deferred_callback(Object *p_object return true; } ERR_FAIL_COND_V(p_object == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_times_in_sec < 0, false); ERR_EXPLAIN("Object has no callback named: %s" + p_callback); @@ -1291,7 +1296,9 @@ bool Tween::follow_property(Object *p_object if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t(); ERR_FAIL_COND_V(p_object == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_target == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); @@ -1357,7 +1364,9 @@ bool Tween::follow_method(Object *p_object if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t(); ERR_FAIL_COND_V(p_object == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_target == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); @@ -1424,7 +1433,9 @@ bool Tween::targeting_property(Object *p_object if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); ERR_FAIL_COND_V(p_object == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_initial == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); @@ -1495,7 +1506,9 @@ bool Tween::targeting_method(Object *p_object if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); ERR_FAIL_COND_V(p_object == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_initial == NULL, false); + ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); diff --git a/scene/audio/stream_player.cpp b/scene/audio/stream_player.cpp index c1799ec12c..b6b1ee85f3 100644 --- a/scene/audio/stream_player.cpp +++ b/scene/audio/stream_player.cpp @@ -342,8 +342,8 @@ int StreamPlayer::get_buffering_msec() const{ void StreamPlayer::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_stream","stream:Stream"),&StreamPlayer::set_stream); - ObjectTypeDB::bind_method(_MD("get_stream:Stream"),&StreamPlayer::get_stream); + ObjectTypeDB::bind_method(_MD("set_stream","stream:AudioStream"),&StreamPlayer::set_stream); + ObjectTypeDB::bind_method(_MD("get_stream:AudioStream"),&StreamPlayer::get_stream); ObjectTypeDB::bind_method(_MD("play","offset"),&StreamPlayer::play,DEFVAL(0)); ObjectTypeDB::bind_method(_MD("stop"),&StreamPlayer::stop); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index b393f926e7..a30c05527c 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -604,8 +604,11 @@ void Control::_notification(int p_notification) { if(get_viewport() != NULL) get_viewport()->_gui_hid_control(this); - _modal_stack_remove(); - minimum_size_changed(); + + if(is_inside_tree()) { + _modal_stack_remove(); + minimum_size_changed(); + } //remove key focus //remove modalness diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index cb8806e2ef..0f415f013d 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -53,23 +53,7 @@ void MenuButton::_unhandled_key_input(InputEvent p_event) { code|=KEY_MASK_SHIFT; - int item = popup->find_item_by_accelerator(code); - - - if (item>=0 && ! popup->is_item_disabled(item)) - popup->activate_item(item); - /* - for(int i=0;i<items.size();i++) { - - - if (items[i].accel==0) - continue; - - if (items[i].accel==code) { - - emit_signal("item_pressed",items[i].ID); - } - }*/ + int item = popup->activate_item_by_accelerator(code); } } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 3329d24890..819885809b 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -740,15 +740,33 @@ int PopupMenu::get_item_count() const { return items.size(); } -int PopupMenu::find_item_by_accelerator(uint32_t p_accel) const { +bool PopupMenu::activate_item_by_accelerator(uint32_t p_accel) { int il=items.size(); for(int i=0;i<il;i++) { + if (is_item_disabled(i)) + continue; - if (items[i].accel==p_accel) - return i; + if (items[i].accel==p_accel) { + activate_item(i); + return true; + } + + if (items[i].submenu!="") { + Node* n = get_node(items[i].submenu); + if(!n) + continue; + + PopupMenu* pm = n->cast_to<PopupMenu>(); + if(!pm) + continue; + + if(pm->activate_item_by_accelerator(p_accel)) { + return true; + } + } } - return -1; + return false; } void PopupMenu::activate_item(int p_item) { diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 72f8795067..0e98765dc4 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -117,7 +117,7 @@ public: int get_item_count() const; - int find_item_by_accelerator(uint32_t p_accel) const; + bool activate_item_by_accelerator(uint32_t p_accel); void activate_item(int p_item); void remove_item(int p_idx); diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp index fc0e7be34f..02da8ff27e 100644 --- a/scene/gui/progress_bar.cpp +++ b/scene/gui/progress_bar.cpp @@ -35,7 +35,9 @@ Size2 ProgressBar::get_minimum_size() const { Ref<Font> font = get_font("font"); Size2 ms=bg->get_minimum_size()+bg->get_center_size(); - ms.height=MAX(ms.height,bg->get_minimum_size().height+font->get_height()); + if (percent_visible) { + ms.height=MAX(ms.height,bg->get_minimum_size().height+font->get_height()); + } return ms; } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index c9dd2dacf9..f7461a736c 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -44,7 +44,7 @@ static bool _is_text_char(CharType c) { static bool _is_symbol(CharType c) { - return c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t'); + return c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t' || c==' '); } static bool _is_char(CharType c) { @@ -671,6 +671,8 @@ void TextEdit::_notification(int p_what) { bool prev_is_number = false; bool in_keyword=false; bool in_word = false; + bool in_function_name = false; + bool in_member_variable = false; Color keyword_color; // check if line contains highlighted word @@ -680,14 +682,12 @@ void TextEdit::_notification(int p_what) { } if (cache.line_number_w) { - Color fcol = cache.font_color; - fcol.a*=0.4; String fc = String::num(line+1); while (fc.length() < line_number_char_count) { fc="0"+fc; } - cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,fcol); + cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,cache.line_number_color); } const Map<int,Text::ColorRegionInfo>& cri_map=text.get_color_region_info(line); @@ -790,11 +790,42 @@ void TextEdit::_notification(int p_what) { } } + if (!in_function_name && in_word && !in_keyword) { + + int k = j; + while(k < str.length() && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + k++; + } + + if (str[k] == '(') { + in_function_name = true; + } + } + + if (!in_function_name && !in_member_variable && !in_keyword && !is_number && in_word) { + int k = j; + while(k > 0 && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + k--; + } + + if (str[k] == '.') { + in_member_variable = true; + } + } + + if (is_symbol) { + in_function_name = false; + in_member_variable = false; + } if (in_region>=0) color=color_regions[in_region].color; else if (in_keyword) color=keyword_color; + else if (in_member_variable) + color=cache.member_variable_color; + else if (in_function_name) + color=cache.function_color; else if (is_symbol) color=symbol_color; else if (is_number) @@ -890,7 +921,12 @@ void TextEdit::_notification(int p_what) { if (cursor.column==j && cursor.line==line) { cursor_pos = Point2i( char_ofs+char_margin, ofs_y ); - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color); + if (insert_mode) { + cursor_pos.y += get_row_height(); + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(char_w,1)),cache.caret_color); + } else { + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.caret_color); + } } @@ -901,8 +937,13 @@ void TextEdit::_notification(int p_what) { if (cursor.column==str.length() && cursor.line==line && (char_ofs+char_margin)>=xmargin_beg) { cursor_pos=Point2i( char_ofs+char_margin, ofs_y ); - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color); - + if (insert_mode) { + cursor_pos.y += get_row_height(); + int char_w = cache.font->get_char_size(' ').width; + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(char_w,1)),cache.caret_color); + } else { + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.caret_color); + } } } @@ -1104,7 +1145,7 @@ void TextEdit::_consume_pair_symbol(CharType ch) { int new_column,new_line; - _begin_compex_operation(); + begin_complex_operation(); _insert_text(get_selection_from_line(), get_selection_from_column(), ch_single, &new_line, &new_column); @@ -1117,7 +1158,7 @@ void TextEdit::_consume_pair_symbol(CharType ch) { get_selection_to_column() + to_col_offset, ch_single_pair, &new_line,&new_column); - _end_compex_operation(); + end_complex_operation(); cursor_set_line(get_selection_to_line()); cursor_set_column(get_selection_to_column() + to_col_offset); @@ -1201,6 +1242,66 @@ void TextEdit::backspace_at_cursor() { } +void TextEdit::indent_selection_right() { + + if (!is_selection_active()) { + return; + } + begin_complex_operation(); + int start_line = get_selection_from_line(); + int end_line = get_selection_to_line(); + + // ignore if the cursor is not past the first column + if (get_selection_to_column() == 0) { + end_line--; + } + + for (int i = start_line; i <= end_line; i++) { + String line_text = get_line(i); + line_text = '\t' + line_text; + set_line(i, line_text); + } + + // fix selection being off by one on the last line + selection.to_column++; + end_complex_operation(); + update(); +} + +void TextEdit::indent_selection_left() { + + if (!is_selection_active()) { + return; + } + begin_complex_operation(); + int start_line = get_selection_from_line(); + int end_line = get_selection_to_line(); + + // ignore if the cursor is not past the first column + if (get_selection_to_column() == 0) { + end_line--; + } + String last_line_text = get_line(end_line); + + for (int i = start_line; i <= end_line; i++) { + String line_text = get_line(i); + + if (line_text.begins_with("\t")) { + line_text = line_text.substr(1, line_text.length()); + set_line(i, line_text); + } else if (line_text.begins_with(" ")) { + line_text = line_text.substr(4, line_text.length()); + set_line(i, line_text); + } + } + + // fix selection being off by one on the last line + if (last_line_text != get_line(end_line) && selection.to_column > 0) { + selection.to_column--; + } + end_complex_operation(); + update(); +} void TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const { @@ -1568,7 +1669,22 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { _consume_pair_symbol(chr[0]); } else { + + // remove the old character if in insert mode + if (insert_mode) { + begin_complex_operation(); + + // make sure we don't try and remove empty space + if (cursor.column < get_line(cursor.line).length()) { + _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1); + } + } + _insert_text_at_cursor(chr); + + if (insert_mode) { + end_complex_operation(); + } } } @@ -1597,8 +1713,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { k.mod.shift=false; } - // stuff to do when selection is active.. + // save here for insert mode, just in case it is cleared in the following section + bool had_selection = selection.active; + // stuff to do when selection is active.. if (selection.active) { if (readonly) @@ -1611,51 +1729,13 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { switch(k.scancode) { case KEY_TAB: { - - String txt = _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column); - String prev_txt=txt; - if (k.mod.shift) { - - for(int i=0;i<txt.length();i++) { - if (((i>0 && txt[i-1]=='\n') || (i==0 /*&& selection.from_column==0*/)) && (txt[i]=='\t' || txt[i]==' ')) { - txt.remove(i); - //i--; - } - } + indent_selection_left(); } else { - - for(int i=0;i<txt.length();i++) { - - if (((i>0 && txt[i-1]=='\n') || (i==0 /*&& selection.from_column==0*/))) { - txt=txt.insert(i,"\t"); - //i--; - } - } - } - - if (txt!=prev_txt) { - - int sel_line=selection.from_line; - int sel_column=selection.from_column; - - cursor_set_line(selection.from_line); - cursor_set_column(selection.from_column); - _begin_compex_operation(); - _remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column); - _insert_text_at_cursor(txt); - _end_compex_operation(); - selection.active=true; - selection.from_column=sel_column; - selection.from_line=sel_line; - selection.to_column=cursor.column; - selection.to_line=cursor.line; - update(); + indent_selection_right(); } - dobreak=true; accept_event(); - } break; case KEY_X: case KEY_C: @@ -1702,6 +1782,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } if (clear) { + begin_complex_operation(); selection.active=false; update(); _remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column); @@ -2335,6 +2416,12 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } } */ + if (k.scancode==KEY_INSERT) { + set_insert_mode(!insert_mode); + accept_event(); + return; + } + if (!scancode_handled && !k.mod.command) { //for german kbds if (k.unicode>=32) { @@ -2342,6 +2429,16 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if (readonly) break; + // remove the old character if in insert mode and no selection + if (insert_mode && !had_selection) { + begin_complex_operation(); + + // make sure we don't try and remove empty space + if (cursor.column < get_line(cursor.line).length()) { + _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1); + } + } + const CharType chr[2] = {(CharType)k.unicode, 0}; if (completion_hint!="" && k.unicode==')') { @@ -2353,6 +2450,13 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { _insert_text_at_cursor(chr); } + if (insert_mode && !had_selection) { + end_complex_operation(); + } + + if (selection.active != had_selection) { + end_complex_operation(); + } accept_event(); } else { @@ -2976,9 +3080,13 @@ void TextEdit::_update_caches() { cache.style_normal=get_stylebox("normal"); cache.style_focus=get_stylebox("focus"); cache.font=get_font("font"); + cache.caret_color=get_color("caret_color"); + cache.line_number_color=get_color("line_number_color"); cache.font_color=get_color("font_color"); cache.font_selected_color=get_color("font_selected_color"); cache.keyword_color=get_color("keyword_color"); + cache.function_color=get_color("function_color"); + cache.member_variable_color=get_color("member_variable_color"); cache.number_color=get_color("number_color"); cache.selection_color=get_color("selection_color"); cache.mark_color=get_color("mark_color"); @@ -3543,12 +3651,12 @@ void TextEdit::clear_undo_history() { } -void TextEdit::_begin_compex_operation() { +void TextEdit::begin_complex_operation() { _push_current_op(); next_operation_is_complex=true; } -void TextEdit::_end_compex_operation() { +void TextEdit::end_complex_operation() { _push_current_op(); ERR_FAIL_COND(undo_stack.size() == 0); @@ -3595,6 +3703,15 @@ bool TextEdit::is_drawing_tabs() const{ return draw_tabs; } +void TextEdit::set_insert_mode(bool p_enabled) { + insert_mode = p_enabled; + update(); +} + +bool TextEdit::is_insert_mode() const { + return insert_mode; +} + uint32_t TextEdit::get_version() const { return current_op.version; } @@ -4087,6 +4204,7 @@ TextEdit::TextEdit() { auto_brace_completion_enabled=false; brace_matching_enabled=false; auto_indent=false; + insert_mode = false; } TextEdit::~TextEdit() diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index e7e6760379..09c2a4d729 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -73,10 +73,14 @@ class TextEdit : public Control { Ref<StyleBox> style_normal; Ref<StyleBox> style_focus; Ref<Font> font; + Color caret_color; + Color line_number_color; Color font_color; Color font_selected_color; Color keyword_color; Color number_color; + Color function_color; + Color member_variable_color; Color selection_color; Color mark_color; Color breakpoint_color; @@ -220,6 +224,7 @@ class TextEdit : public Control { bool brace_matching_enabled; bool auto_indent; bool cut_copy_line; + bool insert_mode; uint64_t last_dblclk; @@ -263,8 +268,6 @@ class TextEdit : public Control { void _cursor_changed_emit(); void _text_changed_emit(); - void _begin_compex_operation(); - void _end_compex_operation(); void _push_current_op(); /* super internal api, undo/redo builds on it */ @@ -316,6 +319,9 @@ public: //void delete_char(); //void delete_line(); + void begin_complex_operation(); + void end_complex_operation(); + void set_text(String p_text); void insert_text_at_cursor(const String& p_text); void insert_at(const String& p_text, int at); @@ -329,6 +335,9 @@ public: void set_line(int line, String new_text); void backspace_at_cursor(); + void indent_selection_left(); + void indent_selection_right(); + inline void set_scroll_pass_end_of_file(bool p_enabled) { scroll_past_end_of_file_enabled = p_enabled; update(); @@ -389,6 +398,9 @@ public: void set_draw_tabs(bool p_draw); bool is_drawing_tabs() const; + void set_insert_mode(bool p_enabled); + bool is_insert_mode() const; + void add_keyword_color(const String& p_keyword,const Color& p_color); void add_color_region(const String& p_begin_key=String(),const String& p_end_key=String(),const Color &p_color=Color(),bool p_line_only=false); void set_symbol_color(const Color& p_color); diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index 73458e03c0..7d9bbd7f4f 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -121,6 +121,20 @@ void Timer::stop() { autostart=false; } + +void Timer::set_active(bool p_active) { + if (active == p_active) + return; + + active = p_active; + _set_process(processing); + +} + +bool Timer::is_active() const { + return active; +} + float Timer::get_time_left() const { return time_left >0 ? time_left : 0; @@ -157,9 +171,10 @@ Timer::TimerProcessMode Timer::get_timer_process_mode() const{ void Timer::_set_process(bool p_process, bool p_force) { switch (timer_process_mode) { - case TIMER_PROCESS_FIXED: set_fixed_process(p_process); break; - case TIMER_PROCESS_IDLE: set_process(p_process); break; + case TIMER_PROCESS_FIXED: set_fixed_process(p_process && active); break; + case TIMER_PROCESS_IDLE: set_process(p_process && active); break; } + processing = p_process; } void Timer::_bind_methods() { @@ -176,6 +191,9 @@ void Timer::_bind_methods() { ObjectTypeDB::bind_method(_MD("start"),&Timer::start); ObjectTypeDB::bind_method(_MD("stop"),&Timer::stop); + ObjectTypeDB::bind_method(_MD("set_active", "active"), &Timer::set_active); + ObjectTypeDB::bind_method(_MD("is_active"), &Timer::is_active); + ObjectTypeDB::bind_method(_MD("get_time_left"),&Timer::get_time_left); ObjectTypeDB::bind_method(_MD("set_timer_process_mode", "mode"), &Timer::set_timer_process_mode); @@ -198,5 +216,7 @@ Timer::Timer() { autostart=false; wait_time=1; one_shot=false; - time_left=-1; + time_left = -1; + processing = false; + active = true; } diff --git a/scene/main/timer.h b/scene/main/timer.h index 0baea76fad..688be6e4f2 100644 --- a/scene/main/timer.h +++ b/scene/main/timer.h @@ -38,6 +38,8 @@ class Timer : public Node { float wait_time; bool one_shot; bool autostart; + bool processing; + bool active; double time_left; protected: @@ -62,6 +64,8 @@ public: void start(); void stop(); + void set_active(bool p_active); + bool is_active() const; float get_time_left() const; diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 57bde00de4..f47b61001c 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -48,6 +48,7 @@ SceneStringNames::SceneStringNames() { item_rect_changed=StaticCString::create("item_rect_changed"); size_flags_changed=StaticCString::create("size_flags_changed"); minimum_size_changed=StaticCString::create("minimum_size_changed"); + sleeping_state_changed=StaticCString::create("sleeping_state_changed"); finished=StaticCString::create("finished"); animation_changed=StaticCString::create("animation_changed"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index b2c0e9abf0..fc45351c33 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -62,6 +62,7 @@ public: StringName exit_tree; StringName size_flags_changed; StringName minimum_size_changed; + StringName sleeping_state_changed; StringName idle; StringName iteration; StringName update; |