Add main_gutter (breakpoints, bookmarks, execution lines) to code_edit

This commit is contained in:
Paulb23 2020-07-26 15:57:23 +01:00
parent 907f9f2a84
commit 4d7df24d46
19 changed files with 403 additions and 377 deletions

View file

@ -934,8 +934,7 @@ void CodeTextEditor::update_editor_settings() {
text_editor->set_minimap_width((int)EditorSettings::get_singleton()->get("text_editor/navigation/minimap_width") * EDSCALE);
text_editor->set_draw_line_numbers(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_numbers"));
text_editor->set_line_numbers_zero_padded(EditorSettings::get_singleton()->get("text_editor/appearance/line_numbers_zero_padded"));
text_editor->set_bookmark_gutter_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/show_bookmark_gutter"));
text_editor->set_breakpoint_gutter_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/show_breakpoint_gutter"));
text_editor->set_draw_bookmarks_gutter(EditorSettings::get_singleton()->get("text_editor/appearance/show_bookmark_gutter"));
text_editor->set_draw_info_gutter(EditorSettings::get_singleton()->get("text_editor/appearance/show_info_gutter"));
text_editor->set_hiding_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/code_folding"));
text_editor->set_draw_fold_gutter(EditorSettings::get_singleton()->get("text_editor/appearance/code_folding"));
@ -1390,11 +1389,11 @@ void CodeTextEditor::goto_line_centered(int p_line) {
}
void CodeTextEditor::set_executing_line(int p_line) {
text_editor->set_executing_line(p_line);
text_editor->set_line_as_executing(p_line, true);
}
void CodeTextEditor::clear_executing_line() {
text_editor->clear_executing_line();
text_editor->clear_executing_lines();
}
Variant CodeTextEditor::get_edit_state() {
@ -1414,8 +1413,8 @@ Variant CodeTextEditor::get_edit_state() {
}
state["folded_lines"] = text_editor->get_folded_lines();
state["breakpoints"] = text_editor->get_breakpoints_array();
state["bookmarks"] = text_editor->get_bookmarks_array();
state["breakpoints"] = text_editor->get_breakpointed_lines();
state["bookmarks"] = text_editor->get_bookmarked_lines();
Ref<EditorSyntaxHighlighter> syntax_highlighter = text_editor->get_syntax_highlighter();
state["syntax_highlighter"] = syntax_highlighter->_get_name();
@ -1453,7 +1452,7 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) {
if (state.has("bookmarks")) {
Array bookmarks = state["bookmarks"];
for (int i = 0; i < bookmarks.size(); i++) {
text_editor->set_line_as_bookmark(bookmarks[i], true);
text_editor->set_line_as_bookmarked(bookmarks[i], true);
}
}
}
@ -1591,27 +1590,26 @@ void CodeTextEditor::set_warning_nb(int p_warning_nb) {
void CodeTextEditor::toggle_bookmark() {
int line = text_editor->cursor_get_line();
text_editor->set_line_as_bookmark(line, !text_editor->is_line_set_as_bookmark(line));
text_editor->set_line_as_bookmarked(line, !text_editor->is_line_bookmarked(line));
}
void CodeTextEditor::goto_next_bookmark() {
List<int> bmarks;
text_editor->get_bookmarks(&bmarks);
Array bmarks = text_editor->get_bookmarked_lines();
if (bmarks.size() <= 0) {
return;
}
int line = text_editor->cursor_get_line();
if (line >= bmarks[bmarks.size() - 1]) {
if (line >= (int)bmarks[bmarks.size() - 1]) {
text_editor->unfold_line(bmarks[0]);
text_editor->cursor_set_line(bmarks[0]);
text_editor->center_viewport_to_cursor();
} else {
for (List<int>::Element *E = bmarks.front(); E; E = E->next()) {
int bline = E->get();
if (bline > line) {
text_editor->unfold_line(bline);
text_editor->cursor_set_line(bline);
for (int i = 0; i < bmarks.size(); i++) {
int bmark_line = bmarks[i];
if (bmark_line > line) {
text_editor->unfold_line(bmark_line);
text_editor->cursor_set_line(bmark_line);
text_editor->center_viewport_to_cursor();
return;
}
@ -1620,23 +1618,22 @@ void CodeTextEditor::goto_next_bookmark() {
}
void CodeTextEditor::goto_prev_bookmark() {
List<int> bmarks;
text_editor->get_bookmarks(&bmarks);
Array bmarks = text_editor->get_bookmarked_lines();
if (bmarks.size() <= 0) {
return;
}
int line = text_editor->cursor_get_line();
if (line <= bmarks[0]) {
if (line <= (int)bmarks[0]) {
text_editor->unfold_line(bmarks[bmarks.size() - 1]);
text_editor->cursor_set_line(bmarks[bmarks.size() - 1]);
text_editor->center_viewport_to_cursor();
} else {
for (List<int>::Element *E = bmarks.back(); E; E = E->prev()) {
int bline = E->get();
if (bline < line) {
text_editor->unfold_line(bline);
text_editor->cursor_set_line(bline);
for (int i = bmarks.size(); i >= 0; i--) {
int bmark_line = bmarks[i];
if (bmark_line < line) {
text_editor->unfold_line(bmark_line);
text_editor->cursor_set_line(bmark_line);
text_editor->center_viewport_to_cursor();
return;
}
@ -1645,12 +1642,7 @@ void CodeTextEditor::goto_prev_bookmark() {
}
void CodeTextEditor::remove_all_bookmarks() {
List<int> bmarks;
text_editor->get_bookmarks(&bmarks);
for (List<int>::Element *E = bmarks.front(); E; E = E->next()) {
text_editor->set_line_as_bookmark(E->get(), false);
}
text_editor->clear_bookmarked_lines();
}
void CodeTextEditor::_bind_methods() {
@ -1694,6 +1686,8 @@ CodeTextEditor::CodeTextEditor() {
find_replace_bar->set_text_edit(text_editor);
text_editor->set_draw_line_numbers(true);
text_editor->set_draw_breakpoints_gutter(true);
text_editor->set_draw_executing_lines_gutter(true);
text_editor->set_brace_matching(true);
text_editor->set_auto_indent(true);

View file

@ -707,8 +707,8 @@ void EditorSettings::_load_default_text_editor_theme() {
_initial_set("text_editor/highlighting/member_variable_color", Color(0.9, 0.31, 0.35));
_initial_set("text_editor/highlighting/mark_color", Color(1.0, 0.4, 0.4, 0.4));
_initial_set("text_editor/highlighting/bookmark_color", Color(0.08, 0.49, 0.98));
_initial_set("text_editor/highlighting/breakpoint_color", Color(0.8, 0.8, 0.4, 0.2));
_initial_set("text_editor/highlighting/executing_line_color", Color(0.2, 0.8, 0.2, 0.4));
_initial_set("text_editor/highlighting/breakpoint_color", Color(0.9, 0.29, 0.3));
_initial_set("text_editor/highlighting/executing_line_color", Color(0.98, 0.89, 0.27));
_initial_set("text_editor/highlighting/code_folding_color", Color(0.8, 0.8, 0.8, 0.8));
_initial_set("text_editor/highlighting/search_result_color", Color(0.05, 0.25, 0.05, 1));
_initial_set("text_editor/highlighting/search_result_border_color", Color(0.41, 0.61, 0.91, 0.38));

View file

@ -883,6 +883,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("space", "CodeEdit", theme->get_icon("GuiSpace", "EditorIcons"));
theme->set_icon("folded", "CodeEdit", theme->get_icon("GuiTreeArrowRight", "EditorIcons"));
theme->set_icon("fold", "CodeEdit", theme->get_icon("GuiTreeArrowDown", "EditorIcons"));
theme->set_icon("executing_line", "CodeEdit", theme->get_icon("MainPlay", "EditorIcons"));
theme->set_color("font_color", "CodeEdit", font_color);
theme->set_color("caret_color", "CodeEdit", font_color);
theme->set_color("selection_color", "CodeEdit", font_color_selection);
@ -1192,7 +1193,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color mark_color = Color(error_color.r, error_color.g, error_color.b, 0.3);
const Color bookmark_color = Color(0.08, 0.49, 0.98);
const Color breakpoint_color = error_color;
const Color executing_line_color = Color(0.2, 0.8, 0.2, 0.4);
const Color executing_line_color = Color(0.98, 0.89, 0.27);
const Color code_folding_color = alpha3;
const Color search_result_color = alpha1;
const Color search_result_border_color = Color(0.41, 0.61, 0.91, 0.38);

View file

@ -1585,15 +1585,14 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
continue;
}
List<int> bpoints;
se->get_breakpoints(&bpoints);
String base = script->get_path();
if (base.begins_with("local://") || base == "") {
continue;
}
for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
p_breakpoints->push_back(base + ":" + itos(E->get() + 1));
Array bpoints = se->get_breakpoints();
for (int j = 0; j < bpoints.size(); j++) {
p_breakpoints->push_back(base + ":" + itos((int)bpoints[j] + 1));
}
}
}

View file

@ -151,7 +151,7 @@ public:
virtual void ensure_focus() = 0;
virtual void tag_saved_version() = 0;
virtual void reload(bool p_soft) {}
virtual void get_breakpoints(List<int> *p_breakpoints) = 0;
virtual Array get_breakpoints() = 0;
virtual void add_callback(const String &p_function, PackedStringArray p_args) = 0;
virtual void update_settings() = 0;
virtual void set_debugger_active(bool p_active) = 0;

View file

@ -566,7 +566,7 @@ void ScriptTextEditor::_update_bookmark_list() {
bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
Array bookmark_list = code_editor->get_text_editor()->get_bookmarks_array();
Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines();
if (bookmark_list.size() == 0) {
return;
}
@ -717,7 +717,7 @@ void ScriptTextEditor::_update_breakpoint_list() {
breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_breakpoint"), DEBUG_GOTO_NEXT_BREAKPOINT);
breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_breakpoint"), DEBUG_GOTO_PREV_BREAKPOINT);
Array breakpoint_list = code_editor->get_text_editor()->get_breakpoints_array();
Array breakpoint_list = code_editor->get_text_editor()->get_breakpointed_lines();
if (breakpoint_list.size() == 0) {
return;
}
@ -749,7 +749,7 @@ void ScriptTextEditor::_breakpoint_item_pressed(int p_idx) {
}
void ScriptTextEditor::_breakpoint_toggled(int p_row) {
EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_editor()->is_line_set_as_breakpoint(p_row));
EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_editor()->is_line_breakpointed(p_row));
}
void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_column) {
@ -1177,24 +1177,22 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case DEBUG_TOGGLE_BREAKPOINT: {
int line = tx->cursor_get_line();
bool dobreak = !tx->is_line_set_as_breakpoint(line);
bool dobreak = !tx->is_line_breakpointed(line);
tx->set_line_as_breakpoint(line, dobreak);
EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak);
} break;
case DEBUG_REMOVE_ALL_BREAKPOINTS: {
List<int> bpoints;
tx->get_breakpoints(&bpoints);
Array bpoints = tx->get_breakpointed_lines();
for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
int line = E->get();
bool dobreak = !tx->is_line_set_as_breakpoint(line);
for (int i = 0; i < bpoints.size(); i++) {
int line = bpoints[i];
bool dobreak = !tx->is_line_breakpointed(line);
tx->set_line_as_breakpoint(line, dobreak);
EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak);
}
} break;
case DEBUG_GOTO_NEXT_BREAKPOINT: {
List<int> bpoints;
tx->get_breakpoints(&bpoints);
Array bpoints = tx->get_breakpointed_lines();
if (bpoints.size() <= 0) {
return;
}
@ -1202,13 +1200,13 @@ void ScriptTextEditor::_edit_option(int p_op) {
int line = tx->cursor_get_line();
// wrap around
if (line >= bpoints[bpoints.size() - 1]) {
if (line >= (int)bpoints[bpoints.size() - 1]) {
tx->unfold_line(bpoints[0]);
tx->cursor_set_line(bpoints[0]);
tx->center_viewport_to_cursor();
} else {
for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
int bline = E->get();
for (int i = 0; i < bpoints.size(); i++) {
int bline = bpoints[i];
if (bline > line) {
tx->unfold_line(bline);
tx->cursor_set_line(bline);
@ -1220,21 +1218,20 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case DEBUG_GOTO_PREV_BREAKPOINT: {
List<int> bpoints;
tx->get_breakpoints(&bpoints);
Array bpoints = tx->get_breakpointed_lines();
if (bpoints.size() <= 0) {
return;
}
int line = tx->cursor_get_line();
// wrap around
if (line <= bpoints[0]) {
if (line <= (int)bpoints[0]) {
tx->unfold_line(bpoints[bpoints.size() - 1]);
tx->cursor_set_line(bpoints[bpoints.size() - 1]);
tx->center_viewport_to_cursor();
} else {
for (List<int>::Element *E = bpoints.back(); E; E = E->prev()) {
int bline = E->get();
for (int i = bpoints.size(); i >= 0; i--) {
int bline = bpoints[i];
if (bline < line) {
tx->unfold_line(bline);
tx->cursor_set_line(bline);
@ -1342,8 +1339,8 @@ void ScriptTextEditor::reload(bool p_soft) {
scr->get_language()->reload_tool_script(scr, soft);
}
void ScriptTextEditor::get_breakpoints(List<int> *p_breakpoints) {
code_editor->get_text_editor()->get_breakpoints(p_breakpoints);
Array ScriptTextEditor::get_breakpoints() {
return code_editor->get_text_editor()->get_breakpointed_lines();
}
void ScriptTextEditor::set_tooltip_request_func(String p_method, Object *p_obj) {

View file

@ -211,7 +211,7 @@ public:
virtual void clear_executing_line() override;
virtual void reload(bool p_soft) override;
virtual void get_breakpoints(List<int> *p_breakpoints) override;
virtual Array get_breakpoints() override;
virtual void add_callback(const String &p_function, PackedStringArray p_args) override;
virtual void update_settings() override;

View file

@ -379,7 +379,7 @@ void ShaderEditor::_editor_settings_changed() {
shader_editor->get_text_editor()->set_show_line_length_guidelines(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_length_guidelines"));
shader_editor->get_text_editor()->set_line_length_guideline_soft_column(EditorSettings::get_singleton()->get("text_editor/appearance/line_length_guideline_soft_column"));
shader_editor->get_text_editor()->set_line_length_guideline_hard_column(EditorSettings::get_singleton()->get("text_editor/appearance/line_length_guideline_hard_column"));
shader_editor->get_text_editor()->set_breakpoint_gutter_enabled(false);
shader_editor->get_text_editor()->set_draw_breakpoints_gutter(false);
}
void ShaderEditor::_bind_methods() {
@ -521,7 +521,7 @@ void ShaderEditor::_update_bookmark_list() {
bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
Array bookmark_list = shader_editor->get_text_editor()->get_bookmarks_array();
Array bookmark_list = shader_editor->get_text_editor()->get_bookmarked_lines();
if (bookmark_list.size() == 0) {
return;
}

View file

@ -171,7 +171,8 @@ void TextEditor::add_callback(const String &p_function, PackedStringArray p_args
void TextEditor::set_debugger_active(bool p_active) {
}
void TextEditor::get_breakpoints(List<int> *p_breakpoints) {
Array TextEditor::get_breakpoints() {
return Array();
}
void TextEditor::reload_text() {
@ -207,7 +208,7 @@ void TextEditor::_update_bookmark_list() {
bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
Array bookmark_list = code_editor->get_text_editor()->get_bookmarks_array();
Array bookmark_list = code_editor->get_text_editor()->get_bookmarked_lines();
if (bookmark_list.size() == 0) {
return;
}

View file

@ -119,7 +119,7 @@ public:
virtual Variant get_edit_state() override;
virtual void set_edit_state(const Variant &p_state) override;
virtual Vector<String> get_functions() override;
virtual void get_breakpoints(List<int> *p_breakpoints) override;
virtual Array get_breakpoints() override;
virtual void goto_line(int p_line, bool p_with_error = false) override;
void goto_line_selection(int p_line, int p_begin, int p_end);
virtual void set_executing_line(int p_line) override;

View file

@ -2682,7 +2682,8 @@ void VisualScriptEditor::reload(bool p_soft) {
_update_graph();
}
void VisualScriptEditor::get_breakpoints(List<int> *p_breakpoints) {
Array VisualScriptEditor::get_breakpoints() {
Array breakpoints;
List<StringName> functions;
script->get_function_list(&functions);
for (List<StringName>::Element *E = functions.front(); E; E = E->next()) {
@ -2691,10 +2692,11 @@ void VisualScriptEditor::get_breakpoints(List<int> *p_breakpoints) {
for (List<int>::Element *F = nodes.front(); F; F = F->next()) {
Ref<VisualScriptNode> vsn = script->get_node(E->get(), F->get());
if (vsn->is_breakpoint()) {
p_breakpoints->push_back(F->get() - 1); //subtract 1 because breakpoints in text start from zero
breakpoints.push_back(F->get() - 1); //subtract 1 because breakpoints in text start from zero
}
}
}
return breakpoints;
}
void VisualScriptEditor::add_callback(const String &p_function, PackedStringArray p_args) {

View file

@ -312,7 +312,7 @@ public:
virtual void ensure_focus() override;
virtual void tag_saved_version() override;
virtual void reload(bool p_soft) override;
virtual void get_breakpoints(List<int> *p_breakpoints) override;
virtual Array get_breakpoints() override;
virtual void add_callback(const String &p_function, PackedStringArray p_args) override;
virtual void update_settings() override;
virtual bool show_members_overview() override;

View file

@ -34,8 +34,18 @@ void CodeEdit::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
set_gutter_width(main_gutter, cache.row_height);
set_gutter_width(line_number_gutter, (line_number_digits + 1) * cache.font->get_char_size('0').width);
breakpoint_color = get_theme_color("breakpoint_color");
breakpoint_icon = get_theme_icon("breakpoint");
bookmark_color = get_theme_color("bookmark_color");
bookmark_icon = get_theme_icon("bookmark");
executing_line_color = get_theme_color("executing_line_color");
executing_line_icon = get_theme_icon("executing_line");
line_number_color = get_theme_color("line_number_color");
} break;
case NOTIFICATION_DRAW: {
@ -43,6 +53,160 @@ void CodeEdit::_notification(int p_what) {
}
}
/* Main Gutter */
void CodeEdit::_update_draw_main_gutter() {
set_gutter_draw(main_gutter, draw_breakpoints || draw_bookmarks || draw_executing_lines);
}
void CodeEdit::set_draw_breakpoints_gutter(bool p_draw) {
draw_breakpoints = p_draw;
set_gutter_clickable(main_gutter, p_draw);
_update_draw_main_gutter();
}
bool CodeEdit::is_drawing_breakpoints_gutter() const {
return draw_breakpoints;
}
void CodeEdit::set_draw_bookmarks_gutter(bool p_draw) {
draw_bookmarks = p_draw;
_update_draw_main_gutter();
}
bool CodeEdit::is_drawing_bookmarks_gutter() const {
return draw_bookmarks;
}
void CodeEdit::set_draw_executing_lines_gutter(bool p_draw) {
draw_executing_lines = p_draw;
_update_draw_main_gutter();
}
bool CodeEdit::is_drawing_executing_lines_gutter() const {
return draw_executing_lines;
}
void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 &p_region) {
if (draw_breakpoints && is_line_breakpointed(p_line)) {
int padding = p_region.size.x / 6;
Rect2 breakpoint_region = p_region;
breakpoint_region.position += Point2(padding, padding);
breakpoint_region.size -= Point2(padding, padding) * 2;
breakpoint_icon->draw_rect(get_canvas_item(), breakpoint_region, false, breakpoint_color);
}
if (draw_bookmarks && is_line_bookmarked(p_line)) {
int horizontal_padding = p_region.size.x / 2;
int vertical_padding = p_region.size.y / 4;
Rect2 bookmark_region = p_region;
bookmark_region.position += Point2(horizontal_padding, 0);
bookmark_region.size -= Point2(horizontal_padding * 1.1, vertical_padding);
bookmark_icon->draw_rect(get_canvas_item(), bookmark_region, false, bookmark_color);
}
if (draw_executing_lines && is_line_executing(p_line)) {
int horizontal_padding = p_region.size.x / 10;
int vertical_padding = p_region.size.y / 4;
Rect2 executing_line_region = p_region;
executing_line_region.position += Point2(horizontal_padding, vertical_padding);
executing_line_region.size -= Point2(horizontal_padding, vertical_padding) * 2;
executing_line_icon->draw_rect(get_canvas_item(), executing_line_region, false, executing_line_color);
}
}
// Breakpoints
void CodeEdit::set_line_as_breakpoint(int p_line, bool p_breakpointed) {
int mask = get_line_gutter_metadata(p_line, main_gutter);
set_line_gutter_metadata(p_line, main_gutter, p_breakpointed ? mask | MAIN_GUTTER_BREAKPOINT : mask & ~MAIN_GUTTER_BREAKPOINT);
if (p_breakpointed) {
breakpointed_lines[p_line] = true;
} else if (breakpointed_lines.has(p_line)) {
breakpointed_lines.erase(p_line);
}
emit_signal("breakpoint_toggled", p_line);
}
bool CodeEdit::is_line_breakpointed(int p_line) const {
return (int)get_line_gutter_metadata(p_line, main_gutter) & MAIN_GUTTER_BREAKPOINT;
}
void CodeEdit::clear_breakpointed_lines() {
for (int i = 0; i < get_line_count(); i++) {
if (is_line_breakpointed(i)) {
set_line_as_breakpoint(i, false);
}
}
}
Array CodeEdit::get_breakpointed_lines() const {
Array ret;
for (int i = 0; i < get_line_count(); i++) {
if (is_line_breakpointed(i)) {
ret.append(i);
}
}
return ret;
}
// Bookmarks
void CodeEdit::set_line_as_bookmarked(int p_line, bool p_bookmarked) {
int mask = get_line_gutter_metadata(p_line, main_gutter);
set_line_gutter_metadata(p_line, main_gutter, p_bookmarked ? mask | MAIN_GUTTER_BOOKMARK : mask & ~MAIN_GUTTER_BOOKMARK);
}
bool CodeEdit::is_line_bookmarked(int p_line) const {
return (int)get_line_gutter_metadata(p_line, main_gutter) & MAIN_GUTTER_BOOKMARK;
}
void CodeEdit::clear_bookmarked_lines() {
for (int i = 0; i < get_line_count(); i++) {
if (is_line_bookmarked(i)) {
set_line_as_bookmarked(i, false);
}
}
}
Array CodeEdit::get_bookmarked_lines() const {
Array ret;
for (int i = 0; i < get_line_count(); i++) {
if (is_line_bookmarked(i)) {
ret.append(i);
}
}
return ret;
}
// executing lines
void CodeEdit::set_line_as_executing(int p_line, bool p_executing) {
int mask = get_line_gutter_metadata(p_line, main_gutter);
set_line_gutter_metadata(p_line, main_gutter, p_executing ? mask | MAIN_GUTTER_EXECUTING : mask & ~MAIN_GUTTER_EXECUTING);
}
bool CodeEdit::is_line_executing(int p_line) const {
return (int)get_line_gutter_metadata(p_line, main_gutter) & MAIN_GUTTER_EXECUTING;
}
void CodeEdit::clear_executing_lines() {
for (int i = 0; i < get_line_count(); i++) {
if (is_line_executing(i)) {
set_line_as_executing(i, false);
}
}
}
Array CodeEdit::get_executing_lines() const {
Array ret;
for (int i = 0; i < get_line_count(); i++) {
if (is_line_executing(i)) {
ret.append(i);
}
}
return ret;
}
/* Line numbers */
void CodeEdit::set_draw_line_numbers(bool p_draw) {
set_gutter_draw(line_number_gutter, p_draw);
@ -69,6 +233,36 @@ void CodeEdit::_line_number_draw_callback(int p_line, int p_gutter, const Rect2
}
void CodeEdit::_bind_methods() {
/* Main Gutter */
ClassDB::bind_method(D_METHOD("_main_gutter_draw_callback"), &CodeEdit::_main_gutter_draw_callback);
ClassDB::bind_method(D_METHOD("set_draw_breakpoints_gutter", "enable"), &CodeEdit::set_draw_breakpoints_gutter);
ClassDB::bind_method(D_METHOD("is_drawing_breakpoints_gutter"), &CodeEdit::is_drawing_breakpoints_gutter);
ClassDB::bind_method(D_METHOD("set_draw_bookmarks_gutter", "enable"), &CodeEdit::set_draw_bookmarks_gutter);
ClassDB::bind_method(D_METHOD("is_drawing_bookmarks_gutter"), &CodeEdit::is_drawing_bookmarks_gutter);
ClassDB::bind_method(D_METHOD("set_draw_executing_lines_gutter", "enable"), &CodeEdit::set_draw_executing_lines_gutter);
ClassDB::bind_method(D_METHOD("is_drawing_executing_lines_gutter"), &CodeEdit::is_drawing_executing_lines_gutter);
// Breakpoints
ClassDB::bind_method(D_METHOD("set_line_as_breakpoint", "line", "breakpointed"), &CodeEdit::set_line_as_breakpoint);
ClassDB::bind_method(D_METHOD("is_line_breakpointed", "line"), &CodeEdit::is_line_breakpointed);
ClassDB::bind_method(D_METHOD("clear_breakpointed_lines"), &CodeEdit::clear_breakpointed_lines);
ClassDB::bind_method(D_METHOD("get_breakpointed_lines"), &CodeEdit::get_breakpointed_lines);
// Bookmarks
ClassDB::bind_method(D_METHOD("set_line_as_bookmarked", "line", "bookmarked"), &CodeEdit::set_line_as_bookmarked);
ClassDB::bind_method(D_METHOD("is_line_bookmarked", "line"), &CodeEdit::is_line_bookmarked);
ClassDB::bind_method(D_METHOD("clear_bookmarked_lines"), &CodeEdit::clear_bookmarked_lines);
ClassDB::bind_method(D_METHOD("get_bookmarked_lines"), &CodeEdit::get_bookmarked_lines);
// executing lines
ClassDB::bind_method(D_METHOD("set_line_as_executing", "line", "executing"), &CodeEdit::set_line_as_executing);
ClassDB::bind_method(D_METHOD("is_line_executing", "line"), &CodeEdit::is_line_executing);
ClassDB::bind_method(D_METHOD("clear_executing_lines"), &CodeEdit::clear_executing_lines);
ClassDB::bind_method(D_METHOD("get_executing_lines"), &CodeEdit::get_executing_lines);
/* Line numbers */
ClassDB::bind_method(D_METHOD("_line_number_draw_callback"), &CodeEdit::_line_number_draw_callback);
@ -77,11 +271,28 @@ void CodeEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_line_numbers_zero_padded", "enable"), &CodeEdit::set_line_numbers_zero_padded);
ClassDB::bind_method(D_METHOD("is_line_numbers_zero_padded"), &CodeEdit::is_line_numbers_zero_padded);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_breakpoints_gutter"), "set_draw_breakpoints_gutter", "is_drawing_breakpoints_gutter");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_bookmarks"), "set_draw_bookmarks_gutter", "is_drawing_bookmarks_gutter");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_executing_lines"), "set_draw_executing_lines_gutter", "is_drawing_executing_lines_gutter");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_line_numbers"), "set_draw_line_numbers", "is_draw_line_numbers_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "zero_pad_line_numbers"), "set_line_numbers_zero_padded", "is_line_numbers_zero_padded");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_fold_gutter"), "set_draw_fold_gutter", "is_drawing_fold_gutter");
ADD_SIGNAL(MethodInfo("breakpoint_toggled", PropertyInfo(Variant::INT, "line")));
}
void CodeEdit::_gutter_clicked(int p_line, int p_gutter) {
if (p_gutter == main_gutter) {
if (draw_breakpoints) {
set_line_as_breakpoint(p_line, !is_line_breakpointed(p_line));
}
return;
}
if (p_gutter == line_number_gutter) {
cursor_set_line(p_line);
return;
@ -89,21 +300,44 @@ void CodeEdit::_gutter_clicked(int p_line, int p_gutter) {
}
void CodeEdit::_lines_edited_from(int p_from_line, int p_to_line) {
int line_count = get_line_count();
if (line_count != cached_line_count) {
int lc = line_count;
line_number_digits = 1;
while (lc /= 10) {
line_number_digits++;
}
set_gutter_width(line_number_gutter, (line_number_digits + 1) * cache.font->get_char_size('0').width);
if (p_from_line == p_to_line) {
return;
}
cached_line_count = line_count;
int lc = get_line_count();
line_number_digits = 1;
while (lc /= 10) {
line_number_digits++;
}
set_gutter_width(line_number_gutter, (line_number_digits + 1) * cache.font->get_char_size('0').width);
int from_line = MIN(p_from_line, p_to_line);
int line_count = (p_to_line - p_from_line);
List<int> breakpoints;
breakpointed_lines.get_key_list(&breakpoints);
for (const List<int>::Element *E = breakpoints.front(); E; E = E->next()) {
int line = E->get();
if (line <= from_line) {
continue;
}
breakpointed_lines.erase(line);
emit_signal("breakpoint_toggled", line);
if (line_count > 0 || line >= p_from_line) {
emit_signal("breakpoint_toggled", line + line_count);
breakpointed_lines[line + line_count] = true;
continue;
}
}
}
void CodeEdit::_update_gutter_indexes() {
for (int i = 0; i < get_gutter_count(); i++) {
if (get_gutter_name(i) == "main_gutter") {
main_gutter = i;
continue;
}
if (get_gutter_name(i) == "line_numbers") {
line_number_gutter = i;
continue;
@ -112,12 +346,25 @@ void CodeEdit::_update_gutter_indexes() {
}
CodeEdit::CodeEdit() {
/* Gutters */
int gutter_idx = 0;
/* Main Gutter */
add_gutter();
set_gutter_name(gutter_idx, "main_gutter");
set_gutter_draw(gutter_idx, false);
set_gutter_overwritable(gutter_idx, true);
set_gutter_type(gutter_idx, GUTTER_TPYE_CUSTOM);
set_gutter_custom_draw(gutter_idx, this, "_main_gutter_draw_callback");
gutter_idx++;
/* Line numbers */
add_gutter();
set_gutter_name(0, "line_numbers");
set_gutter_draw(0, false);
set_gutter_type(0, GUTTER_TPYE_CUSTOM);
set_gutter_custom_draw(0, this, "_line_number_draw_callback");
set_gutter_name(gutter_idx, "line_numbers");
set_gutter_draw(gutter_idx, false);
set_gutter_type(gutter_idx, GUTTER_TPYE_CUSTOM);
set_gutter_custom_draw(gutter_idx, this, "_line_number_draw_callback");
gutter_idx++;
connect("lines_edited_from", callable_mp(this, &CodeEdit::_lines_edited_from));
connect("gutter_clicked", callable_mp(this, &CodeEdit::_gutter_clicked));

View file

@ -37,7 +37,32 @@ class CodeEdit : public TextEdit {
GDCLASS(CodeEdit, TextEdit)
private:
int cached_line_count = 0;
/* Main Gutter */
enum MainGutterType {
MAIN_GUTTER_BREAKPOINT = 0x01,
MAIN_GUTTER_BOOKMARK = 0x02,
MAIN_GUTTER_EXECUTING = 0x04
};
int main_gutter = -1;
void _update_draw_main_gutter();
void _main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 &p_region);
// breakpoints
HashMap<int, bool> breakpointed_lines;
bool draw_breakpoints = false;
Color breakpoint_color = Color(1, 1, 1);
Ref<Texture2D> breakpoint_icon = Ref<Texture2D>();
// bookmarks
bool draw_bookmarks = false;
Color bookmark_color = Color(1, 1, 1);
Ref<Texture2D> bookmark_icon = Ref<Texture2D>();
// executing lines
bool draw_executing_lines = false;
Color executing_line_color = Color(1, 1, 1);
Ref<Texture2D> executing_line_icon = Ref<Texture2D>();
/* Line numbers */
int line_number_gutter = -1;
@ -57,6 +82,34 @@ protected:
static void _bind_methods();
public:
/* Main Gutter */
void set_draw_breakpoints_gutter(bool p_draw);
bool is_drawing_breakpoints_gutter() const;
void set_draw_bookmarks_gutter(bool p_draw);
bool is_drawing_bookmarks_gutter() const;
void set_draw_executing_lines_gutter(bool p_draw);
bool is_drawing_executing_lines_gutter() const;
// breakpoints
void set_line_as_breakpoint(int p_line, bool p_breakpointed);
bool is_line_breakpointed(int p_line) const;
void clear_breakpointed_lines();
Array get_breakpointed_lines() const;
// bookmarks
void set_line_as_bookmarked(int p_line, bool p_bookmarked);
bool is_line_bookmarked(int p_line) const;
void clear_bookmarked_lines();
Array get_bookmarked_lines() const;
// executing lines
void set_line_as_executing(int p_line, bool p_executing);
bool is_line_executing(int p_line) const;
void clear_executing_lines();
Array get_executing_lines() const;
/* Line numbers */
void set_draw_line_numbers(bool p_draw);
bool is_draw_line_numbers_enabled() const;

View file

@ -203,8 +203,6 @@ void TextEdit::Text::insert(int p_at, const String &p_text) {
line.gutters.resize(gutter_count);
line.marked = false;
line.safe = false;
line.breakpoint = false;
line.bookmark = false;
line.hidden = false;
line.has_info = false;
line.width_cache = -1;
@ -280,10 +278,6 @@ void TextEdit::_update_scrollbars() {
int visible_width = size.width - cache.style_normal->get_minimum_size().width;
int total_width = text.get_max_width(true) + vmin.x + gutters_width + gutter_padding;
if (draw_breakpoint_gutter || draw_bookmark_gutter) {
total_width += cache.breakpoint_gutter_width;
}
if (draw_info_gutter) {
total_width += cache.info_gutter_width;
}
@ -582,13 +576,6 @@ void TextEdit::_notification(int p_what) {
draw_caret = false;
}
if (draw_breakpoint_gutter || draw_bookmark_gutter) {
breakpoint_gutter_width = (get_row_height() * 55) / 100;
cache.breakpoint_gutter_width = breakpoint_gutter_width;
} else {
cache.breakpoint_gutter_width = 0;
}
if (draw_info_gutter) {
info_gutter_width = (get_row_height());
cache.info_gutter_width = info_gutter_width;
@ -612,7 +599,7 @@ void TextEdit::_notification(int p_what) {
RID ci = get_canvas_item();
RenderingServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), true);
int xmargin_beg = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width;
int xmargin_beg = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding + cache.fold_gutter_width + cache.info_gutter_width;
int xmargin_end = size.width - cache.style_normal->get_margin(MARGIN_RIGHT) - cache.minimap_width;
// Let's do it easy for now.
@ -1107,41 +1094,11 @@ void TextEdit::_notification(int p_what) {
gutter_offset += gutter.width;
}
if (text.is_breakpoint(line) && !draw_breakpoint_gutter) {
#ifdef TOOLS_ENABLED
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y + get_row_height() - EDSCALE, xmargin_end - xmargin_beg, EDSCALE), cache.breakpoint_color);
#else
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - xmargin_beg, get_row_height()), cache.breakpoint_color);
#endif
}
// Draw bookmark marker.
if (text.is_bookmark(line)) {
if (draw_bookmark_gutter) {
int vertical_gap = (get_row_height() * 40) / 100;
int horizontal_gap = (cache.breakpoint_gutter_width * 30) / 100;
int marker_radius = get_row_height() - (vertical_gap * 2);
RenderingServer::get_singleton()->canvas_item_add_circle(ci, Point2(cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + horizontal_gap - 2 + marker_radius / 2, ofs_y + vertical_gap + marker_radius / 2), marker_radius, Color(cache.bookmark_color.r, cache.bookmark_color.g, cache.bookmark_color.b));
}
}
// Draw breakpoint marker.
if (text.is_breakpoint(line)) {
if (draw_breakpoint_gutter) {
int vertical_gap = (get_row_height() * 40) / 100;
int horizontal_gap = (cache.breakpoint_gutter_width * 30) / 100;
int marker_height = get_row_height() - (vertical_gap * 2);
int marker_width = cache.breakpoint_gutter_width - (horizontal_gap * 2);
// No transparency on marker.
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + horizontal_gap - 2, ofs_y + vertical_gap, marker_width, marker_height), Color(cache.breakpoint_color.r, cache.breakpoint_color.g, cache.breakpoint_color.b));
}
}
// Draw info icons.
if (draw_info_gutter && text.has_info_icon(line)) {
int vertical_gap = (get_row_height() * 40) / 100;
int horizontal_gap = (cache.info_gutter_width * 30) / 100;
int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + cache.breakpoint_gutter_width;
int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width;
Ref<Texture2D> info_icon = text.get_info_icon(line);
// Ensure the icon fits the gutter size.
@ -1162,28 +1119,10 @@ void TextEdit::_notification(int p_what) {
draw_texture_rect(info_icon, Rect2(icon_pos, icon_size));
}
// Draw execution marker.
if (executing_line == line) {
if (draw_breakpoint_gutter) {
int icon_extra_size = 4;
int vertical_gap = (get_row_height() * 40) / 100;
int horizontal_gap = (cache.breakpoint_gutter_width * 30) / 100;
int marker_height = get_row_height() - (vertical_gap * 2) + icon_extra_size;
int marker_width = cache.breakpoint_gutter_width - (horizontal_gap * 2) + icon_extra_size;
cache.executing_icon->draw_rect(ci, Rect2(cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + horizontal_gap - 2 - icon_extra_size / 2, ofs_y + vertical_gap - icon_extra_size / 2, marker_width, marker_height), false, Color(cache.executing_line_color.r, cache.executing_line_color.g, cache.executing_line_color.b));
} else {
#ifdef TOOLS_ENABLED
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y + get_row_height() - EDSCALE, xmargin_end - xmargin_beg, EDSCALE), cache.executing_line_color);
#else
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - xmargin_beg, get_row_height()), cache.executing_line_color);
#endif
}
}
// Draw fold markers.
if (draw_fold_gutter) {
int horizontal_gap = (cache.fold_gutter_width * 30) / 100;
int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + cache.breakpoint_gutter_width + cache.info_gutter_width;
int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + cache.info_gutter_width;
if (is_folded(line)) {
int xofs = horizontal_gap - (cache.can_fold_icon->get_width()) / 2;
int yofs = (get_row_height() - cache.folded_icon->get_height()) / 2;
@ -1869,12 +1808,6 @@ void TextEdit::backspace_at_cursor() {
if (is_line_hidden(cursor.line)) {
set_line_as_hidden(prev_line, true);
}
if (is_line_set_as_breakpoint(cursor.line)) {
if (!text.is_breakpoint(prev_line)) {
emit_signal("breakpoint_toggled", prev_line);
}
set_line_as_breakpoint(prev_line, true);
}
if (text.has_info_icon(cursor.line)) {
set_line_info_icon(prev_line, text.get_info_icon(cursor.line), text.get_info(cursor.line));
@ -2067,7 +2000,7 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
row = text.size() - 1;
col = text[row].size();
} else {
int colx = p_mouse.x - (cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width);
int colx = p_mouse.x - (cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding + cache.fold_gutter_width + cache.info_gutter_width);
colx += cursor.x_ofs;
col = get_char_pos_for_line(colx, row, wrap_index);
if (is_wrap_enabled() && wrap_index < times_line_wraps(row)) {
@ -2112,7 +2045,7 @@ Vector2i TextEdit::_get_cursor_pixel_pos() {
// Calculate final pixel position
int y = (row - get_v_scroll_offset() + 1 /*Bottom of line*/) * get_row_height();
int x = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width - cursor.x_ofs;
int x = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding + cache.fold_gutter_width + cache.info_gutter_width - cursor.x_ofs;
int ix = 0;
while (ix < rows2[0].size() && ix < cursor.column) {
if (cache.font != nullptr) {
@ -2261,20 +2194,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
left_margin += gutters[i].width;
}
// Toggle breakpoint on gutter click.
if (draw_breakpoint_gutter) {
int gutter = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width;
if (mb->get_position().x > gutter - 6 && mb->get_position().x <= gutter + cache.breakpoint_gutter_width - 3) {
set_line_as_breakpoint(row, !is_line_set_as_breakpoint(row));
emit_signal("breakpoint_toggled", row);
return;
}
}
// Emit info clicked.
if (draw_info_gutter && text.has_info_icon(row)) {
left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
int gutter_left = left_margin + gutters_width + cache.breakpoint_gutter_width;
int gutter_left = left_margin + gutters_width;
if (mb->get_position().x > gutter_left - 6 && mb->get_position().x <= gutter_left + cache.info_gutter_width - 3) {
emit_signal("info_clicked", row, text.get_info(row));
return;
@ -2284,7 +2207,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
// Toggle fold on gutter click if can.
if (draw_fold_gutter) {
left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
int gutter_left = left_margin + gutters_width + cache.breakpoint_gutter_width + cache.info_gutter_width;
int gutter_left = left_margin + gutters_width + cache.info_gutter_width;
if (mb->get_position().x > gutter_left - 6 && mb->get_position().x <= gutter_left + cache.fold_gutter_width - 3) {
if (is_folded(row)) {
unfold_line(row);
@ -2298,7 +2221,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
// Unfold on folded icon click.
if (is_folded(row)) {
int line_width = text.get_line_width(row);
line_width += cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding + cache.breakpoint_gutter_width + cache.info_gutter_width + cache.fold_gutter_width - cursor.x_ofs;
line_width += cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding + cache.info_gutter_width + cache.fold_gutter_width - cursor.x_ofs;
if (mb->get_position().x > line_width - 3 && mb->get_position().x <= line_width + cache.folded_eol_icon->get_width() + 3) {
unfold_line(row);
return;
@ -3858,30 +3781,15 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
Vector<String> substrings = p_text.replace("\r", "").split("\n");
/* STEP 2: Fire breakpoint_toggled signals. */
// Is this just a new empty line?
bool shift_first_line = p_char == 0 && p_text.replace("\r", "") == "\n";
int i = p_line + !shift_first_line;
int lines = substrings.size() - 1;
for (; i < text.size(); i++) {
if (text.is_breakpoint(i)) {
if ((i - lines < p_line || !text.is_breakpoint(i - lines)) || (i - lines == p_line && !shift_first_line)) {
emit_signal("breakpoint_toggled", i);
}
if (i + lines >= text.size() || !text.is_breakpoint(i + lines)) {
emit_signal("breakpoint_toggled", i + lines);
}
}
}
/* STEP 3: Add spaces if the char is greater than the end of the line. */
/* STEP 2: Add spaces if the char is greater than the end of the line. */
while (p_char > text[p_line].length()) {
text.set(p_line, text[p_line] + String::chr(' '));
}
/* STEP 4: Separate dest string in pre and post text. */
/* STEP 3: Separate dest string in pre and post text. */
String preinsert_text = text[p_line].substr(0, p_char);
String postinsert_text = text[p_line].substr(p_char, text[p_line].size());
@ -3902,13 +3810,11 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
if (shift_first_line) {
text.move_gutters(p_line, p_line + 1);
text.set_breakpoint(p_line + 1, text.is_breakpoint(p_line));
text.set_hidden(p_line + 1, text.is_hidden(p_line));
if (text.has_info_icon(p_line)) {
text.set_info_icon(p_line + 1, text.get_info_icon(p_line), text.get_info(p_line));
}
text.set_breakpoint(p_line, false);
text.set_hidden(p_line, false);
text.set_info_icon(p_line, nullptr, "");
}
@ -3961,19 +3867,6 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
String pre_text = text[p_from_line].substr(0, p_from_column);
String post_text = text[p_to_line].substr(p_to_column, text[p_to_line].length());
int lines = p_to_line - p_from_line;
for (int i = p_from_line + 1; i < text.size(); i++) {
if (text.is_breakpoint(i)) {
if (i + lines >= text.size() || !text.is_breakpoint(i + lines)) {
emit_signal("breakpoint_toggled", i);
}
if (i > p_to_line && (i - lines < 0 || !text.is_breakpoint(i - lines))) {
emit_signal("breakpoint_toggled", i - lines);
}
}
}
for (int i = p_from_line; i < p_to_line; i++) {
text.remove(p_from_line + 1);
}
@ -4181,7 +4074,7 @@ int TextEdit::get_total_visible_rows() const {
}
void TextEdit::_update_wrap_at() {
wrap_at = get_size().width - cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width - wrap_right_offset;
wrap_at = get_size().width - cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width - wrap_right_offset;
update_cursor_wrap_offset();
text.clear_wrap_cache();
@ -4216,7 +4109,7 @@ void TextEdit::adjust_viewport_to_cursor() {
set_line_as_last_visible(cur_line, cur_wrap);
}
int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width;
int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width;
if (v_scroll->is_visible_in_tree()) {
visible_width -= v_scroll->get_combined_minimum_size().width;
}
@ -4251,7 +4144,7 @@ void TextEdit::center_viewport_to_cursor() {
}
set_line_as_center_visible(cursor.line, get_cursor_wrap_index());
int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width;
int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - gutters_width - gutter_padding - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width;
if (v_scroll->is_visible_in_tree()) {
visible_width -= v_scroll->get_combined_minimum_size().width;
}
@ -4698,7 +4591,7 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
return CURSOR_POINTING_HAND;
}
int gutter = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width;
int gutter = cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + cache.fold_gutter_width + cache.info_gutter_width;
if ((completion_active && completion_rect.has_point(p_pos))) {
return CURSOR_ARROW;
}
@ -4722,14 +4615,9 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
left_margin += gutters_width;
// Breakpoint icon.
if (draw_breakpoint_gutter && p_pos.x > left_margin - 6 && p_pos.x <= left_margin + cache.breakpoint_gutter_width - 3) {
return CURSOR_POINTING_HAND;
}
// Info icons.
int gutter_left = left_margin + cache.breakpoint_gutter_width + cache.info_gutter_width;
if (draw_info_gutter && p_pos.x > left_margin + cache.breakpoint_gutter_width - 6 && p_pos.x <= gutter_left - 3) {
int gutter_left = left_margin + cache.info_gutter_width;
if (draw_info_gutter && p_pos.x > left_margin - 6 && p_pos.x <= gutter_left - 3) {
if (text.has_info_icon(row)) {
return CURSOR_POINTING_HAND;
}
@ -4757,7 +4645,7 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
// EOL fold icon.
if (is_folded(row)) {
int line_width = text.get_line_width(row);
line_width += cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width - cursor.x_ofs;
line_width += cache.style_normal->get_margin(MARGIN_LEFT) + gutters_width + gutter_padding + cache.fold_gutter_width + cache.info_gutter_width - cursor.x_ofs;
if (p_pos.x > line_width - 3 && p_pos.x <= line_width + cache.folded_eol_icon->get_width() + 3) {
return CURSOR_POINTING_HAND;
}
@ -4968,9 +4856,6 @@ void TextEdit::_update_caches() {
cache.mark_color = get_theme_color("mark_color");
cache.current_line_color = get_theme_color("current_line_color");
cache.line_length_guideline_color = get_theme_color("line_length_guideline_color");
cache.bookmark_color = get_theme_color("bookmark_color");
cache.breakpoint_color = get_theme_color("breakpoint_color");
cache.executing_line_color = get_theme_color("executing_line_color");
cache.code_folding_color = get_theme_color("code_folding_color");
cache.brace_mismatch_color = get_theme_color("brace_mismatch_color");
cache.word_highlighted_color = get_theme_color("word_highlighted_color");
@ -4988,7 +4873,6 @@ void TextEdit::_update_caches() {
cache.folded_icon = get_theme_icon("folded");
cache.can_fold_icon = get_theme_icon("fold");
cache.folded_eol_icon = get_theme_icon("GuiEllipsis", "EditorIcons");
cache.executing_icon = get_theme_icon("MainPlay", "EditorIcons");
text.set_font(cache.font);
text.clear_width_cache();
@ -5632,84 +5516,6 @@ bool TextEdit::is_line_set_as_safe(int p_line) const {
return text.is_safe(p_line);
}
void TextEdit::set_executing_line(int p_line) {
ERR_FAIL_INDEX(p_line, text.size());
executing_line = p_line;
update();
}
void TextEdit::clear_executing_line() {
executing_line = -1;
update();
}
bool TextEdit::is_line_set_as_bookmark(int p_line) const {
ERR_FAIL_INDEX_V(p_line, text.size(), false);
return text.is_bookmark(p_line);
}
void TextEdit::set_line_as_bookmark(int p_line, bool p_bookmark) {
ERR_FAIL_INDEX(p_line, text.size());
text.set_bookmark(p_line, p_bookmark);
update();
}
void TextEdit::get_bookmarks(List<int> *p_bookmarks) const {
for (int i = 0; i < text.size(); i++) {
if (text.is_bookmark(i)) {
p_bookmarks->push_back(i);
}
}
}
Array TextEdit::get_bookmarks_array() const {
Array arr;
for (int i = 0; i < text.size(); i++) {
if (text.is_bookmark(i)) {
arr.append(i);
}
}
return arr;
}
bool TextEdit::is_line_set_as_breakpoint(int p_line) const {
ERR_FAIL_INDEX_V(p_line, text.size(), false);
return text.is_breakpoint(p_line);
}
void TextEdit::set_line_as_breakpoint(int p_line, bool p_breakpoint) {
ERR_FAIL_INDEX(p_line, text.size());
text.set_breakpoint(p_line, p_breakpoint);
update();
}
void TextEdit::get_breakpoints(List<int> *p_breakpoints) const {
for (int i = 0; i < text.size(); i++) {
if (text.is_breakpoint(i)) {
p_breakpoints->push_back(i);
}
}
}
Array TextEdit::get_breakpoints_array() const {
Array arr;
for (int i = 0; i < text.size(); i++) {
if (text.is_breakpoint(i)) {
arr.append(i);
}
}
return arr;
}
void TextEdit::remove_breakpoints() {
for (int i = 0; i < text.size(); i++) {
if (text.is_breakpoint(i)) {
/* Should "breakpoint_toggled" be fired when breakpoints are removed this way? */
text.set_breakpoint(i, false);
}
}
}
void TextEdit::set_line_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info) {
ERR_FAIL_INDEX(p_line, text.size());
text.set_info_icon(p_line, p_icon, p_info);
@ -6797,33 +6603,6 @@ void TextEdit::set_line_length_guideline_hard_column(int p_column) {
update();
}
void TextEdit::set_bookmark_gutter_enabled(bool p_draw) {
draw_bookmark_gutter = p_draw;
update();
}
bool TextEdit::is_bookmark_gutter_enabled() const {
return draw_bookmark_gutter;
}
void TextEdit::set_breakpoint_gutter_enabled(bool p_draw) {
draw_breakpoint_gutter = p_draw;
update();
}
bool TextEdit::is_breakpoint_gutter_enabled() const {
return draw_breakpoint_gutter;
}
void TextEdit::set_breakpoint_gutter_width(int p_gutter_width) {
breakpoint_gutter_width = p_gutter_width;
update();
}
int TextEdit::get_breakpoint_gutter_width() const {
return cache.breakpoint_gutter_width;
}
void TextEdit::set_draw_fold_gutter(bool p_draw) {
draw_fold_gutter = p_draw;
update();
@ -7070,8 +6849,6 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_drawing_tabs"), &TextEdit::is_drawing_tabs);
ClassDB::bind_method(D_METHOD("set_draw_spaces"), &TextEdit::set_draw_spaces);
ClassDB::bind_method(D_METHOD("is_drawing_spaces"), &TextEdit::is_drawing_spaces);
ClassDB::bind_method(D_METHOD("set_breakpoint_gutter_enabled", "enable"), &TextEdit::set_breakpoint_gutter_enabled);
ClassDB::bind_method(D_METHOD("is_breakpoint_gutter_enabled"), &TextEdit::is_breakpoint_gutter_enabled);
ClassDB::bind_method(D_METHOD("set_draw_fold_gutter"), &TextEdit::set_draw_fold_gutter);
ClassDB::bind_method(D_METHOD("is_drawing_fold_gutter"), &TextEdit::is_drawing_fold_gutter);
@ -7145,9 +6922,6 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("menu_option", "option"), &TextEdit::menu_option);
ClassDB::bind_method(D_METHOD("get_menu"), &TextEdit::get_menu);
ClassDB::bind_method(D_METHOD("get_breakpoints"), &TextEdit::get_breakpoints_array);
ClassDB::bind_method(D_METHOD("remove_breakpoints"), &TextEdit::remove_breakpoints);
ClassDB::bind_method(D_METHOD("draw_minimap", "draw"), &TextEdit::set_draw_minimap);
ClassDB::bind_method(D_METHOD("is_drawing_minimap"), &TextEdit::is_drawing_minimap);
ClassDB::bind_method(D_METHOD("set_minimap_width", "width"), &TextEdit::set_minimap_width);
@ -7158,7 +6932,6 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_current_line"), "set_highlight_current_line", "is_highlight_current_line_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_tabs"), "set_draw_tabs", "is_drawing_tabs");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_spaces"), "set_draw_spaces", "is_drawing_spaces");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "breakpoint_gutter"), "set_breakpoint_gutter_enabled", "is_breakpoint_gutter_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fold_gutter"), "set_draw_fold_gutter", "is_drawing_fold_gutter");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color");
@ -7192,7 +6965,6 @@ void TextEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("gutter_clicked", PropertyInfo(Variant::INT, "line"), PropertyInfo(Variant::INT, "gutter")));
ADD_SIGNAL(MethodInfo("gutter_added"));
ADD_SIGNAL(MethodInfo("gutter_removed"));
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")));
ADD_SIGNAL(MethodInfo("info_clicked", PropertyInfo(Variant::INT, "row"), PropertyInfo(Variant::STRING, "info")));
ADD_SIGNAL(MethodInfo("symbol_validate", PropertyInfo(Variant::STRING, "symbol")));
@ -7227,8 +6999,6 @@ TextEdit::TextEdit() {
_update_caches();
cache.row_height = 1;
cache.line_spacing = 1;
cache.breakpoint_gutter_width = 0;
breakpoint_gutter_width = 0;
cache.fold_gutter_width = 0;
fold_gutter_width = 0;
info_gutter_width = 0;
@ -7299,8 +7069,6 @@ TextEdit::TextEdit() {
line_length_guidelines = false;
line_length_guideline_soft_col = 80;
line_length_guideline_hard_col = 100;
draw_bookmark_gutter = false;
draw_breakpoint_gutter = false;
draw_fold_gutter = false;
draw_info_gutter = false;
hiding_enabled = false;
@ -7340,8 +7108,6 @@ TextEdit::TextEdit() {
set_readonly(false);
menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
first_draw = true;
executing_line = -1;
}
TextEdit::~TextEdit() {

View file

@ -81,8 +81,6 @@ private:
int width_cache : 24;
bool marked : 1;
bool breakpoint : 1;
bool bookmark : 1;
bool hidden : 1;
bool safe : 1;
bool has_info : 1;
@ -93,8 +91,6 @@ private:
Line() {
width_cache = 0;
marked = false;
breakpoint = false;
bookmark = false;
hidden = false;
safe = false;
has_info = false;
@ -121,10 +117,6 @@ private:
void set(int p_line, const String &p_text);
void set_marked(int p_line, bool p_marked) { text.write[p_line].marked = p_marked; }
bool is_marked(int p_line) const { return text[p_line].marked; }
void set_bookmark(int p_line, bool p_bookmark) { text.write[p_line].bookmark = p_bookmark; }
bool is_bookmark(int p_line) const { return text[p_line].bookmark; }
void set_breakpoint(int p_line, bool p_breakpoint) { text.write[p_line].breakpoint = p_breakpoint; }
bool is_breakpoint(int p_line) const { return text[p_line].breakpoint; }
void set_hidden(int p_line, bool p_hidden) { text.write[p_line].hidden = p_hidden; }
bool is_hidden(int p_line) const { return text[p_line].hidden; }
void set_safe(int p_line, bool p_safe) { text.write[p_line].safe = p_safe; }
@ -321,9 +313,6 @@ private:
bool line_length_guidelines;
int line_length_guideline_soft_col;
int line_length_guideline_hard_col;
bool draw_bookmark_gutter;
bool draw_breakpoint_gutter;
int breakpoint_gutter_width;
bool draw_fold_gutter;
int fold_gutter_width;
bool hiding_enabled;
@ -383,11 +372,8 @@ private:
bool context_menu_enabled;
bool shortcut_keys_enabled;
bool virtual_keyboard_enabled = true;
int executing_line;
void _generate_context_menu();
int get_visible_rows() const;
@ -484,7 +470,6 @@ protected:
Ref<Texture2D> can_fold_icon;
Ref<Texture2D> folded_icon;
Ref<Texture2D> folded_eol_icon;
Ref<Texture2D> executing_icon;
Ref<StyleBox> style_normal;
Ref<StyleBox> style_focus;
Ref<StyleBox> style_readonly;
@ -501,9 +486,6 @@ protected:
Color font_color_readonly;
Color selection_color;
Color mark_color;
Color bookmark_color;
Color breakpoint_color;
Color executing_line_color;
Color code_folding_color;
Color current_line_color;
Color line_length_guideline_color;
@ -515,14 +497,12 @@ protected:
int row_height;
int line_spacing;
int breakpoint_gutter_width;
int fold_gutter_width;
int info_gutter_width;
int minimap_width;
Cache() {
row_height = 0;
line_spacing = 0;
breakpoint_gutter_width = 0;
fold_gutter_width = 0;
info_gutter_width = 0;
minimap_width = 0;
@ -625,19 +605,8 @@ public:
void insert_at(const String &p_text, int at);
int get_line_count() const;
void set_line_as_marked(int p_line, bool p_marked);
void set_line_as_bookmark(int p_line, bool p_bookmark);
bool is_line_set_as_bookmark(int p_line) const;
void get_bookmarks(List<int> *p_bookmarks) const;
Array get_bookmarks_array() const;
void set_line_as_breakpoint(int p_line, bool p_breakpoint);
bool is_line_set_as_breakpoint(int p_line) const;
void set_executing_line(int p_line);
void clear_executing_line();
void set_line_as_safe(int p_line, bool p_safe);
bool is_line_set_as_safe(int p_line) const;
void get_breakpoints(List<int> *p_breakpoints) const;
Array get_breakpoints_array() const;
void remove_breakpoints();
void set_line_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info = "");
void clear_info_icons();
@ -788,15 +757,6 @@ public:
void set_line_length_guideline_soft_column(int p_column);
void set_line_length_guideline_hard_column(int p_column);
void set_bookmark_gutter_enabled(bool p_draw);
bool is_bookmark_gutter_enabled() const;
void set_breakpoint_gutter_enabled(bool p_draw);
bool is_breakpoint_gutter_enabled() const;
void set_breakpoint_gutter_width(int p_gutter_width);
int get_breakpoint_gutter_width() const;
void set_draw_fold_gutter(bool p_draw);
bool is_drawing_fold_gutter() const;

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

View file

@ -419,9 +419,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("tab", "CodeEdit", make_icon(tab_png));
theme->set_icon("space", "CodeEdit", make_icon(space_png));
theme->set_icon("breakpoint", "CodeEdit", make_icon(graph_port_png));
theme->set_icon("bookmark", "CodeEdit", make_icon(bookmark_png));
theme->set_icon("executing_line", "CodeEdit", make_icon(arrow_right_png));
theme->set_icon("folded", "CodeEdit", make_icon(arrow_right_png));
theme->set_icon("fold", "CodeEdit", make_icon(arrow_down_png));
theme->set_font("font", "CodeEdit", Ref<Font>());
theme->set_color("background_color", "CodeEdit", Color(0, 0, 0, 0));
@ -435,9 +437,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_color_readonly", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
theme->set_color("selection_color", "CodeEdit", font_color_selection);
theme->set_color("mark_color", "CodeEdit", Color(1.0, 0.4, 0.4, 0.4));
theme->set_color("bookmark_color", "CodeEdit", Color(0.08, 0.49, 0.98));
theme->set_color("breakpoint_color", "CodeEdit", Color(0.8, 0.8, 0.4, 0.2));
theme->set_color("executing_line_color", "CodeEdit", Color(0.2, 0.8, 0.2, 0.4));
theme->set_color("bookmark_color", "CodeEdit", Color(0.5, 0.64, 1, 0.8));
theme->set_color("breakpoint_color", "CodeEdit", Color(0.9, 0.29, 0.3));
theme->set_color("executing_line_color", "CodeEdit", Color(0.98, 0.89, 0.27));
theme->set_color("code_folding_color", "CodeEdit", Color(0.8, 0.8, 0.8, 0.8));
theme->set_color("current_line_color", "CodeEdit", Color(0.25, 0.25, 0.26, 0.8));
theme->set_color("caret_color", "CodeEdit", control_font_color);

View file

@ -10,6 +10,10 @@ static const unsigned char arrow_right_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x17, 0x3c, 0xf8, 0xf, 0x82, 0xf7, 0x13, 0x70, 0x48, 0x3c, 0xf8, 0xf2, 0x50, 0x1b, 0x43, 0x2, 0xa, 0xaf, 0xbe, 0xe0, 0xc6, 0x2e, 0xf1, 0xff, 0xe1, 0x7c, 0x12, 0x24, 0x10, 0x46, 0x11, 0xb6, 0x1c, 0xe1, 0x5c, 0xa, 0x0, 0x0, 0xe0, 0x14, 0x48, 0xb1, 0x3d, 0x1b, 0x7a, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char bookmark_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x57, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0xa, 0xc0, 0x30, 0xc, 0x3, 0xa5, 0xd0, 0xff, 0x7f, 0x59, 0x1d, 0x8a, 0x42, 0x8, 0x9, 0x95, 0xc9, 0xd2, 0xa1, 0x9a, 0x8c, 0xf1, 0xdd, 0x62, 0x1b, 0x38, 0xc, 0x87, 0x5a, 0x5, 0xae, 0x79, 0xde, 0x2, 0x1, 0x80, 0x94, 0x39, 0x48, 0x76, 0x49, 0x17, 0xa4, 0xf0, 0x24, 0x61, 0x2b, 0x51, 0x8b, 0xfc, 0x82, 0xcf, 0xb, 0x48, 0x7a, 0xdf, 0x75, 0x81, 0xf, 0xe5, 0x29, 0xf7, 0x92, 0x6b, 0x3, 0x1a, 0x1e, 0xda, 0x7c, 0x3d, 0x77, 0x21, 0x7b, 0xa8, 0x74, 0x2e, 0xcb, 0xd, 0xc8, 0x75, 0x13, 0x28, 0x9, 0xed, 0xc2, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char button_disabled_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xc7, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0xd0, 0x81, 0x66, 0x43, 0x31, 0x14, 0x87, 0xf1, 0xf, 0x5, 0x17, 0xb8, 0x28, 0x2e, 0x8, 0x71, 0xf3, 0x6, 0x19, 0xb6, 0xb9, 0xcb, 0xac, 0x95, 0xa4, 0xb7, 0xad, 0x6a, 0xd5, 0x68, 0x5f, 0xe4, 0x3e, 0x76, 0x1e, 0xe1, 0xbf, 0x21, 0xa6, 0xab, 0xf8, 0x1, 0x7c, 0x9c, 0x73, 0xe, 0xac, 0xe8, 0xe8, 0x19, 0x30, 0x58, 0xc6, 0xca, 0x62, 0x18, 0xe8, 0xe9, 0x58, 0x41, 0xc7, 0x1a, 0x87, 0x27, 0x10, 0x49, 0xe4, 0x5f, 0x89, 0x48, 0xc0, 0xe3, 0x58, 0xd3, 0x41, 0x8f, 0xb, 0xcb, 0xbd, 0x7c, 0xeb, 0xbf, 0x7b, 0x9, 0xb, 0x8e, 0x1e, 0x6, 0xfc, 0xad, 0x64, 0x6d, 0xb5, 0x79, 0xb0, 0x55, 0xd6, 0xad, 0xe0, 0x19, 0xc0, 0x10, 0xae, 0xda, 0x34, 0x5c, 0x45, 0xc0, 0x80, 0x25, 0x5e, 0xf4, 0xd5, 0x70, 0x11, 0x11, 0xb, 0x23, 0xe9, 0xac, 0xcf, 0x86, 0xb3, 0x48, 0x8c, 0x30, 0x92, 0x4f, 0xa, 0xd, 0x27, 0x91, 0x6b, 0x70, 0xd4, 0x47, 0xc3, 0xf1, 0x2f, 0x48, 0x7, 0x4d, 0xd, 0x87, 0x3a, 0xc2, 0x12, 0x67, 0xbd, 0x37, 0xcc, 0x75, 0x49, 0x43, 0xd8, 0xe9, 0xad, 0x61, 0x57, 0xcf, 0x1c, 0xf0, 0xfb, 0x32, 0xe9, 0xf5, 0xc9, 0xa4, 0x7d, 0x7d, 0x54, 0x8f, 0x7b, 0x59, 0xe6, 0x92, 0x14, 0x1f, 0x24, 0xcd, 0x3f, 0x7b, 0x6b, 0xa, 0xe, 0x6a, 0x82, 0x91, 0x45, 0x30, 0xba, 0x1, 0x4a, 0x51, 0xc4, 0x35, 0x1f, 0xe5, 0xa1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};