diff options
Diffstat (limited to 'scene/gui/text_edit.cpp')
-rw-r--r-- | scene/gui/text_edit.cpp | 184 |
1 files changed, 170 insertions, 14 deletions
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 4756fdee26..cabd6520b4 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -34,6 +34,7 @@ #include "globals.h" #include "message_queue.h" +#include "scene/main/viewport.h" #define TAB_PIXELS @@ -699,6 +700,7 @@ void TextEdit::_notification(int p_what) { bool prev_is_char=false; bool prev_is_number = false; bool in_keyword=false; + bool underlined=false; bool in_word = false; bool in_function_name = false; bool in_member_variable = false; @@ -824,8 +826,10 @@ void TextEdit::_notification(int p_what) { } } - if (!is_char) + if (!is_char) { in_keyword=false; + underlined=false; + } if (in_region==-1 && !in_keyword && is_char && !prev_is_char) { @@ -843,6 +847,12 @@ void TextEdit::_notification(int p_what) { in_keyword=true; keyword_color=*col; } + + if (select_identifiers_enabled && hilighted_word!=String()) { + if (hilighted_word==range) { + underlined=true; + } + } } if (!in_function_name && in_word && !in_keyword) { @@ -1023,8 +1033,12 @@ void TextEdit::_notification(int p_what) { color = cache.caret_background_color; } - if (str[j]>=32) - cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),str[j],str[j+1],in_selection?cache.font_selected_color:color); + if (str[j]>=32) { + int w = cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),str[j],str[j+1],in_selection?cache.font_selected_color:color); + if (underlined) { + draw_rect(Rect2( char_ofs+char_margin, ofs_y+ascent+2,w,1),in_selection?cache.font_selected_color:color); + } + } else if (draw_tabs && str[j]=='\t') { int yofs= (get_row_height() - cache.tab_icon->get_height())/2; @@ -1500,11 +1514,19 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } if (mb.button_index==BUTTON_LEFT) { + _reset_caret_blink_timer(); int row,col; _get_mouse_pos(Point2i(mb.x,mb.y), row,col); + if (mb.mod.command && hilighted_word!=String()) { + + emit_signal("symbol_lookup",hilighted_word,row,col); + return; + } + + // toggle breakpoint on gutter click if (draw_breakpoint_gutter) { int gutter=cache.style_normal->get_margin(MARGIN_LEFT); @@ -1629,7 +1651,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { update(); } - if (mb.button_index==BUTTON_RIGHT) { + if (mb.button_index==BUTTON_RIGHT && context_menu_enabled) { menu->set_pos(get_global_transform().xform(get_local_mouse_pos())); menu->set_size(Vector2(1,1)); @@ -1651,7 +1673,23 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { const InputEventMouseMotion &mm=p_input_event.mouse_motion; - if (mm.button_mask&BUTTON_MASK_LEFT) { + if (select_identifiers_enabled) { + if (mm.mod.command && mm.button_mask==0) { + + String new_word = get_word_at_pos(Vector2(mm.x,mm.y)); + if (new_word!=hilighted_word) { + hilighted_word=new_word; + update(); + } + } else { + if (hilighted_word!=String()) { + hilighted_word=String(); + update(); + } + } + } + + if (mm.button_mask&BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data()==Variant()) { //ignore if dragging if (selection.selecting_mode!=Selection::MODE_NONE) { @@ -1678,6 +1716,27 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { InputEventKey k=p_input_event.key; + +#ifdef OSX_ENABLED + if (k.scancode==KEY_META) { +#else + if (k.scancode==KEY_CONTROL) { + +#endif + if (select_identifiers_enabled) { + + if (k.pressed) { + + hilighted_word = get_word_at_pos(get_local_mouse_pos()); + update(); + + } else { + hilighted_word=String(); + update(); + } + } + } + if (!k.pressed) return; @@ -1845,6 +1904,8 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if (!k.mod.command) { _reset_caret_blink_timer(); } + + // save here for insert mode, just in case it is cleared in the following section bool had_selection = selection.active; @@ -2481,7 +2542,9 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } break; case KEY_X: { - + if (readonly) { + break; + } if (!k.mod.command || k.mod.shift || k.mod.alt) { scancode_handled=false; break; @@ -2513,7 +2576,9 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { undo(); } break; case KEY_V: { - + if (readonly) { + break; + } if (!k.mod.command || k.mod.shift || k.mod.alt) { scancode_handled=false; break; @@ -2558,7 +2623,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } update(); } - break;} + } break; default: { @@ -3222,6 +3287,9 @@ void TextEdit::insert_text_at_cursor(const String& p_text) { } Control::CursorShape TextEdit::get_cursor_shape(const Point2& p_pos) const { + if (hilighted_word!=String()) + return CURSOR_POINTING_HAND; + int gutter=cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w+cache.breakpoint_gutter_width; if((completion_active && completion_rect.has_point(p_pos)) || p_pos.x < gutter) { return CURSOR_ARROW; @@ -3264,6 +3332,36 @@ String TextEdit::get_text() { }; + +String TextEdit::get_text_for_lookup_completion() { + + + int row,col; + _get_mouse_pos(get_local_mouse_pos(), row,col); + + + String longthing; + int len = text.size(); + for (int i=0;i<len;i++) { + + if (i==row) { + longthing+=text[i].substr(0,col); + longthing+=String::chr(0xFFFF); //not unicode, represents the cursor + longthing+=text[i].substr(col,text[i].size()); + } else { + + longthing+=text[i]; + } + + + if (i!=len-1) + longthing+="\n"; + } + + return longthing; + +} + String TextEdit::get_text_for_completion() { String longthing; @@ -4099,12 +4197,15 @@ void TextEdit::_confirm_completion() { void TextEdit::_cancel_code_hint() { + + VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 0); completion_hint=""; update(); } void TextEdit::_cancel_completion() { + VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 0); if (!completion_active) return; @@ -4284,6 +4385,7 @@ void TextEdit::query_code_comple() { void TextEdit::set_code_hint(const String& p_hint) { + VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 1); completion_hint=p_hint; completion_hint_offset=-0xFFFF; update(); @@ -4291,7 +4393,7 @@ void TextEdit::set_code_hint(const String& p_hint) { void TextEdit::code_complete(const Vector<String> &p_strings) { - + VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 1); completion_strings=p_strings; completion_active=true; completion_current=""; @@ -4301,6 +4403,38 @@ void TextEdit::code_complete(const Vector<String> &p_strings) { } +String TextEdit::get_word_at_pos(const Vector2& p_pos) const { + + int row,col; + _get_mouse_pos(p_pos, row, col); + + String s = text[row]; + if (s.length()==0) + return ""; + int beg=CLAMP(col,0,s.length()); + int end=beg; + + + if (s[beg]>32 || beg==s.length()) { + + bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this + + while(beg>0 && s[beg-1]>32 && (symbol==_is_symbol(s[beg-1]))) { + beg--; + } + while(end<s.length() && s[end+1]>32 && (symbol==_is_symbol(s[end+1]))) { + end++; + } + + if (end<s.length()) + end+=1; + + return s.substr(beg,end-beg); + } + + return String(); +} + String TextEdit::get_tooltip(const Point2& p_pos) const { if (!tooltip_obj) @@ -4401,18 +4535,22 @@ void TextEdit::menu_option(int p_option) { switch( p_option ) { case MENU_CUT: { - - cut(); + if (!readonly) { + cut(); + } } break; case MENU_COPY: { copy(); } break; case MENU_PASTE: { - - paste(); + if (!readonly) { + paste(); + } } break; case MENU_CLEAR: { - clear(); + if (!readonly) { + clear(); + } } break; case MENU_SELECT_ALL: { select_all(); @@ -4424,6 +4562,21 @@ void TextEdit::menu_option(int p_option) { }; } + +void TextEdit::set_select_identifiers_on_hover(bool p_enable) { + + select_identifiers_enabled=p_enable; +} + +bool TextEdit::is_selecting_identifiers_on_hover_enabled() const { + + return select_identifiers_enabled; +} + +void TextEdit::set_context_menu_enabled(bool p_enable) { + context_menu_enabled = p_enable; +} + PopupMenu *TextEdit::get_menu() const { return menu; } @@ -4520,6 +4673,7 @@ void TextEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("text_changed")); ADD_SIGNAL(MethodInfo("request_completion")); ADD_SIGNAL(MethodInfo("breakpoint_toggled", PropertyInfo( Variant::INT, "row"))); + ADD_SIGNAL(MethodInfo("symbol_lookup", PropertyInfo(Variant::STRING,"symbol"),PropertyInfo( Variant::INT, "row"),PropertyInfo( Variant::INT, "column"))); BIND_CONSTANT( MENU_CUT ); BIND_CONSTANT( MENU_COPY ); @@ -4640,7 +4794,9 @@ TextEdit::TextEdit() { auto_indent=false; insert_mode = false; window_has_focus=true; + select_identifiers_enabled=false; + context_menu_enabled=true; menu = memnew( PopupMenu ); add_child(menu); menu->add_item(TTR("Cut"),MENU_CUT,KEY_MASK_CMD|KEY_X); |