summaryrefslogtreecommitdiff
path: root/scene/gui/text_edit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/text_edit.cpp')
-rw-r--r--scene/gui/text_edit.cpp292
1 files changed, 222 insertions, 70 deletions
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index be6c0d0a8b..70da7e39a4 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,6 +29,7 @@
#include "text_edit.h"
#include "os/keyboard.h"
+#include "os/input.h"
#include "os/os.h"
#include "globals.h"
@@ -349,6 +350,29 @@ void TextEdit::_update_scrollbars() {
updating_scrolls=false;
}
+void TextEdit::_click_selection_held() {
+
+ if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode!=Selection::MODE_NONE) {
+
+ Point2 mp = Input::get_singleton()->get_mouse_pos()-get_global_pos();
+
+ int row,col;
+ _get_mouse_pos(Point2i(mp.x,mp.y), row,col);
+
+ select(selection.selecting_line,selection.selecting_column,row,col);
+
+ cursor_set_line( row );
+ cursor_set_column( col );
+ update();
+
+ click_select_held->start();
+
+ } else {
+
+ click_select_held->stop();
+ }
+}
+
void TextEdit::_notification(int p_what) {
@@ -1094,16 +1118,16 @@ void TextEdit::backspace_at_cursor() {
}
-bool TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const {
-
- int row=p_mouse.y;
- row-=cache.style_normal->get_margin(MARGIN_TOP);
- row/=get_row_height();
+void TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const {
- if (row<0 || row>=get_visible_rows())
- return false;
-
- row+=cursor.line_ofs;
+ float rows=p_mouse.y;
+ rows-=cache.style_normal->get_margin(MARGIN_TOP);
+ rows/=get_row_height();
+ int row=cursor.line_ofs+rows;
+
+ if (row<0)
+ row=0;
+
int col=0;
if (row>=text.size()) {
@@ -1119,7 +1143,6 @@ bool TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) co
r_row=row;
r_col=col;
- return true;
}
void TextEdit::_input_event(const InputEvent& p_input_event) {
@@ -1177,8 +1200,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (mb.button_index==BUTTON_LEFT) {
int row,col;
- if (!_get_mouse_pos(Point2i(mb.x,mb.y), row,col))
- return;
+ _get_mouse_pos(Point2i(mb.x,mb.y), row,col);
int prev_col=cursor.column;
int prev_line=cursor.line;
@@ -1210,27 +1232,30 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
update();
} else {
- if (cursor.line<selection.from_line || (cursor.line==selection.from_line && cursor.column<=selection.from_column)) {
- selection.from_column=cursor.column;
- selection.from_line=cursor.line;
- } else if (cursor.line>selection.to_line || (cursor.line==selection.to_line && cursor.column>=selection.to_column)) {
- selection.to_column=cursor.column;
- selection.to_line=cursor.line;
-
- } else if (!selection.shiftclick_left) {
+ if (cursor.line<selection.selecting_line || (cursor.line==selection.selecting_line && cursor.column<selection.selecting_column)) {
+ if (selection.shiftclick_left) {
+ SWAP(selection.from_column,selection.to_column);
+ SWAP(selection.from_line,selection.to_line);
+ selection.shiftclick_left = !selection.shiftclick_left;
+ }
selection.from_column=cursor.column;
selection.from_line=cursor.line;
- } else {
+ } else if (cursor.line>selection.selecting_line || (cursor.line==selection.selecting_line && cursor.column>selection.selecting_column)) {
+
+ if (!selection.shiftclick_left) {
+ SWAP(selection.from_column,selection.to_column);
+ SWAP(selection.from_line,selection.to_line);
+ selection.shiftclick_left = !selection.shiftclick_left;
+ }
selection.to_column=cursor.column;
selection.to_line=cursor.line;
- }
- if (selection.from_line>selection.to_line || (selection.from_line==selection.to_line && selection.from_column>selection.to_column)) {
- SWAP(selection.from_column,selection.to_column);
- SWAP(selection.from_line,selection.to_line);
+ } else {
+ selection.active=false;
}
+
update();
}
@@ -1255,6 +1280,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (!mb.doubleclick && (OS::get_singleton()->get_ticks_msec()-last_dblclk)<600 && cursor.line==prev_line) {
//tripleclick select line
select(cursor.line,0,cursor.line,text[cursor.line].length());
+ selection.selecting_column=0;
last_dblclk=0;
} else if (mb.doubleclick && text[cursor.line].length()) {
@@ -1279,6 +1305,8 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
end+=1;
select(cursor.line,beg,cursor.line,end);
+
+ selection.selecting_column=beg;
}
last_dblclk = OS::get_singleton()->get_ticks_msec();
@@ -1288,8 +1316,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
update();
}
} else {
+
+ if (mb.button_index==BUTTON_LEFT)
+ click_select_held->stop();
- selection.selecting_mode=Selection::MODE_NONE;
// notify to show soft keyboard
notification(NOTIFICATION_FOCUS_ENTER);
}
@@ -1301,17 +1331,18 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (mm.button_mask&BUTTON_MASK_LEFT) {
- int row,col;
- if (!_get_mouse_pos(Point2i(mm.x,mm.y), row,col))
- return;
-
- if (selection.selecting_mode==Selection::MODE_POINTER) {
+ if (selection.selecting_mode!=Selection::MODE_NONE) {
+
+ int row,col;
+ _get_mouse_pos(Point2i(mm.x,mm.y), row,col);
select(selection.selecting_line,selection.selecting_column,row,col);
cursor_set_line( row );
cursor_set_column( col );
update();
+
+ click_select_held->start();
}
@@ -1585,7 +1616,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
break;
}
- selection.selecting_test=false;
+ selection.selecting_text=false;
bool scancode_handled=true;
@@ -1608,6 +1639,13 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
else
break;
}
+ if(auto_indent){
+ // indent once again if previous line will end with ':'
+ // (i.e. colon precedes current cursor position)
+ if(cursor.column>0 && text[cursor.line][cursor.column-1]==':') {
+ ins+="\t";
+ }
+ }
_insert_text_at_cursor(ins);
_push_current_op();
@@ -1647,8 +1685,60 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
case KEY_BACKSPACE: {
if (readonly)
break;
- backspace_at_cursor();
-
+
+#ifdef APPLE_STYLE_KEYS
+ if (k.mod.alt) {
+#else
+ if (k.mod.alt) {
+ scancode_handled=false;
+ break;
+ } else if (k.mod.command) {
+#endif
+ int line=cursor.line;
+ int column=cursor.column;
+
+ bool prev_char=false;
+ bool only_whitespace=true;
+
+ while (only_whitespace && line > 0) {
+
+ while (column>0) {
+ CharType c=text[line][column-1];
+
+ if (c != '\t' && c != ' ') {
+ only_whitespace=false;
+ break;
+ }
+
+ column--;
+ }
+
+ if (only_whitespace) {
+ line--;
+ column=text[line].length();
+ }
+ }
+
+ while (column>0) {
+ bool ischar=_is_text_char(text[line][column-1]);
+
+ if (prev_char && !ischar)
+ break;
+
+ prev_char=ischar;
+ column--;
+
+ }
+
+ _remove_text(line, column, cursor.line, cursor.column);
+
+ cursor_set_line(line);
+ cursor_set_column(column);
+
+ } else {
+ backspace_at_cursor();
+ }
+
} break;
case KEY_LEFT: {
@@ -1789,10 +1879,63 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (cursor.line==text.size()-1 && cursor.column==curline_len)
break; //nothing to do
- int next_line = cursor.column<curline_len?cursor.line:cursor.line+1;
- int next_column = cursor.column<curline_len?(cursor.column+1):0;
+ int next_line=cursor.column<curline_len?cursor.line:cursor.line+1;
+ int next_column;
+
+#ifdef APPLE_STYLE_KEYS
+ if (k.mod.alt) {
+#else
+ if (k.mod.alt) {
+ scancode_handled=false;
+ break;
+ } else if (k.mod.command) {
+#endif
+ int last_line=text.size()-1;
+
+ int line=cursor.line;
+ int column=cursor.column;
+
+ bool prev_char=false;
+ bool only_whitespace=true;
+
+ while (only_whitespace && line < last_line) {
+
+ while (column<text[line].length()) {
+ CharType c=text[line][column];
+
+ if (c != '\t' && c != ' ') {
+ only_whitespace=false;
+ break;
+ }
+
+ column++;
+ }
+
+ if (only_whitespace) {
+ line++;
+ column=0;
+ }
+ }
+
+ while (column<text[line].length()) {
+
+ bool ischar=_is_text_char(text[line][column]);
+
+ if (prev_char && !ischar)
+ break;
+ prev_char=ischar;
+ column++;
+ }
+
+ next_line=line;
+ next_column=column;
+ } else {
+ next_column=cursor.column<curline_len?(cursor.column+1):0;
+ }
+
_remove_text(cursor.line,cursor.column,next_line,next_column);
update();
+
} break;
#ifdef APPLE_STYLE_KEYS
case KEY_HOME: {
@@ -1903,15 +2046,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
break;
}
- if (text.size()==1 && text[0].length()==0)
- break;
- selection.active=true;
- selection.from_line=0;
- selection.from_column=0;
- selection.to_line=text.size()-1;
- selection.to_column=text[selection.to_line].length();
- selection.selecting_mode=Selection::MODE_NONE;
- update();
+ select_all();
} break;
case KEY_X: {
@@ -2096,12 +2231,6 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
}
}
-
- if (!selection.selecting_test) {
-
- selection.selecting_mode=Selection::MODE_NONE;
- }
-
return;
} break;
@@ -2113,13 +2242,14 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
void TextEdit::_pre_shift_selection() {
- if (!selection.active || selection.selecting_mode!=Selection::MODE_SHIFT) {
+ if (!selection.active || selection.selecting_mode==Selection::MODE_NONE) {
selection.selecting_line=cursor.line;
selection.selecting_column=cursor.column;
selection.active=true;
- selection.selecting_mode=Selection::MODE_SHIFT;
}
+
+ selection.selecting_mode=Selection::MODE_SHIFT;
}
void TextEdit::_post_shift_selection() {
@@ -2132,7 +2262,7 @@ void TextEdit::_post_shift_selection() {
}
- selection.selecting_test=true;
+ selection.selecting_text=true;
}
/**** TEXT EDIT CORE API ****/
@@ -2428,7 +2558,7 @@ void TextEdit::adjust_viewport_to_cursor() {
}
-void TextEdit::cursor_set_column(int p_col) {
+void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) {
if (p_col<0)
p_col=0;
@@ -2439,7 +2569,8 @@ void TextEdit::cursor_set_column(int p_col) {
cursor.last_fit_x=get_column_x_offset(cursor.column,get_line(cursor.line));
- adjust_viewport_to_cursor();
+ if (p_adjust_viewport)
+ adjust_viewport_to_cursor();
if (!cursor_changed_dirty) {
if (is_inside_tree())
@@ -2450,7 +2581,7 @@ void TextEdit::cursor_set_column(int p_col) {
}
-void TextEdit::cursor_set_line(int p_row) {
+void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport) {
if (setting_row)
return;
@@ -2466,8 +2597,8 @@ void TextEdit::cursor_set_line(int p_row) {
cursor.line=p_row;
cursor.column=get_char_pos_for( cursor.last_fit_x, get_line( cursor.line) );
-
- adjust_viewport_to_cursor();
+ if (p_adjust_viewport)
+ adjust_viewport_to_cursor();
setting_row=false;
@@ -2774,6 +2905,10 @@ bool TextEdit::is_syntax_coloring_enabled() const {
return syntax_coloring;
}
+void TextEdit::set_auto_indent(bool p_auto_indent) {
+ auto_indent = p_auto_indent;
+}
+
void TextEdit::cut() {
if (!selection.active)
@@ -2832,9 +2967,14 @@ void TextEdit::select_all() {
selection.active=true;
selection.from_line=0;
selection.from_column=0;
+ selection.selecting_line=0;
+ selection.selecting_column=0;
selection.to_line=text.size()-1;
selection.to_column=text[selection.to_line].length();
- selection.selecting_mode=Selection::MODE_NONE;
+ selection.selecting_mode=Selection::MODE_SHIFT;
+ selection.shiftclick_left=true;
+ cursor_set_line( selection.to_line, false );
+ cursor_set_column( selection.to_column, false );
update();
}
@@ -2873,12 +3013,20 @@ void TextEdit::select(int p_from_line,int p_from_column,int p_to_line,int p_to_c
} else if (selection.from_column>selection.to_column) {
+ selection.shiftclick_left = false;
SWAP( selection.from_column, selection.to_column );
+ } else {
+
+ selection.shiftclick_left = true;
}
} else if (selection.from_line>selection.to_line) {
+ selection.shiftclick_left = false;
SWAP( selection.from_line, selection.to_line );
SWAP( selection.from_column, selection.to_column );
+ } else {
+
+ selection.shiftclick_left = true;
}
@@ -3502,10 +3650,8 @@ String TextEdit::get_tooltip(const Point2& p_pos) const {
if (!tooltip_obj)
return Control::get_tooltip(p_pos);
int row,col;
- if (!_get_mouse_pos(p_pos, row,col)) {
- return Control::get_tooltip(p_pos);
- }
-
+ _get_mouse_pos(p_pos, row, col);
+
String s = text[row];
if (s.length()==0)
return Control::get_tooltip(p_pos);
@@ -3580,6 +3726,7 @@ void TextEdit::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_cursor_changed_emit"),&TextEdit::_cursor_changed_emit);
ObjectTypeDB::bind_method(_MD("_text_changed_emit"),&TextEdit::_text_changed_emit);
ObjectTypeDB::bind_method(_MD("_push_current_op"),&TextEdit::_push_current_op);
+ ObjectTypeDB::bind_method(_MD("_click_selection_held"),&TextEdit::_click_selection_held);
BIND_CONSTANT( SEARCH_MATCH_CASE );
BIND_CONSTANT( SEARCH_WHOLE_WORDS );
@@ -3595,10 +3742,10 @@ void TextEdit::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_line_count"),&TextEdit::get_line_count);
ObjectTypeDB::bind_method(_MD("get_text"),&TextEdit::get_text);
- ObjectTypeDB::bind_method(_MD("get_line"),&TextEdit::get_line);
+ ObjectTypeDB::bind_method(_MD("get_line","line"),&TextEdit::get_line);
- ObjectTypeDB::bind_method(_MD("cursor_set_column","column"),&TextEdit::cursor_set_column);
- ObjectTypeDB::bind_method(_MD("cursor_set_line","line"),&TextEdit::cursor_set_line);
+ ObjectTypeDB::bind_method(_MD("cursor_set_column","column","adjust_viewport"),&TextEdit::cursor_set_column,DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("cursor_set_line","line","adjust_viewport"),&TextEdit::cursor_set_line,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("cursor_get_column"),&TextEdit::cursor_get_column);
ObjectTypeDB::bind_method(_MD("cursor_get_line"),&TextEdit::cursor_get_line);
@@ -3684,7 +3831,7 @@ TextEdit::TextEdit() {
selection.selecting_mode=Selection::MODE_NONE;
selection.selecting_line=0;
selection.selecting_column=0;
- selection.selecting_test=false;
+ selection.selecting_text=false;
selection.active=false;
syntax_coloring=false;
@@ -3694,6 +3841,11 @@ TextEdit::TextEdit() {
idle_detect->set_one_shot(true);
idle_detect->set_wait_time(GLOBAL_DEF("display/text_edit_idle_detect_sec",3));
idle_detect->connect("timeout", this,"_push_current_op");
+
+ click_select_held = memnew( Timer );
+ add_child(click_select_held);
+ click_select_held->set_wait_time(0.05);
+ click_select_held->connect("timeout", this,"_click_selection_held");
#if 0
syntax_coloring=true;
@@ -3730,7 +3882,7 @@ TextEdit::TextEdit() {
next_operation_is_complex=false;
auto_brace_completion_enabled=false;
brace_matching_enabled=false;
-
+ auto_indent=false;
}
TextEdit::~TextEdit()