PirateTreasureHunt/thirdparty/gdhexgrid/addons/gut/gut_gui.gd

354 lines
14 KiB
GDScript

################################################################################
#The MIT License (MIT)
#=====================
#
#Copyright (c) 2017 Tom "Butch" Wesley
#
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
#
################################################################################
################################################################################
# This class contains all the GUI creation code for Gut. It was split out and
# hopefully can be moved to a scene in the future.
################################################################################
extends WindowDialog
# various counters. Most have been moved to the Summary object but not all.
var _summary = {
moved_methods = 0,
# these are used to display the tally in the top right corner. Since the
# implementation changed to summing things up at the end, the running
# update wasn't showing. Hack.
tally_passed = 0,
tally_failed = 0
}
var _is_running = false
var min_size = Vector2(650, 400)
#controls
var _ctrls = {
text_box = TextEdit.new(),
run_button = Button.new(),
copy_button = Button.new(),
clear_button = Button.new(),
continue_button = Button.new(),
log_level_slider = HSlider.new(),
scripts_drop_down = OptionButton.new(),
next_button = Button.new(),
previous_button = Button.new(),
stop_button = Button.new(),
script_progress = ProgressBar.new(),
test_progress = ProgressBar.new(),
runtime_label = Label.new(),
ignore_continue_checkbox = CheckBox.new(),
pass_count = Label.new(),
run_rest = Button.new()
}
var _mouse_down = false
var _mouse_down_pos = null
var _mouse_in = false
func _set_anchor_top_right(obj):
obj.set_anchor(MARGIN_RIGHT, ANCHOR_BEGIN)
obj.set_anchor(MARGIN_LEFT, ANCHOR_END)
obj.set_anchor(MARGIN_TOP, ANCHOR_BEGIN)
func _set_anchor_bottom_right(obj):
obj.set_anchor(MARGIN_LEFT, ANCHOR_END)
obj.set_anchor(MARGIN_RIGHT, ANCHOR_END)
obj.set_anchor(MARGIN_TOP, ANCHOR_END)
obj.set_anchor(MARGIN_BOTTOM, ANCHOR_END)
func _set_anchor_bottom_left(obj):
obj.set_anchor(MARGIN_LEFT, ANCHOR_BEGIN)
obj.set_anchor(MARGIN_TOP, ANCHOR_END)
obj.set_anchor(MARGIN_TOP, ANCHOR_END)
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
func setup_controls():
var button_size = Vector2(75, 35)
var button_spacing = Vector2(10, 0)
var pos = Vector2(0, 0)
add_child(_ctrls.text_box)
_ctrls.text_box.set_size(Vector2(get_size().x - 4, 300))
_ctrls.text_box.set_position(Vector2(2, 0))
_ctrls.text_box.set_readonly(true)
_ctrls.text_box.set_syntax_coloring(true)
_ctrls.text_box.set_anchor(MARGIN_LEFT, ANCHOR_BEGIN)
_ctrls.text_box.set_anchor(MARGIN_RIGHT, ANCHOR_END)
_ctrls.text_box.set_anchor(MARGIN_TOP, ANCHOR_BEGIN)
_ctrls.text_box.set_anchor(MARGIN_BOTTOM, ANCHOR_END)
add_child(_ctrls.copy_button)
_ctrls.copy_button.set_text("Copy")
_ctrls.copy_button.set_size(button_size)
_ctrls.copy_button.set_position(Vector2(get_size().x - 5 - button_size.x, _ctrls.text_box.get_size().y + 10))
_set_anchor_bottom_right(_ctrls.copy_button)
add_child(_ctrls.clear_button)
_ctrls.clear_button.set_text("Clear")
_ctrls.clear_button.set_size(button_size)
_ctrls.clear_button.set_position(_ctrls.copy_button.get_position() - Vector2(button_size.x, 0) - button_spacing)
_set_anchor_bottom_right(_ctrls.clear_button)
add_child(_ctrls.pass_count)
_ctrls.pass_count.set_text('0 - 0')
_ctrls.pass_count.set_size(Vector2(100, 30))
_ctrls.pass_count.set_position(Vector2(550, 0))
_ctrls.pass_count.set_align(HALIGN_RIGHT)
_set_anchor_top_right(_ctrls.pass_count)
add_child(_ctrls.continue_button)
_ctrls.continue_button.set_text("Continue")
_ctrls.continue_button.set_size(Vector2(100, 25))
_ctrls.continue_button.set_position(Vector2(_ctrls.clear_button.get_position().x, _ctrls.clear_button.get_position().y + _ctrls.clear_button.get_size().y + 10))
_ctrls.continue_button.set_disabled(true)
_set_anchor_bottom_right(_ctrls.continue_button)
add_child(_ctrls.ignore_continue_checkbox)
_ctrls.ignore_continue_checkbox.set_text("Ignore pauses")
#_ctrls.ignore_continue_checkbox.set_pressed(_ignore_pause_before_teardown)
_ctrls.ignore_continue_checkbox.set_size(Vector2(50, 30))
_ctrls.ignore_continue_checkbox.set_position(Vector2(_ctrls.continue_button.get_position().x, _ctrls.continue_button.get_position().y + _ctrls.continue_button.get_size().y - 5))
_set_anchor_bottom_right(_ctrls.ignore_continue_checkbox)
var log_label = Label.new()
add_child(log_label)
log_label.set_text("Log Level")
log_label.set_position(Vector2(10, _ctrls.text_box.get_size().y + 1))
_set_anchor_bottom_left(log_label)
add_child(_ctrls.log_level_slider)
_ctrls.log_level_slider.set_size(Vector2(75, 30))
_ctrls.log_level_slider.set_position(Vector2(10, log_label.get_position().y + 20))
_ctrls.log_level_slider.set_min(0)
_ctrls.log_level_slider.set_max(2)
_ctrls.log_level_slider.set_ticks(3)
_ctrls.log_level_slider.set_ticks_on_borders(true)
_ctrls.log_level_slider.set_step(1)
#_ctrls.log_level_slider.set_rounded_values(true)
#_ctrls.log_level_slider.set_value(_log_level)
_set_anchor_bottom_left(_ctrls.log_level_slider)
var script_prog_label = Label.new()
add_child(script_prog_label)
script_prog_label.set_position(Vector2(100, log_label.get_position().y))
script_prog_label.set_text('Scripts:')
_set_anchor_bottom_left(script_prog_label)
add_child(_ctrls.script_progress)
_ctrls.script_progress.set_size(Vector2(200, 10))
_ctrls.script_progress.set_position(script_prog_label.get_position() + Vector2(70, 0))
_ctrls.script_progress.set_min(0)
_ctrls.script_progress.set_max(1)
_ctrls.script_progress.set_step(1)
_set_anchor_bottom_left(_ctrls.script_progress)
var test_prog_label = Label.new()
add_child(test_prog_label)
test_prog_label.set_position(Vector2(100, log_label.get_position().y + 15))
test_prog_label.set_text('Tests:')
_set_anchor_bottom_left(test_prog_label)
add_child(_ctrls.test_progress)
_ctrls.test_progress.set_size(Vector2(200, 10))
_ctrls.test_progress.set_position(test_prog_label.get_position() + Vector2(70, 0))
_ctrls.test_progress.set_min(0)
_ctrls.test_progress.set_max(1)
_ctrls.test_progress.set_step(1)
_set_anchor_bottom_left(_ctrls.test_progress)
add_child(_ctrls.previous_button)
_ctrls.previous_button.set_size(Vector2(50, 25))
pos = _ctrls.test_progress.get_position() + Vector2(250, 25)
pos.x -= 300
_ctrls.previous_button.set_position(pos)
_ctrls.previous_button.set_text("<")
_set_anchor_bottom_left(_ctrls.previous_button)
add_child(_ctrls.stop_button)
_ctrls.stop_button.set_size(Vector2(50, 25))
pos.x += 60
_ctrls.stop_button.set_position(pos)
_ctrls.stop_button.set_text('stop')
_set_anchor_bottom_left(_ctrls.stop_button)
add_child(_ctrls.run_rest)
_ctrls.run_rest.set_text('run')
_ctrls.run_rest.set_size(Vector2(50, 25))
pos.x += 60
_ctrls.run_rest.set_position(pos)
_set_anchor_bottom_left(_ctrls.run_rest)
add_child(_ctrls.next_button)
_ctrls.next_button.set_size(Vector2(50, 25))
pos.x += 60
_ctrls.next_button.set_position(pos)
_ctrls.next_button.set_text(">")
_set_anchor_bottom_left(_ctrls.next_button)
add_child(_ctrls.runtime_label)
_ctrls.runtime_label.set_text('0.0')
_ctrls.runtime_label.set_size(Vector2(50, 30))
_ctrls.runtime_label.set_position(Vector2(_ctrls.clear_button.get_position().x - 90, _ctrls.next_button.get_position().y))
_set_anchor_bottom_right(_ctrls.runtime_label)
# the drop down has to be one of the last added so that when then list of
# scripts is displayed, other controls do not get in the way of selecting
# an item in the list.
add_child(_ctrls.scripts_drop_down)
_ctrls.scripts_drop_down.set_size(Vector2(375, 25))
_ctrls.scripts_drop_down.set_position(Vector2(10, _ctrls.log_level_slider.get_position().y + 50))
_set_anchor_bottom_left(_ctrls.scripts_drop_down)
_ctrls.scripts_drop_down.set_clip_text(true)
add_child(_ctrls.run_button)
_ctrls.run_button.set_text('<- run')
_ctrls.run_button.set_size(Vector2(50, 25))
_ctrls.run_button.set_position(_ctrls.scripts_drop_down.get_position() + Vector2(_ctrls.scripts_drop_down.get_size().x + 5, 0))
_set_anchor_bottom_left(_ctrls.run_button)
func set_it_up():
self.set_size(min_size)
setup_controls()
self.connect("mouse_entered", self, "_on_mouse_enter")
self.connect("mouse_exited", self, "_on_mouse_exit")
set_process(true)
set_pause_mode(PAUSE_MODE_PROCESS)
_update_controls()
#-------------------------------------------------------------------------------
# Updates the display
#-------------------------------------------------------------------------------
func _update_controls():
if(_is_running):
_ctrls.previous_button.set_disabled(true)
_ctrls.next_button.set_disabled(true)
_ctrls.pass_count.show()
else:
_ctrls.previous_button.set_disabled(_ctrls.scripts_drop_down.get_selected() <= 0)
_ctrls.next_button.set_disabled(_ctrls.scripts_drop_down.get_selected() != -1 and _ctrls.scripts_drop_down.get_selected() == _ctrls.scripts_drop_down.get_item_count() -1)
_ctrls.pass_count.hide()
# disabled during run
_ctrls.run_button.set_disabled(_is_running)
_ctrls.run_rest.set_disabled(_is_running)
_ctrls.scripts_drop_down.set_disabled(_is_running)
# enabled during run
_ctrls.stop_button.set_disabled(!_is_running)
_ctrls.pass_count.set_text(str( _summary.tally_passed, ' - ', _summary.tally_failed))
#-------------------------------------------------------------------------------
#detect mouse movement
#-------------------------------------------------------------------------------
func _on_mouse_enter():
_mouse_in = true
#-------------------------------------------------------------------------------
#detect mouse movement
#-------------------------------------------------------------------------------
func _on_mouse_exit():
_mouse_in = false
_mouse_down = false
#-------------------------------------------------------------------------------
#Send text box text to clipboard
#-------------------------------------------------------------------------------
func _copy_button_pressed():
_ctrls.text_box.select_all()
_ctrls.text_box.copy()
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
func _init_run():
_ctrls.text_box.clear_colors()
_ctrls.text_box.add_keyword_color("PASSED", Color(0, 1, 0))
_ctrls.text_box.add_keyword_color("FAILED", Color(1, 0, 0))
_ctrls.text_box.add_color_region('/#', '#/', Color(.9, .6, 0))
_ctrls.text_box.add_color_region('/-', '-/', Color(1, 1, 0))
_ctrls.text_box.add_color_region('/*', '*/', Color(.5, .5, 1))
#_ctrls.text_box.set_symbol_color(Color(.5, .5, .5))
_ctrls.runtime_label.set_text('0.0')
_ctrls.test_progress.set_max(1)
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
func _input(event):
#if the mouse is somewhere within the debug window
if(_mouse_in):
#Check for mouse click inside the resize handle
if(event is InputEventMouseButton):
if (event.button_index == 1):
#It's checking a square area for the bottom right corner, but that's close enough. I'm lazy
if(event.position.x > get_size().x + get_position().x - 10 and event.position.y > get_size().y + get_position().y - 10):
if event.pressed:
_mouse_down = true
_mouse_down_pos = event.position
else:
_mouse_down = false
#Reszie
if(event is InputEventMouseMotion):
if(_mouse_down):
if(get_size() >= min_size):
var new_size = get_size() + event.position - _mouse_down_pos
var new_mouse_down_pos = event.position
if(new_size.x < min_size.x):
new_size.x = min_size.x
new_mouse_down_pos.x = _mouse_down_pos.x
if(new_size.y < min_size.y):
new_size.y = min_size.y
new_mouse_down_pos.y = _mouse_down_pos.y
_mouse_down_pos = new_mouse_down_pos
set_size(new_size)
#-------------------------------------------------------------------------------
#Custom drawing to indicate results.
#-------------------------------------------------------------------------------
func _draw():
#Draw the lines in the corner to show where you can
#drag to resize the dialog
var grab_margin = 2
var line_space = 3
var grab_line_color = Color(.4, .4, .4)
for i in range(1, 6):
draw_line(get_size() - Vector2(i * line_space, grab_margin), get_size() - Vector2(grab_margin, i * line_space), grab_line_color)
return
var where = Vector2(430, 565)
var r = 25
if(_summary.tests > 0):
if(_summary.failed > 0):
draw_circle(where, r , Color(1, 0, 0, 1))
else:
draw_circle(where, r, Color(0, 1, 0, 1))