Merge pull request #4812 from neikeq/pr-search-bar
ScriptEditor/ShaderEditor: Replace find/replace dialog with a bar
This commit is contained in:
commit
6a7530c718
9 changed files with 640 additions and 55 deletions
|
@ -682,9 +682,13 @@ void TextEdit::_notification(int p_what) {
|
|||
|
||||
// check if line contains highlighted word
|
||||
int highlighted_text_col = -1;
|
||||
if (highlighted_text.length() != 0) {
|
||||
highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, 0);
|
||||
}
|
||||
int search_text_col = -1;
|
||||
|
||||
if (!search_text.empty())
|
||||
search_text_col = _get_column_pos_of_word(search_text, str, search_flags, 0);
|
||||
|
||||
if (highlighted_text.length() != 0 && highlighted_text != search_text)
|
||||
highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE|SEARCH_WHOLE_WORDS, 0);
|
||||
|
||||
if (cache.line_number_w) {
|
||||
String fc = String::num(line+1);
|
||||
|
@ -879,20 +883,45 @@ void TextEdit::_notification(int p_what) {
|
|||
break;
|
||||
}
|
||||
|
||||
bool in_selection = (selection.active && line>=selection.from_line && line<=selection.to_line && (line>selection.from_line || j>=selection.from_column) && (line<selection.to_line || j<selection.to_column));
|
||||
bool in_search_result=false;
|
||||
|
||||
if (search_text_col != -1) {
|
||||
// if we are at the end check for new search result on same line
|
||||
if (j >= search_text_col+search_text.length())
|
||||
search_text_col = _get_column_pos_of_word(search_text, str, search_flags, j);
|
||||
|
||||
in_search_result = j >= search_text_col && j < search_text_col+search_text.length();
|
||||
|
||||
if (in_search_result) {
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(char_w, get_row_height())),cache.search_result_color);
|
||||
}
|
||||
}
|
||||
|
||||
bool in_selection = (selection.active && line>=selection.from_line && line<=selection.to_line && (line>selection.from_line || j>=selection.from_column) && (line<selection.to_line || j<selection.to_column));
|
||||
|
||||
if (in_selection) {
|
||||
//inside selection!
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(char_w,get_row_height())),cache.selection_color);
|
||||
}
|
||||
|
||||
if (in_search_result) {
|
||||
Color border_color=(line==search_result_line && j>=search_result_col && j<search_result_col+search_text.length())?cache.font_color:cache.search_result_border_color;
|
||||
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(char_w,1)),border_color);
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y+get_row_height()-1 ), Size2i(char_w,1)),border_color);
|
||||
|
||||
if (j==search_text_col)
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(1,get_row_height())),border_color);
|
||||
if (j==search_text_col+search_text.length()-1)
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin+char_w-1, ofs_y ), Size2i(1,get_row_height())),border_color);
|
||||
}
|
||||
|
||||
if (highlight_all_occurrences) {
|
||||
if (highlighted_text_col != -1) {
|
||||
|
||||
// if we are at the end check for new word on same line
|
||||
if (j > highlighted_text_col+highlighted_text.length()) {
|
||||
highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, j);
|
||||
highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE|SEARCH_WHOLE_WORDS, j);
|
||||
}
|
||||
|
||||
bool in_highlighted_word = (j >= highlighted_text_col && j < highlighted_text_col+highlighted_text.length());
|
||||
|
@ -1892,7 +1921,8 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
|
|||
if (completion_hint!="") {
|
||||
completion_hint="";
|
||||
update();
|
||||
|
||||
} else {
|
||||
scancode_handled=false;
|
||||
}
|
||||
} break;
|
||||
case KEY_TAB: {
|
||||
|
@ -3220,6 +3250,8 @@ void TextEdit::_update_caches() {
|
|||
cache.breakpoint_color=get_color("breakpoint_color");
|
||||
cache.brace_mismatch_color=get_color("brace_mismatch_color");
|
||||
cache.word_highlighted_color=get_color("word_highlighted_color");
|
||||
cache.search_result_color=get_color("search_result_color");
|
||||
cache.search_result_border_color=get_color("search_result_border_color");
|
||||
cache.line_spacing=get_constant("line_spacing");
|
||||
cache.row_height = cache.font->get_height() + cache.line_spacing;
|
||||
cache.tab_icon=get_icon("tab");
|
||||
|
@ -3481,12 +3513,25 @@ String TextEdit::get_word_under_cursor() const {
|
|||
return text[cursor.line].substr(prev_cc, next_cc-prev_cc);
|
||||
}
|
||||
|
||||
void TextEdit::set_search_text(const String &p_search_text) {
|
||||
search_text = p_search_text;
|
||||
}
|
||||
|
||||
void TextEdit::set_search_flags(uint32_t p_flags) {
|
||||
search_flags = p_flags;
|
||||
}
|
||||
|
||||
void TextEdit::set_current_search_result(int line, int col) {
|
||||
search_result_line = line;
|
||||
search_result_col = col;
|
||||
}
|
||||
|
||||
void TextEdit::set_highlight_all_occurrences(const bool p_enabled) {
|
||||
highlight_all_occurrences = p_enabled;
|
||||
update();
|
||||
}
|
||||
|
||||
int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_search, int p_from_column) {
|
||||
int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_search, uint32_t p_search_flags, int p_from_column) {
|
||||
int col = -1;
|
||||
|
||||
if (p_key.length() > 0 && p_search.length() > 0) {
|
||||
|
@ -3494,12 +3539,15 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc
|
|||
p_from_column = 0;
|
||||
}
|
||||
|
||||
while (col == -1 && p_from_column <= p_search.length()) {
|
||||
// match case
|
||||
col = p_search.findn(p_key, p_from_column);
|
||||
while (col == -1 && p_from_column <= p_search.length()) {
|
||||
if (p_search_flags&SEARCH_MATCH_CASE) {
|
||||
col = p_search.find(p_key,p_from_column);
|
||||
} else {
|
||||
col = p_search.findn(p_key,p_from_column);
|
||||
}
|
||||
|
||||
// whole words only
|
||||
if (col != -1) {
|
||||
if (col != -1 && p_search_flags&SEARCH_WHOLE_WORDS) {
|
||||
p_from_column=col;
|
||||
|
||||
if (col > 0 && _is_text_char(p_search[col-1])) {
|
||||
|
@ -3565,10 +3613,8 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
|
|||
//wrapped
|
||||
|
||||
if (p_search_flags&SEARCH_BACKWARDS) {
|
||||
text_line=text_line.substr(from_column,text_line.length());
|
||||
from_column=text_line.length();
|
||||
} else {
|
||||
text_line=text_line.substr(0,from_column);
|
||||
from_column=0;
|
||||
}
|
||||
|
||||
|
@ -3579,7 +3625,6 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
|
|||
|
||||
|
||||
} else {
|
||||
//text_line=text_line.substr(0,p_from_column); //wrap around for missing begining.
|
||||
if (p_search_flags&SEARCH_BACKWARDS)
|
||||
from_column=text_line.length()-1;
|
||||
else
|
||||
|
@ -3588,12 +3633,25 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
|
|||
|
||||
pos=-1;
|
||||
|
||||
if (!(p_search_flags&SEARCH_BACKWARDS)) {
|
||||
int pos_from=0;
|
||||
int last_pos=-1;
|
||||
while ((last_pos=(p_search_flags&SEARCH_MATCH_CASE)?text_line.find(p_key,pos_from):text_line.findn(p_key,pos_from))!=-1) {
|
||||
|
||||
pos = (p_search_flags&SEARCH_MATCH_CASE)?text_line.find(p_key,from_column):text_line.findn(p_key,from_column);
|
||||
} else {
|
||||
if (p_search_flags&SEARCH_BACKWARDS) {
|
||||
|
||||
pos = (p_search_flags&SEARCH_MATCH_CASE)?text_line.rfind(p_key,from_column):text_line.rfindn(p_key,from_column);
|
||||
if (last_pos>from_column)
|
||||
break;
|
||||
pos=last_pos;
|
||||
|
||||
} else {
|
||||
|
||||
if (last_pos>=from_column) {
|
||||
pos=last_pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pos_from=last_pos+p_key.length();
|
||||
}
|
||||
|
||||
if (pos!=-1 && (p_search_flags&SEARCH_WHOLE_WORDS)) {
|
||||
|
|
|
@ -88,6 +88,8 @@ class TextEdit : public Control {
|
|||
Color current_line_color;
|
||||
Color brace_mismatch_color;
|
||||
Color word_highlighted_color;
|
||||
Color search_result_color;
|
||||
Color search_result_border_color;
|
||||
|
||||
int row_height;
|
||||
int line_spacing;
|
||||
|
@ -249,6 +251,11 @@ class TextEdit : public Control {
|
|||
bool callhint_below;
|
||||
Vector2 callhint_offset;
|
||||
|
||||
String search_text;
|
||||
uint32_t search_flags;
|
||||
int search_result_line;
|
||||
int search_result_col;
|
||||
|
||||
int get_visible_rows() const;
|
||||
|
||||
int get_char_count();
|
||||
|
@ -287,7 +294,7 @@ class TextEdit : public Control {
|
|||
String _base_get_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column) const;
|
||||
void _base_remove_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column);
|
||||
|
||||
int _get_column_pos_of_word(const String &p_key, const String &p_search, int p_from_column);
|
||||
int _get_column_pos_of_word(const String &p_key, const String &p_search, uint32_t p_search_flags, int p_from_column);
|
||||
|
||||
DVector<int> _search_bind(const String &p_key,uint32_t p_search_flags, int p_from_line,int p_from_column) const;
|
||||
|
||||
|
@ -408,6 +415,10 @@ public:
|
|||
void select(int p_from_line,int p_from_column,int p_to_line,int p_to_column);
|
||||
void deselect();
|
||||
|
||||
void set_search_text(const String& p_search_text);
|
||||
void set_search_flags(uint32_t p_flags);
|
||||
void set_current_search_result(int line, int col);
|
||||
|
||||
void set_highlight_all_occurrences(const bool p_enabled);
|
||||
bool is_selection_active() const;
|
||||
int get_selection_from_line() const;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "editor_settings.h"
|
||||
#include "scene/gui/margin_container.h"
|
||||
#include "scene/gui/separator.h"
|
||||
#include "os/keyboard.h"
|
||||
|
||||
void GotoLineDialog::popup_find_line(TextEdit *p_edit) {
|
||||
|
||||
|
@ -76,6 +77,436 @@ GotoLineDialog::GotoLineDialog() {
|
|||
}
|
||||
|
||||
|
||||
void FindReplaceBar::_notification(int p_what) {
|
||||
|
||||
if (p_what == NOTIFICATION_READY) {
|
||||
|
||||
find_prev->set_icon(get_icon("MoveUp", "EditorIcons"));
|
||||
find_next->set_icon(get_icon("MoveDown", "EditorIcons"));
|
||||
hide_button->set_normal_texture(get_icon("Close","EditorIcons"));
|
||||
hide_button->set_hover_texture(get_icon("CloseHover","EditorIcons"));
|
||||
hide_button->set_pressed_texture(get_icon("Close","EditorIcons"));
|
||||
|
||||
} else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
|
||||
|
||||
set_process_unhandled_input(is_visible());
|
||||
}
|
||||
}
|
||||
|
||||
void FindReplaceBar::_unhandled_input(const InputEvent &p_event) {
|
||||
|
||||
if (p_event.type == InputEvent::KEY) {
|
||||
|
||||
const InputEventKey& k = p_event.key;
|
||||
|
||||
if (k.pressed && (text_edit->has_focus() || text_vbc->is_a_parent_of(get_focus_owner()))) {
|
||||
|
||||
bool accepted = true;
|
||||
|
||||
switch (k.scancode) {
|
||||
|
||||
case KEY_ESCAPE: {
|
||||
|
||||
_hide_bar();
|
||||
} break;
|
||||
default: {
|
||||
|
||||
accepted = false;
|
||||
} break;
|
||||
}
|
||||
|
||||
if (accepted) {
|
||||
accept_event();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FindReplaceBar::_search(bool p_include_current, bool p_backwards) {
|
||||
|
||||
String text=get_search_text();
|
||||
uint32_t flags=0;
|
||||
|
||||
if (is_whole_words())
|
||||
flags|=TextEdit::SEARCH_WHOLE_WORDS;
|
||||
if (is_case_sensitive())
|
||||
flags|=TextEdit::SEARCH_MATCH_CASE;
|
||||
if (p_backwards)
|
||||
flags|=TextEdit::SEARCH_BACKWARDS;
|
||||
|
||||
int line=text_edit->cursor_get_line();
|
||||
int col=text_edit->cursor_get_column();
|
||||
|
||||
if (text_edit->is_selection_active() && !replace_all_mode) {
|
||||
line = text_edit->get_selection_from_line();
|
||||
col = text_edit->get_selection_from_column();
|
||||
}
|
||||
|
||||
bool cursor_at_result=false;
|
||||
|
||||
if (line==current_result_line && col>=current_result_col && col<=current_result_col+text.length()) {
|
||||
col=current_result_col;
|
||||
cursor_at_result=true;
|
||||
}
|
||||
|
||||
if (!p_include_current) {
|
||||
if (p_backwards) {
|
||||
col-=text.length();
|
||||
if (col<0) {
|
||||
line-=1;
|
||||
if (line<0)
|
||||
line=text_edit->get_line_count()-1;
|
||||
col=text_edit->get_line(line).length();
|
||||
}
|
||||
} else if (cursor_at_result) {
|
||||
col+=text.length();
|
||||
if (col>text_edit->get_line(line).length()) {
|
||||
line+=1;
|
||||
if (line>=text_edit->get_line_count())
|
||||
line=0;
|
||||
col=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool found = text_edit->search(text,flags,line,col,line,col);
|
||||
|
||||
if (!found) {
|
||||
if (p_backwards) {
|
||||
line = text_edit->get_line_count()-1;
|
||||
col = text_edit->get_line(line).length()-1;
|
||||
} else {
|
||||
line = 0;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
found = text_edit->search(text,flags,line,col,line,col);
|
||||
}
|
||||
|
||||
if (found) {
|
||||
text_edit->cursor_set_line(line);
|
||||
text_edit->cursor_set_column(p_backwards?col:col+text.length());
|
||||
text_edit->select(line,col,line,col+text.length());
|
||||
text_edit->set_search_text(text);
|
||||
text_edit->set_search_flags(flags);
|
||||
text_edit->set_current_search_result(line,col);
|
||||
|
||||
current_result_line = line;
|
||||
current_result_col = col;
|
||||
|
||||
set_error("");
|
||||
} else {
|
||||
current_result_line = -1;
|
||||
current_result_col = -1;
|
||||
text_edit->set_search_text("");
|
||||
set_error(text.empty()?"":TTR("No Matches"));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
void FindReplaceBar::_replace() {
|
||||
|
||||
if (text_edit->get_selection_text()==get_search_text()) {
|
||||
text_edit->insert_text_at_cursor(get_replace_text());
|
||||
}
|
||||
|
||||
search_current();
|
||||
}
|
||||
|
||||
void FindReplaceBar::_replace_all() {
|
||||
|
||||
// line as x so it gets priority in comparison, column as y
|
||||
Point2i orig_cursor(text_edit->cursor_get_line(),text_edit->cursor_get_column());
|
||||
Point2i prev_match=Point2(-1,-1);
|
||||
|
||||
bool selection_enabled = text_edit->is_selection_active();
|
||||
Point2i selection_begin,selection_end;
|
||||
if (selection_enabled) {
|
||||
selection_begin=Point2i(text_edit->get_selection_from_line(),text_edit->get_selection_from_column());
|
||||
selection_end=Point2i(text_edit->get_selection_to_line(),text_edit->get_selection_to_column());
|
||||
}
|
||||
|
||||
int vsval = text_edit->get_v_scroll();
|
||||
|
||||
text_edit->cursor_set_line(0);
|
||||
text_edit->cursor_set_column(0);
|
||||
|
||||
int rc=0;
|
||||
|
||||
replace_all_mode = true;
|
||||
|
||||
text_edit->begin_complex_operation();
|
||||
|
||||
while(_search(false)) {
|
||||
|
||||
if (!text_edit->is_selection_active()) {
|
||||
// search selects
|
||||
break;
|
||||
}
|
||||
|
||||
// replace area
|
||||
Point2i match_from(text_edit->get_selection_from_line(),text_edit->get_selection_from_column());
|
||||
Point2i match_to(text_edit->get_selection_to_line(),text_edit->get_selection_to_column());
|
||||
|
||||
if (match_from < prev_match)
|
||||
break; // done
|
||||
|
||||
prev_match=match_to;
|
||||
|
||||
if (selection_enabled && is_selection_only()) {
|
||||
|
||||
if (match_from<selection_begin || match_to>selection_end)
|
||||
continue;
|
||||
|
||||
// replace but adjust selection bounds
|
||||
text_edit->insert_text_at_cursor(get_replace_text());
|
||||
if (match_to.x==selection_end.x)
|
||||
selection_end.y+=get_replace_text().length() - get_search_text().length();
|
||||
} else {
|
||||
//just replace
|
||||
text_edit->insert_text_at_cursor(get_replace_text());
|
||||
}
|
||||
|
||||
rc++;
|
||||
}
|
||||
|
||||
text_edit->end_complex_operation();
|
||||
|
||||
replace_all_mode = false;
|
||||
|
||||
// restore editor state (selection, cursor, scroll)
|
||||
text_edit->cursor_set_line(orig_cursor.x);
|
||||
text_edit->cursor_set_column(orig_cursor.y);
|
||||
|
||||
if (selection_enabled && is_selection_only()) {
|
||||
// reselect
|
||||
text_edit->select(selection_begin.x,selection_begin.y,selection_end.x,selection_end.y);
|
||||
} else {
|
||||
text_edit->deselect();
|
||||
}
|
||||
|
||||
text_edit->set_v_scroll(vsval);
|
||||
set_error(vformat(TTR("Replaced %d Ocurrence(s)."), rc));
|
||||
}
|
||||
|
||||
void FindReplaceBar::search_current() {
|
||||
|
||||
_search(true);
|
||||
}
|
||||
|
||||
void FindReplaceBar::search_prev() {
|
||||
|
||||
_search(false, true);
|
||||
}
|
||||
|
||||
void FindReplaceBar::search_next() {
|
||||
|
||||
_search();
|
||||
}
|
||||
|
||||
void FindReplaceBar::_hide_bar() {
|
||||
|
||||
text_edit->set_search_text("");
|
||||
current_result_line = -1;
|
||||
current_result_col = -1;
|
||||
replace_hbc->hide();
|
||||
replace_options_hbc->hide();
|
||||
hide();
|
||||
}
|
||||
|
||||
void FindReplaceBar::_show_search() {
|
||||
|
||||
show();
|
||||
search_text->grab_focus();
|
||||
|
||||
if (text_edit->is_selection_active()) {
|
||||
search_text->set_text(text_edit->get_selection_text());
|
||||
}
|
||||
|
||||
if (!get_search_text().empty()) {
|
||||
search_text->select_all();
|
||||
search_text->set_cursor_pos(search_text->get_text().length());
|
||||
search_current();
|
||||
}
|
||||
}
|
||||
|
||||
void FindReplaceBar::popup_search() {
|
||||
|
||||
replace_hbc->hide();
|
||||
replace_options_hbc->hide();
|
||||
_show_search();
|
||||
}
|
||||
|
||||
void FindReplaceBar::popup_replace() {
|
||||
|
||||
if (!replace_hbc->is_visible() || !replace_options_hbc->is_visible()) {
|
||||
replace_text->clear();
|
||||
replace_hbc->show();
|
||||
replace_options_hbc->show();
|
||||
}
|
||||
|
||||
_show_search();
|
||||
}
|
||||
|
||||
void FindReplaceBar::_search_options_changed(bool p_pressed) {
|
||||
|
||||
search_current();
|
||||
}
|
||||
|
||||
void FindReplaceBar::_search_text_changed(const String& p_text) {
|
||||
|
||||
search_current();
|
||||
}
|
||||
|
||||
void FindReplaceBar::_search_text_entered(const String& p_text) {
|
||||
|
||||
search_next();
|
||||
}
|
||||
|
||||
String FindReplaceBar::get_search_text() const {
|
||||
|
||||
return search_text->get_text();
|
||||
}
|
||||
|
||||
String FindReplaceBar::get_replace_text() const {
|
||||
|
||||
return replace_text->get_text();
|
||||
}
|
||||
|
||||
bool FindReplaceBar::is_case_sensitive() const {
|
||||
|
||||
return case_sensitive->is_pressed();
|
||||
}
|
||||
|
||||
bool FindReplaceBar::is_whole_words() const {
|
||||
|
||||
return whole_words->is_pressed();
|
||||
}
|
||||
|
||||
bool FindReplaceBar::is_selection_only() const {
|
||||
|
||||
return selection_only->is_pressed();
|
||||
}
|
||||
|
||||
void FindReplaceBar::set_error(const String &p_label) {
|
||||
|
||||
error_label->set_text(p_label);
|
||||
}
|
||||
|
||||
void FindReplaceBar::set_text_edit(TextEdit *p_text_edit) {
|
||||
|
||||
text_edit = p_text_edit;
|
||||
text_edit->connect("_text_changed",this,"_search_text_changed",varray(String()));
|
||||
}
|
||||
|
||||
void FindReplaceBar::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method("_unhandled_input",&FindReplaceBar::_unhandled_input);
|
||||
|
||||
ObjectTypeDB::bind_method("_search_text_changed",&FindReplaceBar::_search_text_changed);
|
||||
ObjectTypeDB::bind_method("_search_text_entered",&FindReplaceBar::_search_text_entered);
|
||||
ObjectTypeDB::bind_method("_search_current",&FindReplaceBar::search_current);
|
||||
ObjectTypeDB::bind_method("_search_next",&FindReplaceBar::search_next);
|
||||
ObjectTypeDB::bind_method("_search_prev",&FindReplaceBar::search_prev);
|
||||
ObjectTypeDB::bind_method("_replace_pressed",&FindReplaceBar::_replace);
|
||||
ObjectTypeDB::bind_method("_replace_all_pressed",&FindReplaceBar::_replace_all);
|
||||
ObjectTypeDB::bind_method("_search_options_changed",&FindReplaceBar::_search_options_changed);
|
||||
ObjectTypeDB::bind_method("_hide_pressed",&FindReplaceBar::_hide_bar);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("search"));
|
||||
}
|
||||
|
||||
FindReplaceBar::FindReplaceBar() {
|
||||
|
||||
text_vbc = memnew(VBoxContainer);
|
||||
add_child(text_vbc);
|
||||
|
||||
HBoxContainer *search_hbc = memnew(HBoxContainer);
|
||||
text_vbc->add_child(search_hbc);
|
||||
|
||||
search_text = memnew(LineEdit);
|
||||
search_hbc->add_child(search_text);
|
||||
search_text->set_custom_minimum_size(Size2(200, 0));
|
||||
search_text->connect("text_changed",this,"_search_text_changed");
|
||||
search_text->connect("text_entered",this,"_search_text_entered");
|
||||
|
||||
find_prev = memnew(ToolButton);
|
||||
search_hbc->add_child(find_prev);
|
||||
find_prev->set_focus_mode(FOCUS_NONE);
|
||||
find_prev->connect("pressed",this,"_search_prev");
|
||||
|
||||
find_next = memnew(ToolButton);
|
||||
search_hbc->add_child(find_next);
|
||||
find_next->set_focus_mode(FOCUS_NONE);
|
||||
find_next->connect("pressed",this,"_search_next");
|
||||
|
||||
replace_hbc = memnew(HBoxContainer);
|
||||
text_vbc->add_child(replace_hbc);
|
||||
replace_hbc->hide();
|
||||
|
||||
replace_text = memnew(LineEdit);
|
||||
replace_hbc->add_child(replace_text);
|
||||
replace_text->set_custom_minimum_size(Size2(200, 0));
|
||||
replace_text->connect("text_entered",this,"_search_text_entered");
|
||||
|
||||
replace = memnew(ToolButton);
|
||||
replace_hbc->add_child(replace);
|
||||
replace->set_text(TTR("Replace"));
|
||||
replace->set_focus_mode(FOCUS_NONE);
|
||||
replace->connect("pressed",this,"_replace_pressed");
|
||||
|
||||
replace_all = memnew(ToolButton);
|
||||
replace_hbc->add_child(replace_all);
|
||||
replace_all->set_text(TTR("Replace All"));
|
||||
replace_all->set_focus_mode(FOCUS_NONE);
|
||||
replace_all->connect("pressed",this,"_replace_all_pressed");
|
||||
|
||||
Control *spacer_split = memnew( Control );
|
||||
spacer_split->set_custom_minimum_size(Size2(0, 1));
|
||||
text_vbc->add_child(spacer_split);
|
||||
|
||||
VBoxContainer *options_vbc = memnew(VBoxContainer);
|
||||
add_child(options_vbc);
|
||||
options_vbc->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
HBoxContainer *search_options = memnew(HBoxContainer);
|
||||
options_vbc->add_child(search_options);
|
||||
|
||||
case_sensitive = memnew(CheckBox);
|
||||
search_options->add_child(case_sensitive);
|
||||
case_sensitive->set_text(TTR("Match Case"));
|
||||
case_sensitive->set_focus_mode(FOCUS_NONE);
|
||||
case_sensitive->connect("toggled",this,"_search_options_changed");
|
||||
|
||||
whole_words = memnew(CheckBox);
|
||||
search_options->add_child(whole_words);
|
||||
whole_words->set_text(TTR("Whole Words"));
|
||||
whole_words->set_focus_mode(FOCUS_NONE);
|
||||
whole_words->connect("toggled",this,"_search_options_changed");
|
||||
|
||||
error_label = memnew(Label);
|
||||
search_options->add_child(error_label);
|
||||
|
||||
search_options->add_spacer();
|
||||
|
||||
hide_button = memnew(TextureButton);
|
||||
search_options->add_child(hide_button);
|
||||
hide_button->set_focus_mode(FOCUS_NONE);
|
||||
hide_button->connect("pressed",this,"_hide_pressed");
|
||||
|
||||
replace_options_hbc = memnew(HBoxContainer);
|
||||
options_vbc->add_child(replace_options_hbc);
|
||||
replace_options_hbc->hide();
|
||||
|
||||
selection_only = memnew(CheckBox);
|
||||
replace_options_hbc->add_child(selection_only);
|
||||
selection_only->set_text(TTR("Selection Only"));
|
||||
selection_only->set_focus_mode(FOCUS_NONE);
|
||||
selection_only->connect("toggled",this,"_search_options_changed");
|
||||
}
|
||||
|
||||
|
||||
void FindReplaceDialog::popup_search() {
|
||||
|
||||
set_title(TTR("Search"));
|
||||
|
@ -610,22 +1041,32 @@ void CodeTextEditor::_bind_methods() {
|
|||
|
||||
CodeTextEditor::CodeTextEditor() {
|
||||
|
||||
find_replace_bar = memnew( FindReplaceBar );
|
||||
add_child(find_replace_bar);
|
||||
find_replace_bar->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
find_replace_bar->hide();
|
||||
|
||||
text_editor = memnew( TextEdit );
|
||||
add_child(text_editor);
|
||||
text_editor->set_area_as_parent_rect();
|
||||
text_editor->set_margin(MARGIN_BOTTOM,20);
|
||||
text_editor->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
find_replace_bar->set_text_edit(text_editor);
|
||||
|
||||
text_editor->set_show_line_numbers(true);
|
||||
text_editor->set_brace_matching(true);
|
||||
text_editor->set_auto_indent(true);
|
||||
|
||||
line_col = memnew( Label );
|
||||
add_child(line_col);
|
||||
line_col->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,135);
|
||||
line_col->set_anchor_and_margin(MARGIN_TOP,ANCHOR_END,15);
|
||||
line_col->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,1);
|
||||
line_col->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,5);
|
||||
//line_col->set_align(Label::ALIGN_RIGHT);
|
||||
MarginContainer *status_mc = memnew( MarginContainer );
|
||||
add_child(status_mc);
|
||||
status_mc->set("custom_constants/margin_left", 2);
|
||||
status_mc->set("custom_constants/margin_top", 5);
|
||||
status_mc->set("custom_constants/margin_right", 2);
|
||||
status_mc->set("custom_constants/margin_bottom", 1);
|
||||
|
||||
HBoxContainer *status_bar = memnew( HBoxContainer );
|
||||
status_mc->add_child(status_bar);
|
||||
status_bar->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
idle = memnew( Timer );
|
||||
add_child(idle);
|
||||
idle->set_one_shot(true);
|
||||
|
@ -639,14 +1080,16 @@ CodeTextEditor::CodeTextEditor() {
|
|||
code_complete_timer->set_wait_time(EDITOR_DEF("text_editor/code_complete_delay",.3f));
|
||||
|
||||
error = memnew( Label );
|
||||
add_child(error);
|
||||
error->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,5);
|
||||
error->set_anchor_and_margin(MARGIN_TOP,ANCHOR_END,15);
|
||||
error->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,1);
|
||||
error->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,130);
|
||||
status_bar->add_child(error);
|
||||
error->hide();
|
||||
error->set_valign(Label::VALIGN_CENTER);
|
||||
error->add_color_override("font_color",Color(1,0.7,0.6,0.9));
|
||||
|
||||
status_bar->add_spacer();
|
||||
|
||||
line_col = memnew( Label );
|
||||
status_bar->add_child(line_col);
|
||||
line_col->set_valign(Label::VALIGN_CENTER);
|
||||
|
||||
|
||||
text_editor->connect("cursor_changed", this,"_line_col_changed");
|
||||
|
|
|
@ -33,7 +33,9 @@
|
|||
#include "scene/gui/text_edit.h"
|
||||
#include "scene/gui/dialogs.h"
|
||||
#include "scene/main/timer.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
#include "scene/gui/check_button.h"
|
||||
#include "scene/gui/check_box.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
|
||||
|
||||
|
@ -58,8 +60,71 @@ public:
|
|||
GotoLineDialog();
|
||||
};
|
||||
|
||||
class FindReplaceBar : public HBoxContainer {
|
||||
|
||||
OBJ_TYPE(FindReplaceBar,HBoxContainer);
|
||||
|
||||
LineEdit *search_text;
|
||||
ToolButton *find_prev;
|
||||
ToolButton *find_next;
|
||||
CheckBox *case_sensitive;
|
||||
CheckBox *whole_words;
|
||||
Label *error_label;
|
||||
TextureButton *hide_button;
|
||||
|
||||
LineEdit *replace_text;
|
||||
ToolButton *replace;
|
||||
ToolButton *replace_all;
|
||||
CheckBox *selection_only;
|
||||
|
||||
VBoxContainer *text_vbc;
|
||||
HBoxContainer *replace_hbc;
|
||||
HBoxContainer *replace_options_hbc;
|
||||
|
||||
TextEdit *text_edit;
|
||||
|
||||
int current_result_line;
|
||||
int current_result_col;
|
||||
|
||||
bool replace_all_mode;
|
||||
|
||||
void _show_search();
|
||||
void _hide_bar();
|
||||
void _search_options_changed(bool p_pressed);
|
||||
void _search_text_changed(const String& p_text);
|
||||
void _search_text_entered(const String& p_text);
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
void _unhandled_input(const InputEvent &p_event);
|
||||
|
||||
bool _search(bool p_include_current=false, bool p_backwards=false);
|
||||
|
||||
void _replace();
|
||||
void _replace_all();
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
String get_search_text() const;
|
||||
String get_replace_text() const;
|
||||
|
||||
bool is_case_sensitive() const;
|
||||
bool is_whole_words() const;
|
||||
bool is_selection_only() const;
|
||||
void set_error(const String& p_label);
|
||||
|
||||
void set_text_edit(TextEdit *p_text_edit);
|
||||
|
||||
void popup_search();
|
||||
void popup_replace();
|
||||
|
||||
void search_current();
|
||||
void search_prev();
|
||||
void search_next();
|
||||
|
||||
FindReplaceBar();
|
||||
};
|
||||
|
||||
class FindReplaceDialog : public ConfirmationDialog {
|
||||
|
||||
|
@ -119,11 +184,12 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class CodeTextEditor : public Control {
|
||||
class CodeTextEditor : public VBoxContainer {
|
||||
|
||||
OBJ_TYPE(CodeTextEditor,Control);
|
||||
OBJ_TYPE(CodeTextEditor,VBoxContainer);
|
||||
|
||||
TextEdit *text_editor;
|
||||
FindReplaceBar *find_replace_bar;
|
||||
|
||||
Label *line_col;
|
||||
Label *info;
|
||||
|
@ -158,6 +224,7 @@ protected:
|
|||
public:
|
||||
|
||||
TextEdit *get_text_edit() { return text_editor; }
|
||||
FindReplaceBar *get_find_replace_bar() { return find_replace_bar; }
|
||||
virtual void apply_code() {}
|
||||
|
||||
CodeTextEditor();
|
||||
|
|
|
@ -620,6 +620,8 @@ void EditorSettings::_load_default_text_editor_theme() {
|
|||
set("text_editor/mark_color", Color(1.0,0.4,0.4,0.4));
|
||||
set("text_editor/breakpoint_color", Color(0.8,0.8,0.4,0.2));
|
||||
set("text_editor/word_highlighted_color",Color(0.8,0.9,0.9,0.15));
|
||||
set("text_editor/search_result_color",Color(0.05,0.25,0.05,1));
|
||||
set("text_editor/search_result_border_color",Color(0.1,0.45,0.1,1));
|
||||
}
|
||||
|
||||
void EditorSettings::notify_changes() {
|
||||
|
@ -851,6 +853,8 @@ bool EditorSettings::_save_text_editor_theme(String p_file) {
|
|||
cf->set_value(theme_section, "mark_color", ((Color)get("text_editor/mark_color")).to_html());
|
||||
cf->set_value(theme_section, "breakpoint_color", ((Color)get("text_editor/breakpoint_color")).to_html());
|
||||
cf->set_value(theme_section, "word_highlighted_color", ((Color)get("text_editor/word_highlighted_color")).to_html());
|
||||
cf->set_value(theme_section, "search_result_color", ((Color)get("text_editor/search_result_color")).to_html());
|
||||
cf->set_value(theme_section, "search_result_border_color", ((Color)get("text_editor/search_result_border_color")).to_html());
|
||||
Error err = cf->save(p_file);
|
||||
|
||||
if (err == OK) {
|
||||
|
|
|
@ -300,6 +300,8 @@ void ScriptTextEditor::_load_theme_settings() {
|
|||
get_text_edit()->add_color_override("member_variable_color",EDITOR_DEF("text_editor/member_variable_color",Color(0.9,0.3,0.3)));
|
||||
get_text_edit()->add_color_override("mark_color", EDITOR_DEF("text_editor/mark_color", Color(1.0,0.4,0.4,0.4)));
|
||||
get_text_edit()->add_color_override("breakpoint_color", EDITOR_DEF("text_editor/breakpoint_color", Color(0.8,0.8,0.4,0.2)));
|
||||
get_text_edit()->add_color_override("search_result_color",EDITOR_DEF("text_editor/search_result_color",Color(0.05,0.25,0.05,1)));
|
||||
get_text_edit()->add_color_override("search_result_border_color",EDITOR_DEF("text_editor/search_result_border_color",Color(0.1,0.45,0.1,1)));
|
||||
|
||||
Color keyword_color= EDITOR_DEF("text_editor/keyword_color",Color(0.5,0.0,0.2));
|
||||
|
||||
|
@ -1405,18 +1407,19 @@ void ScriptEditor::_menu_option(int p_option) {
|
|||
} break;
|
||||
case SEARCH_FIND: {
|
||||
|
||||
find_replace_dialog->set_text_edit(current->get_text_edit());
|
||||
find_replace_dialog->popup_search();
|
||||
current->get_find_replace_bar()->popup_search();
|
||||
} break;
|
||||
case SEARCH_FIND_NEXT: {
|
||||
|
||||
find_replace_dialog->set_text_edit(current->get_text_edit());
|
||||
find_replace_dialog->search_next();
|
||||
current->get_find_replace_bar()->search_next();
|
||||
} break;
|
||||
case SEARCH_FIND_PREV: {
|
||||
|
||||
current->get_find_replace_bar()->search_prev();
|
||||
} break;
|
||||
case SEARCH_REPLACE: {
|
||||
|
||||
find_replace_dialog->set_text_edit(current->get_text_edit());
|
||||
find_replace_dialog->popup_replace();
|
||||
current->get_find_replace_bar()->popup_replace();
|
||||
} break;
|
||||
case SEARCH_LOCATE_FUNCTION: {
|
||||
|
||||
|
@ -2531,6 +2534,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
|
|||
search_menu->set_text(TTR("Search"));
|
||||
search_menu->get_popup()->add_item(TTR("Find.."),SEARCH_FIND,KEY_MASK_CMD|KEY_F);
|
||||
search_menu->get_popup()->add_item(TTR("Find Next"),SEARCH_FIND_NEXT,KEY_F3);
|
||||
search_menu->get_popup()->add_item(TTR("Find Previous"),SEARCH_FIND_PREV,KEY_MASK_SHIFT|KEY_F3);
|
||||
search_menu->get_popup()->add_item(TTR("Replace.."),SEARCH_REPLACE,KEY_MASK_CMD|KEY_R);
|
||||
search_menu->get_popup()->add_separator();
|
||||
search_menu->get_popup()->add_item(TTR("Goto Function.."),SEARCH_LOCATE_FUNCTION,KEY_MASK_SHIFT|KEY_MASK_CMD|KEY_F);
|
||||
|
@ -2635,9 +2639,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
|
|||
|
||||
tab_container->connect("tab_changed", this,"_tab_changed");
|
||||
|
||||
find_replace_dialog = memnew(FindReplaceDialog);
|
||||
add_child(find_replace_dialog);
|
||||
|
||||
erase_tab_confirm = memnew( ConfirmationDialog );
|
||||
add_child(erase_tab_confirm);
|
||||
erase_tab_confirm->connect("confirmed", this,"_close_current_tab");
|
||||
|
|
|
@ -144,6 +144,7 @@ class ScriptEditor : public VBoxContainer {
|
|||
EDIT_CLONE_DOWN,
|
||||
SEARCH_FIND,
|
||||
SEARCH_FIND_NEXT,
|
||||
SEARCH_FIND_PREV,
|
||||
SEARCH_REPLACE,
|
||||
SEARCH_LOCATE_FUNCTION,
|
||||
SEARCH_GOTO_LINE,
|
||||
|
@ -184,7 +185,6 @@ class ScriptEditor : public VBoxContainer {
|
|||
HSplitContainer *script_split;
|
||||
TabContainer *tab_container;
|
||||
EditorFileDialog *file_dialog;
|
||||
FindReplaceDialog *find_replace_dialog;
|
||||
GotoLineDialog *goto_line_dialog;
|
||||
ConfirmationDialog *erase_tab_confirm;
|
||||
ScriptCreateDialog *script_create_dialog;
|
||||
|
|
|
@ -90,6 +90,8 @@ void ShaderTextEditor::_load_theme_settings() {
|
|||
get_text_edit()->add_color_override("member_variable_color",EDITOR_DEF("text_editor/member_variable_color",Color(0.9,0.3,0.3)));
|
||||
get_text_edit()->add_color_override("mark_color", EDITOR_DEF("text_editor/mark_color", Color(1.0,0.4,0.4,0.4)));
|
||||
get_text_edit()->add_color_override("breakpoint_color", EDITOR_DEF("text_editor/breakpoint_color", Color(0.8,0.8,0.4,0.2)));
|
||||
get_text_edit()->add_color_override("search_result_color",EDITOR_DEF("text_editor/search_result_color",Color(0.05,0.25,0.05,1)));
|
||||
get_text_edit()->add_color_override("search_result_border_color",EDITOR_DEF("text_editor/search_result_border_color",Color(0.1,0.45,0.1,1)));
|
||||
|
||||
Color keyword_color= EDITOR_DEF("text_editor/keyword_color",Color(0.5,0.0,0.2));
|
||||
|
||||
|
@ -212,18 +214,19 @@ void ShaderEditor::_menu_option(int p_option) {
|
|||
} break;
|
||||
case SEARCH_FIND: {
|
||||
|
||||
find_replace_dialog->set_text_edit(current->get_text_edit());
|
||||
find_replace_dialog->popup_search();
|
||||
current->get_find_replace_bar()->popup_search();
|
||||
} break;
|
||||
case SEARCH_FIND_NEXT: {
|
||||
|
||||
find_replace_dialog->set_text_edit(current->get_text_edit());
|
||||
find_replace_dialog->search_next();
|
||||
current->get_find_replace_bar()->search_next();
|
||||
} break;
|
||||
case SEARCH_FIND_PREV: {
|
||||
|
||||
current->get_find_replace_bar()->search_prev();
|
||||
} break;
|
||||
case SEARCH_REPLACE: {
|
||||
|
||||
find_replace_dialog->set_text_edit(current->get_text_edit());
|
||||
find_replace_dialog->popup_replace();
|
||||
current->get_find_replace_bar()->popup_replace();
|
||||
} break;
|
||||
// case SEARCH_LOCATE_SYMBOL: {
|
||||
|
||||
|
@ -507,6 +510,7 @@ ShaderEditor::ShaderEditor() {
|
|||
search_menu->set_text(TTR("Search"));
|
||||
search_menu->get_popup()->add_item(TTR("Find.."),SEARCH_FIND,KEY_MASK_CMD|KEY_F);
|
||||
search_menu->get_popup()->add_item(TTR("Find Next"),SEARCH_FIND_NEXT,KEY_F3);
|
||||
search_menu->get_popup()->add_item(TTR("Find Previous"),SEARCH_FIND_PREV,KEY_MASK_SHIFT|KEY_F3);
|
||||
search_menu->get_popup()->add_item(TTR("Replace.."),SEARCH_REPLACE,KEY_MASK_CMD|KEY_R);
|
||||
search_menu->get_popup()->add_separator();
|
||||
// search_menu->get_popup()->add_item("Locate Symbol..",SEARCH_LOCATE_SYMBOL,KEY_MASK_CMD|KEY_K);
|
||||
|
@ -516,9 +520,6 @@ ShaderEditor::ShaderEditor() {
|
|||
|
||||
tab_container->connect("tab_changed", this,"_tab_changed");
|
||||
|
||||
find_replace_dialog = memnew(FindReplaceDialog);
|
||||
add_child(find_replace_dialog);
|
||||
|
||||
erase_tab_confirm = memnew( ConfirmationDialog );
|
||||
add_child(erase_tab_confirm);
|
||||
erase_tab_confirm->connect("confirmed", this,"_close_current_tab");
|
||||
|
|
|
@ -76,6 +76,7 @@ class ShaderEditor : public Control {
|
|||
EDIT_SELECT_ALL,
|
||||
SEARCH_FIND,
|
||||
SEARCH_FIND_NEXT,
|
||||
SEARCH_FIND_PREV,
|
||||
SEARCH_REPLACE,
|
||||
//SEARCH_LOCATE_SYMBOL,
|
||||
SEARCH_GOTO_LINE,
|
||||
|
@ -88,7 +89,6 @@ class ShaderEditor : public Control {
|
|||
uint64_t idle;
|
||||
|
||||
TabContainer *tab_container;
|
||||
FindReplaceDialog *find_replace_dialog;
|
||||
GotoLineDialog *goto_line_dialog;
|
||||
ConfirmationDialog *erase_tab_confirm;
|
||||
|
||||
|
|
Loading…
Reference in a new issue