godot-xterm/addons/gut/gui/OutputText.gd

304 lines
7 KiB
GDScript
Raw Normal View History

extends VBoxContainer
@tool
class SearchResults:
var L = 0
var C = 0
var positions = []
var te = null
var _last_term = ''
func _search_te(text, start_position, flags=0):
var start_pos = start_position
if(start_pos[L] < 0 or start_pos[L] > te.get_line_count()):
start_pos[L] = 0
if(start_pos[C] < 0):
start_pos[L] = 0
var result = te.search(text, flags, start_pos[L], start_pos[C])
if(result.size() == 2 and result[L] == start_position[L] and
result[C] == start_position[C] and text == _last_term):
if(flags == TextEdit.SEARCH_BACKWARDS):
result[C] -= 1
else:
result[C] += 1
result = _search_te(text, result, flags)
L = result.y
C = result.x
elif(result.size() == 2):
te.scroll_vertical = result[L]
te.select(result[L], result[C], result[L], result[C] + text.length())
te.set_caret_column(result[C])
te.set_caret_line(result[L])
te.center_viewport_to_caret()
L = result.y
C = result.x
_last_term = text
te.center_viewport_to_caret()
return result
func _cursor_to_pos():
var to_return = [0, 0]
to_return[L] = te.get_caret_line()
to_return[C] = te.get_caret_column()
return to_return
func find_next(term):
return _search_te(term, _cursor_to_pos())
func find_prev(term):
var new_pos = _search_te(term, _cursor_to_pos(), TextEdit.SEARCH_BACKWARDS)
return new_pos
func get_next_pos():
pass
func get_prev_pos():
pass
func clear():
pass
func find_all(text):
var c_pos = [0, 0]
var found = true
var last_pos = [0, 0]
positions.clear()
while(found):
c_pos = te.search(text, 0, c_pos[L], c_pos[C])
if(c_pos.size() > 0 and
(c_pos[L] > last_pos[L] or
(c_pos[L] == last_pos[L] and c_pos[C] > last_pos[C]))):
positions.append([c_pos[L], c_pos[C]])
c_pos[C] += 1
last_pos = c_pos
else:
found = false
@onready var _ctrls = {
output = $Output,
copy_button = $Toolbar/CopyButton,
use_colors = $Toolbar/UseColors,
clear_button = $Toolbar/ClearButton,
word_wrap = $Toolbar/WordWrap,
show_search = $Toolbar/ShowSearch,
search_bar = {
bar = $Search,
search_term = $Search/SearchTerm,
}
}
var _sr = SearchResults.new()
func _test_running_setup():
_ctrls.use_colors.text = 'use colors'
_ctrls.show_search.text = 'search'
_ctrls.word_wrap.text = 'ww'
set_all_fonts("CourierPrime")
set_font_size(20)
load_file('user://.gut_editor.bbcode')
func _ready():
_sr.te = _ctrls.output
_ctrls.use_colors.icon = get_theme_icon('RichTextEffect', 'EditorIcons')
_ctrls.show_search.icon = get_theme_icon('Search', 'EditorIcons')
_ctrls.word_wrap.icon = get_theme_icon('Loop', 'EditorIcons')
_setup_colors()
if(get_parent() == get_tree().root):
_test_running_setup()
# ------------------
# Private
# ------------------
func _setup_colors():
_ctrls.output.clear()
var keywords = [
['Failed', Color.RED],
['Passed', Color.GREEN],
['Pending', Color.YELLOW],
['Orphans', Color.YELLOW],
['WARNING', Color.YELLOW],
['ERROR', Color.RED]
]
for keyword in keywords:
if (_ctrls.output.syntax_highlighter == null) :
_ctrls.output.syntax_highlighter = CodeHighlighter.new()
_ctrls.output.syntax_highlighter.add_keyword_color(keyword[0], keyword[1])
var f_color = null
if (_ctrls.output.theme == null) :
f_color = get_theme_color("font_color")
else :
f_color = _ctrls.output.theme.font_color
_ctrls.output.add_theme_color_override("font_color_readonly", f_color)
_ctrls.output.add_theme_color_override("function_color", f_color)
_ctrls.output.add_theme_color_override("member_variable_color", f_color)
_ctrls.output.queue_redraw()
func _set_font(font_name, custom_name):
var rtl = _ctrls.output
if(font_name == null):
rtl.set('custom_fonts/' + custom_name, null)
else:
pass
# cuasing issues in 4.0
# var dyn_font = FontFile.new()
# var font_data = FontFile.new()
# font_data.font_path = 'res://addons/gut/fonts/' + font_name + '.ttf'
# font_data.antialiased = true
# dyn_font.font_data = font_data
# rtl.set('custom_fonts/' + custom_name, dyn_font)
# ------------------
# Events
# ------------------
func _on_CopyButton_pressed():
copy_to_clipboard()
func _on_UseColors_pressed():
_ctrls.output.syntax_highlighter = _ctrls.use_colors.button_pressed
func _on_ClearButton_pressed():
clear()
func _on_ShowSearch_pressed():
show_search(_ctrls.show_search.button_pressed)
func _on_SearchTerm_focus_entered():
_ctrls.search_bar.search_term.call_deferred('select_all')
func _on_SearchNext_pressed():
_sr.find_next(_ctrls.search_bar.search_term.text)
func _on_SearchPrev_pressed():
_sr.find_prev(_ctrls.search_bar.search_term.text)
func _on_SearchTerm_text_changed(new_text):
if(new_text == ''):
_ctrls.output.deselect()
else:
_sr.find_next(new_text)
func _on_SearchTerm_text_entered(new_text):
if(Input.is_physical_key_pressed(KEY_SHIFT)):
_sr.find_prev(new_text)
else:
_sr.find_next(new_text)
func _on_SearchTerm_gui_input(event):
if(event is InputEventKey and !event.pressed and event.scancode == KEY_ESCAPE):
show_search(false)
func _on_WordWrap_pressed():
_ctrls.output.wrap_enabled = _ctrls.word_wrap.pressed
_ctrls.output.queue_redraw()
# ------------------
# Public
# ------------------
func show_search(should):
_ctrls.search_bar.bar.visible = should
if(should):
_ctrls.search_bar.search_term.grab_focus()
_ctrls.search_bar.search_term.select_all()
_ctrls.show_search.button_pressed = should
func search(text, start_pos, highlight=true):
return _sr.find_next(text)
func copy_to_clipboard():
var selected = _ctrls.output.get_selection_text()
if(selected != ''):
OS.clipboard = selected
else:
OS.clipboard = _ctrls.output.text
func clear():
_ctrls.output.text = ''
func set_all_fonts(base_name):
if(base_name == 'Default'):
_set_font(null, 'font')
# _set_font(null, 'normal_font')
# _set_font(null, 'bold_font')
# _set_font(null, 'italics_font')
# _set_font(null, 'bold_italics_font')
else:
_set_font(base_name + '-Regular', 'font')
# _set_font(base_name + '-Regular', 'normal_font')
# _set_font(base_name + '-Bold', 'bold_font')
# _set_font(base_name + '-Italic', 'italics_font')
# _set_font(base_name + '-BoldItalic', 'bold_italics_font')
func set_font_size(new_size):
var rtl = _ctrls.output
if(rtl.get('custom_fonts/font') != null):
rtl.get('custom_fonts/font').size = new_size
# rtl.get('custom_fonts/bold_italics_font').size = new_size
# rtl.get('custom_fonts/bold_font').size = new_size
# rtl.get('custom_fonts/italics_font').size = new_size
# rtl.get('custom_fonts/normal_font').size = new_size
func set_use_colors(value):
pass
func get_use_colors():
return false;
func get_rich_text_edit():
return _ctrls.output
func load_file(path):
var f = FileAccess.open(path, FileAccess.READ)
if(f == null):
return
var t = f.get_as_text()
f.close()
_ctrls.output.text = t
_ctrls.output.scroll_vertical = _ctrls.output.get_line_count()
_ctrls.output.set_deferred('scroll_vertical', _ctrls.output.get_line_count())
func add_text(text):
if(is_inside_tree()):
_ctrls.output.text += text
func scroll_to_line(line):
_ctrls.output.scroll_vertical = line
_ctrls.output.set_caret_line(line)