Merge pull request #4812 from neikeq/pr-search-bar

ScriptEditor/ShaderEditor: Replace find/replace dialog with a bar
This commit is contained in:
Rémi Verschelde 2016-05-29 18:32:06 +02:00
commit 6a7530c718
9 changed files with 640 additions and 55 deletions

View file

@ -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)) {

View file

@ -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;

View file

@ -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");

View file

@ -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();

View file

@ -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) {

View file

@ -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");

View file

@ -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;

View file

@ -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");

View file

@ -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;