summaryrefslogtreecommitdiff
path: root/addons/gut/GutScene.gd
diff options
context:
space:
mode:
Diffstat (limited to 'addons/gut/GutScene.gd')
-rw-r--r--addons/gut/GutScene.gd502
1 files changed, 502 insertions, 0 deletions
diff --git a/addons/gut/GutScene.gd b/addons/gut/GutScene.gd
new file mode 100644
index 0000000..251ab8f
--- /dev/null
+++ b/addons/gut/GutScene.gd
@@ -0,0 +1,502 @@
+extends Panel
+
+onready var _script_list = $ScriptsList
+onready var _nav_container = $VBox/BottomPanel/VBox/HBox/Navigation
+onready var _nav = {
+ container = _nav_container,
+ prev = _nav_container.get_node('VBox/HBox/Previous'),
+ next = _nav_container.get_node('VBox/HBox/Next'),
+ run = _nav_container.get_node('VBox/HBox/Run'),
+ current_script = _nav_container.get_node('VBox/CurrentScript'),
+ run_single = _nav_container.get_node('VBox/HBox/RunSingleScript')
+}
+
+onready var _progress_container = $VBox/BottomPanel/VBox/HBox/Progress
+onready var _progress = {
+ script = _progress_container.get_node("ScriptProgress"),
+ script_xy = _progress_container.get_node("ScriptProgress/xy"),
+ test = _progress_container.get_node("TestProgress"),
+ test_xy = _progress_container.get_node("TestProgress/xy")
+}
+onready var _summary = {
+ control = $VBox/TitleBar/HBox/Summary,
+ failing = $VBox/TitleBar/HBox/Summary/Failing,
+ passing = $VBox/TitleBar/HBox/Summary/Passing,
+ asserts = $VBox/TitleBar/HBox/Summary/AssertCount,
+ fail_count = 0,
+ pass_count = 0
+}
+
+onready var _extras = $ExtraOptions
+onready var _ignore_pauses = $ExtraOptions/IgnorePause
+onready var _continue_button = $VBox/BottomPanel/VBox/HBox/Continue/Continue
+onready var _text_box = $VBox/TextDisplay/RichTextLabel
+onready var _text_box_container = $VBox/TextDisplay
+onready var _log_level_slider = $VBox/BottomPanel/VBox/HBox2/LogLevelSlider
+onready var _resize_handle = $ResizeHandle
+onready var _current_script = $VBox/BottomPanel/VBox/HBox2/CurrentScriptLabel
+onready var _title_replacement = $VBox/TitleBar/HBox/TitleReplacement
+
+onready var _titlebar = {
+ bar = $VBox/TitleBar,
+ time = $VBox/TitleBar/HBox/Time,
+ label = $VBox/TitleBar/HBox/Title
+}
+
+onready var _user_files = $UserFileViewer
+
+var _mouse = {
+ down = false,
+ in_title = false,
+ down_pos = null,
+ in_handle = false
+}
+
+var _is_running = false
+var _start_time = 0.0
+var _time = 0.0
+
+const DEFAULT_TITLE = 'GUT'
+var _pre_maximize_rect = null
+var _font_size = 20
+var _compact_mode = false
+
+var min_sizes = {
+ compact = Vector2(330, 100),
+ full = Vector2(740, 300),
+}
+
+signal end_pause
+signal ignore_pause
+signal log_level_changed
+signal run_script
+signal run_single_script
+
+func _ready():
+ if(Engine.editor_hint):
+ return
+
+ _current_script.text = ''
+ _pre_maximize_rect = get_rect()
+ _hide_scripts()
+ _update_controls()
+ _nav.current_script.set_text("No scripts available")
+ set_title()
+ clear_summary()
+ _titlebar.time.set_text("t: 0.0")
+
+ _extras.visible = false
+ update()
+
+ set_font_size(_font_size)
+ set_font('CourierPrime')
+
+ _user_files.set_position(Vector2(10, 30))
+
+func elapsed_time_as_str():
+ return str("%.1f" % (_time / 1000.0), 's')
+
+func _process(_delta):
+ if(_is_running):
+ _time = OS.get_ticks_msec() - _start_time
+ _titlebar.time.set_text(str('t: ', elapsed_time_as_str()))
+
+func _draw(): # needs get_size()
+ # Draw the lines in the corner to show where you can
+ # drag to resize the dialog
+ var grab_margin = 3
+ var line_space = 3
+ var grab_line_color = Color(.4, .4, .4)
+ if(_resize_handle.visible):
+ for i in range(1, 10):
+ var x = rect_size - Vector2(i * line_space, grab_margin)
+ var y = rect_size - Vector2(grab_margin, i * line_space)
+ draw_line(x, y, grab_line_color, 1, true)
+
+func _on_Maximize_draw():
+ # draw the maximize square thing.
+ var btn = $VBox/TitleBar/HBox/Maximize
+ btn.set_text('')
+ var w = btn.get_size().x
+ var h = btn.get_size().y
+ btn.draw_rect(Rect2(0, 2, w, h -2), Color(0, 0, 0, 1))
+ btn.draw_rect(Rect2(2, 6, w - 4, h - 8), Color(1,1,1,1))
+
+func _on_ShowExtras_draw():
+ var btn = $VBox/BottomPanel/VBox/HBox/Continue/ShowExtras
+ btn.set_text('')
+ var start_x = 20
+ var start_y = 15
+ var pad = 5
+ var color = Color(.1, .1, .1, 1)
+ var width = 2
+ for i in range(3):
+ var y = start_y + pad * i
+ btn.draw_line(Vector2(start_x, y), Vector2(btn.get_size().x - start_x, y), color, width, true)
+
+# ####################
+# GUI Events
+# ####################
+func _on_Run_pressed():
+ _run_mode()
+ emit_signal('run_script', get_selected_index())
+
+func _on_CurrentScript_pressed():
+ _toggle_scripts()
+
+func _on_Previous_pressed():
+ _select_script(get_selected_index() - 1)
+
+func _on_Next_pressed():
+ _select_script(get_selected_index() + 1)
+
+func _on_LogLevelSlider_value_changed(_value):
+ emit_signal('log_level_changed', _log_level_slider.value)
+
+func _on_Continue_pressed():
+ _continue_button.disabled = true
+ emit_signal('end_pause')
+
+func _on_IgnorePause_pressed():
+ var checked = _ignore_pauses.is_pressed()
+ emit_signal('ignore_pause', checked)
+ if(checked):
+ emit_signal('end_pause')
+ _continue_button.disabled = true
+
+func _on_RunSingleScript_pressed():
+ _run_mode()
+ emit_signal('run_single_script', get_selected_index())
+
+func _on_ScriptsList_item_selected(index):
+ var tmr = $ScriptsList/DoubleClickTimer
+ if(!tmr.is_stopped()):
+ _run_mode()
+ emit_signal('run_single_script', get_selected_index())
+ tmr.stop()
+ else:
+ tmr.start()
+
+ _select_script(index)
+
+func _on_TitleBar_mouse_entered():
+ _mouse.in_title = true
+
+func _on_TitleBar_mouse_exited():
+ _mouse.in_title = false
+
+func _input(event):
+ if(event is InputEventMouseButton):
+ if(event.button_index == 1):
+ _mouse.down = event.pressed
+ if(_mouse.down):
+ _mouse.down_pos = event.position
+
+ if(_mouse.in_title):
+ if(event is InputEventMouseMotion and _mouse.down):
+ set_position(get_position() + (event.position - _mouse.down_pos))
+ _mouse.down_pos = event.position
+ _pre_maximize_rect = get_rect()
+
+ if(_mouse.in_handle):
+ if(event is InputEventMouseMotion and _mouse.down):
+ var new_size = rect_size + event.position - _mouse.down_pos
+ var new_mouse_down_pos = event.position
+ rect_size = new_size
+ _mouse.down_pos = new_mouse_down_pos
+ _pre_maximize_rect = get_rect()
+
+func _on_ResizeHandle_mouse_entered():
+ _mouse.in_handle = true
+
+func _on_ResizeHandle_mouse_exited():
+ _mouse.in_handle = false
+
+func _on_RichTextLabel_gui_input(ev):
+ pass
+ # leaving this b/c it is wired up and might have to send
+ # more signals through
+
+func _on_Copy_pressed():
+ OS.clipboard = _text_box.text
+
+func _on_ShowExtras_toggled(button_pressed):
+ _extras.visible = button_pressed
+
+func _on_Maximize_pressed():
+ if(get_rect() == _pre_maximize_rect):
+ compact_mode(false)
+ maximize()
+ else:
+ compact_mode(false)
+ rect_size = _pre_maximize_rect.size
+ rect_position = _pre_maximize_rect.position
+func _on_Minimize_pressed():
+
+ compact_mode(!_compact_mode)
+
+
+func _on_Minimize_draw():
+ # draw the maximize square thing.
+ var btn = $VBox/TitleBar/HBox/Minimize
+ btn.set_text('')
+ var w = btn.get_size().x
+ var h = btn.get_size().y
+ btn.draw_rect(Rect2(0, h-3, w, 3), Color(0, 0, 0, 1))
+
+func _on_UserFiles_pressed():
+ _user_files.show_open()
+
+
+# ####################
+# Private
+# ####################
+func _run_mode(is_running=true):
+ if(is_running):
+ _start_time = OS.get_ticks_msec()
+ _time = 0.0
+ clear_summary()
+ _is_running = is_running
+
+ _hide_scripts()
+ _nav.prev.disabled = is_running
+ _nav.next.disabled = is_running
+ _nav.run.disabled = is_running
+ _nav.current_script.disabled = is_running
+ _nav.run_single.disabled = is_running
+
+func _select_script(index):
+ var text = _script_list.get_item_text(index)
+ var max_len = 50
+ if(text.length() > max_len):
+ text = '...' + text.right(text.length() - (max_len - 5))
+ _nav.current_script.set_text(text)
+ _script_list.select(index)
+ _update_controls()
+
+func _toggle_scripts():
+ if(_script_list.visible):
+ _hide_scripts()
+ else:
+ _show_scripts()
+
+func _show_scripts():
+ _script_list.show()
+
+func _hide_scripts():
+ _script_list.hide()
+
+func _update_controls():
+ var is_empty = _script_list.get_selected_items().size() == 0
+ if(is_empty):
+ _nav.next.disabled = true
+ _nav.prev.disabled = true
+ else:
+ var index = get_selected_index()
+ _nav.prev.disabled = index <= 0
+ _nav.next.disabled = index >= _script_list.get_item_count() - 1
+
+ _nav.run.disabled = is_empty
+ _nav.current_script.disabled = is_empty
+ _nav.run_single.disabled = is_empty
+
+func _update_summary():
+ if(!_summary):
+ return
+
+ var total = _summary.fail_count + _summary.pass_count
+ _summary.control.visible = !total == 0
+ _summary.asserts.text = str('Failures ', _summary.fail_count, '/', total)
+# ####################
+# Public
+# ####################
+func run_mode(is_running=true):
+ _run_mode(is_running)
+
+func set_scripts(scripts):
+ _script_list.clear()
+ for i in range(scripts.size()):
+ _script_list.add_item(scripts[i])
+ _select_script(0)
+ _update_controls()
+
+func select_script(index):
+ _select_script(index)
+
+func get_selected_index():
+ return _script_list.get_selected_items()[0]
+
+func get_log_level():
+ return _log_level_slider.value
+
+func set_log_level(value):
+ var new_value = value
+ if(new_value == null):
+ new_value = 0
+ # !! For some reason, _log_level_slider was null, but this wasn't, so
+ # here's another hardcoded node path.
+ $VBox/BottomPanel/VBox/HBox2/LogLevelSlider.value = new_value
+
+func set_ignore_pause(should):
+ _ignore_pauses.pressed = should
+
+func get_ignore_pause():
+ return _ignore_pauses.pressed
+
+func get_text_box():
+ # due to some timing issue, this cannot return _text_box but can return
+ # this.
+ return $VBox/TextDisplay/RichTextLabel
+
+func end_run():
+ _run_mode(false)
+ _update_controls()
+
+func set_progress_script_max(value):
+ var max_val = max(value, 1)
+ _progress.script.set_max(max_val)
+ _progress.script_xy.set_text(str('0/', max_val))
+
+func set_progress_script_value(value):
+ _progress.script.set_value(value)
+ var txt = str(value, '/', _progress.test.get_max())
+ _progress.script_xy.set_text(txt)
+
+func set_progress_test_max(value):
+ var max_val = max(value, 1)
+ _progress.test.set_max(max_val)
+ _progress.test_xy.set_text(str('0/', max_val))
+
+func set_progress_test_value(value):
+ _progress.test.set_value(value)
+ var txt = str(value, '/', _progress.test.get_max())
+ _progress.test_xy.set_text(txt)
+
+func clear_progress():
+ _progress.test.set_value(0)
+ _progress.script.set_value(0)
+
+func pause():
+ _continue_button.disabled = false
+
+func set_title(title=null):
+ if(title == null):
+ _titlebar.label.set_text(DEFAULT_TITLE)
+ else:
+ _titlebar.label.set_text(title)
+
+func add_passing(amount=1):
+ if(!_summary):
+ return
+ _summary.pass_count += amount
+ _update_summary()
+
+func add_failing(amount=1):
+ if(!_summary):
+ return
+ _summary.fail_count += amount
+ _update_summary()
+
+func clear_summary():
+ _summary.fail_count = 0
+ _summary.pass_count = 0
+ _update_summary()
+
+func maximize():
+ if(is_inside_tree()):
+ var vp_size_offset = get_tree().root.get_viewport().get_visible_rect().size
+ rect_size = vp_size_offset / get_scale()
+ set_position(Vector2(0, 0))
+
+func clear_text():
+ _text_box.bbcode_text = ''
+
+func scroll_to_bottom():
+ pass
+ #_text_box.cursor_set_line(_gui.get_text_box().get_line_count())
+
+func _set_font_size_for_rtl(rtl, new_size):
+ if(rtl.get('custom_fonts/normal_font') != null):
+ 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_fonts_for_rtl(rtl, base_font_name):
+ pass
+
+
+func set_font_size(new_size):
+ _font_size = new_size
+ _set_font_size_for_rtl(_text_box, new_size)
+ _set_font_size_for_rtl(_user_files.get_rich_text_label(), new_size)
+
+
+func _set_font(rtl, font_name, custom_name):
+ if(font_name == null):
+ rtl.set('custom_fonts/' + custom_name, null)
+ else:
+ var dyn_font = DynamicFont.new()
+ var font_data = DynamicFontData.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)
+
+func _set_all_fonts_in_ftl(ftl, base_name):
+ if(base_name == 'Default'):
+ _set_font(ftl, null, 'normal_font')
+ _set_font(ftl, null, 'bold_font')
+ _set_font(ftl, null, 'italics_font')
+ _set_font(ftl, null, 'bold_italics_font')
+ else:
+ _set_font(ftl, base_name + '-Regular', 'normal_font')
+ _set_font(ftl, base_name + '-Bold', 'bold_font')
+ _set_font(ftl, base_name + '-Italic', 'italics_font')
+ _set_font(ftl, base_name + '-BoldItalic', 'bold_italics_font')
+ set_font_size(_font_size)
+
+func set_font(base_name):
+ _set_all_fonts_in_ftl(_text_box, base_name)
+ _set_all_fonts_in_ftl(_user_files.get_rich_text_label(), base_name)
+
+func set_default_font_color(color):
+ _text_box.set('custom_colors/default_color', color)
+
+func set_background_color(color):
+ _text_box_container.color = color
+
+func get_waiting_label():
+ return $VBox/TextDisplay/WaitingLabel
+
+func compact_mode(should):
+ if(_compact_mode == should):
+ return
+
+ _compact_mode = should
+ _text_box_container.visible = !should
+ _nav.container.visible = !should
+ _log_level_slider.visible = !should
+ $VBox/BottomPanel/VBox/HBox/Continue/ShowExtras.visible = !should
+ _titlebar.label.visible = !should
+ _resize_handle.visible = !should
+ _current_script.visible = !should
+ _title_replacement.visible = should
+
+ if(should):
+ rect_min_size = min_sizes.compact
+ rect_size = rect_min_size
+ else:
+ rect_min_size = min_sizes.full
+ rect_size = min_sizes.full
+
+ goto_bottom_right_corner()
+
+
+func set_script_path(text):
+ _current_script.text = text
+
+
+func goto_bottom_right_corner():
+ rect_position = get_tree().root.get_viewport().get_visible_rect().size - rect_size