diff options
Diffstat (limited to 'scene/gui')
-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 |
7 files changed, 216 insertions, 79 deletions
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); |