mirror of
https://github.com/lihop/godot-xterm.git
synced 2025-05-06 12:55:30 +02:00
Update GUT to version 9.1.1
This commit is contained in:
parent
b18726eac9
commit
cea41d6567
65 changed files with 4178 additions and 2995 deletions
|
@ -1,232 +1,150 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://bsk32dh41b4gs"]
|
||||
|
||||
[ext_resource path="res://addons/gut/gui/ShortcutButton.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://addons/gut/gui/BottomPanelShortcuts.gd" type="Script" id=2]
|
||||
[ext_resource type="PackedScene" uid="uid://sfb1fw8j6ufu" path="res://addons/gut/gui/ShortcutButton.tscn" id="1"]
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/BottomPanelShortcuts.gd" id="2"]
|
||||
|
||||
[node name="BottomPanelShortcuts" type="Window"]
|
||||
[node name="BottomPanelShortcuts" type="Popup"]
|
||||
title = "Shortcuts"
|
||||
size = Vector2i(500, 350)
|
||||
visible = true
|
||||
anchor_right = 0.234
|
||||
anchor_bottom = 0.328
|
||||
offset_right = 195.384
|
||||
offset_bottom = 62.2
|
||||
custom_minimum_size = Vector2( 435, 305 )
|
||||
exclusive = true
|
||||
window_title = "GUT Shortcuts"
|
||||
resizable = true
|
||||
script = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
script = ExtResource("2")
|
||||
|
||||
[node name="Layout" type="VBoxContainer" parent="."]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 5.0
|
||||
offset_right = -5.0
|
||||
offset_bottom = 2.0
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="TopPad" type="CenterContainer" parent="Layout"]
|
||||
offset_right = 425.0
|
||||
offset_bottom = 5.0
|
||||
custom_minimum_size = Vector2( 0, 5 )
|
||||
custom_minimum_size = Vector2(0, 5)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label2" type="Label" parent="Layout"]
|
||||
offset_top = 9.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 29.0
|
||||
custom_minimum_size = Vector2( 0, 20 )
|
||||
custom_minimum_size = Vector2(0, 20)
|
||||
layout_mode = 2
|
||||
text = "Always Active"
|
||||
align = 1
|
||||
valign = 1
|
||||
autowrap = true
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="Layout/Label2"]
|
||||
show_behind_parent = true
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
color = Color( 0, 0, 0, 0.196078 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
color = Color(0, 0, 0, 0.196078)
|
||||
|
||||
[node name="CPanelButton" type="HBoxContainer" parent="Layout"]
|
||||
offset_top = 33.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 58.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="Layout/CPanelButton"]
|
||||
offset_right = 138.0
|
||||
offset_bottom = 25.0
|
||||
custom_minimum_size = Vector2( 50, 0 )
|
||||
custom_minimum_size = Vector2(50, 0)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 7
|
||||
text = "Show/Hide GUT Panel"
|
||||
valign = 1
|
||||
|
||||
[node name="ShortcutButton" parent="Layout/CPanelButton" instance=ExtResource( 1 )]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = 142.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 25.0
|
||||
[node name="ShortcutButton" parent="Layout/CPanelButton" instance=ExtResource("1")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="GutPanelPad" type="CenterContainer" parent="Layout"]
|
||||
offset_top = 62.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 67.0
|
||||
custom_minimum_size = Vector2( 0, 5 )
|
||||
custom_minimum_size = Vector2(0, 5)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="Layout"]
|
||||
offset_top = 71.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 91.0
|
||||
custom_minimum_size = Vector2( 0, 20 )
|
||||
custom_minimum_size = Vector2(0, 20)
|
||||
layout_mode = 2
|
||||
text = "Only Active When GUT Panel Shown"
|
||||
align = 1
|
||||
valign = 1
|
||||
autowrap = true
|
||||
|
||||
[node name="ColorRect2" type="ColorRect" parent="Layout/Label"]
|
||||
show_behind_parent = true
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
color = Color( 0, 0, 0, 0.196078 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
color = Color(0, 0, 0, 0.196078)
|
||||
|
||||
[node name="TopPad2" type="CenterContainer" parent="Layout"]
|
||||
offset_top = 95.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 100.0
|
||||
custom_minimum_size = Vector2( 0, 5 )
|
||||
custom_minimum_size = Vector2(0, 5)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CRunAll" type="HBoxContainer" parent="Layout"]
|
||||
offset_top = 104.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 129.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="Layout/CRunAll"]
|
||||
offset_right = 50.0
|
||||
offset_bottom = 25.0
|
||||
custom_minimum_size = Vector2( 50, 0 )
|
||||
custom_minimum_size = Vector2(50, 0)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 7
|
||||
text = "Run All"
|
||||
valign = 1
|
||||
|
||||
[node name="ShortcutButton" parent="Layout/CRunAll" instance=ExtResource( 1 )]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = 54.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 25.0
|
||||
[node name="ShortcutButton" parent="Layout/CRunAll" instance=ExtResource("1")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="CRunCurrentScript" type="HBoxContainer" parent="Layout"]
|
||||
offset_top = 133.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 158.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="Layout/CRunCurrentScript"]
|
||||
offset_right = 115.0
|
||||
offset_bottom = 25.0
|
||||
custom_minimum_size = Vector2( 50, 0 )
|
||||
custom_minimum_size = Vector2(50, 0)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 7
|
||||
text = "Run Current Script"
|
||||
valign = 1
|
||||
|
||||
[node name="ShortcutButton" parent="Layout/CRunCurrentScript" instance=ExtResource( 1 )]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = 119.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 25.0
|
||||
[node name="ShortcutButton" parent="Layout/CRunCurrentScript" instance=ExtResource("1")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="CRunCurrentInner" type="HBoxContainer" parent="Layout"]
|
||||
offset_top = 162.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 187.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="Layout/CRunCurrentInner"]
|
||||
offset_right = 150.0
|
||||
offset_bottom = 25.0
|
||||
custom_minimum_size = Vector2( 50, 0 )
|
||||
custom_minimum_size = Vector2(50, 0)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 7
|
||||
text = "Run Current Inner Class"
|
||||
valign = 1
|
||||
|
||||
[node name="ShortcutButton" parent="Layout/CRunCurrentInner" instance=ExtResource( 1 )]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = 154.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 25.0
|
||||
[node name="ShortcutButton" parent="Layout/CRunCurrentInner" instance=ExtResource("1")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="CRunCurrentTest" type="HBoxContainer" parent="Layout"]
|
||||
offset_top = 191.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 216.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="Layout/CRunCurrentTest"]
|
||||
offset_right = 106.0
|
||||
offset_bottom = 25.0
|
||||
custom_minimum_size = Vector2( 50, 0 )
|
||||
custom_minimum_size = Vector2(50, 0)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 7
|
||||
text = "Run Current Test"
|
||||
valign = 1
|
||||
|
||||
[node name="ShortcutButton" parent="Layout/CRunCurrentTest" instance=ExtResource( 1 )]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = 110.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 25.0
|
||||
[node name="ShortcutButton" parent="Layout/CRunCurrentTest" instance=ExtResource("1")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="CenterContainer2" type="CenterContainer" parent="Layout"]
|
||||
offset_top = 220.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 241.0
|
||||
custom_minimum_size = Vector2( 0, 5 )
|
||||
custom_minimum_size = Vector2(0, 5)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="ShiftDisclaimer" type="Label" parent="Layout"]
|
||||
offset_top = 245.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 259.0
|
||||
layout_mode = 2
|
||||
text = "\"Shift\" cannot be the only modifier for a shortcut."
|
||||
align = 2
|
||||
autowrap = true
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="Layout"]
|
||||
offset_top = 263.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 293.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="Layout/HBoxContainer"]
|
||||
offset_right = 361.0
|
||||
offset_bottom = 30.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Hide" type="Button" parent="Layout/HBoxContainer"]
|
||||
offset_left = 365.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 30.0
|
||||
custom_minimum_size = Vector2( 60, 30 )
|
||||
custom_minimum_size = Vector2(60, 30)
|
||||
layout_mode = 2
|
||||
text = "Close"
|
||||
|
||||
[node name="BottomPad" type="CenterContainer" parent="Layout"]
|
||||
offset_top = 297.0
|
||||
offset_right = 425.0
|
||||
offset_bottom = 307.0
|
||||
custom_minimum_size = Vector2( 0, 10 )
|
||||
custom_minimum_size = Vector2(0, 10)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[connection signal="pressed" from="Layout/HBoxContainer/Hide" to="." method="_on_Hide_pressed"]
|
||||
|
|
|
@ -1,28 +1,29 @@
|
|||
[gd_scene load_steps=10 format=3 uid="uid://b3bostcslstem"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/GutBottomPanel.gd" id="1"]
|
||||
[ext_resource type="PackedScene" path="res://addons/gut/gui/BottomPanelShortcuts.tscn" id="2"]
|
||||
[ext_resource type="PackedScene" path="res://addons/gut/gui/RunAtCursor.tscn" id="3"]
|
||||
[ext_resource type="Texture2D" path="res://addons/gut/gui/play.png" id="4"]
|
||||
[ext_resource type="PackedScene" path="res://addons/gut/gui/RunResults.tscn" id="5"]
|
||||
[ext_resource type="PackedScene" path="res://addons/gut/gui/OutputText.tscn" id="6"]
|
||||
[ext_resource type="PackedScene" uid="uid://bsk32dh41b4gs" path="res://addons/gut/gui/BottomPanelShortcuts.tscn" id="2"]
|
||||
[ext_resource type="PackedScene" uid="uid://0yunjxtaa8iw" path="res://addons/gut/gui/RunAtCursor.tscn" id="3"]
|
||||
[ext_resource type="Texture2D" uid="uid://cr6tvdv0ve6cv" path="res://addons/gut/gui/play.png" id="4"]
|
||||
[ext_resource type="PackedScene" uid="uid://4gyyn12um08h" path="res://addons/gut/gui/RunResults.tscn" id="5"]
|
||||
[ext_resource type="PackedScene" uid="uid://bqmo4dj64c7yl" path="res://addons/gut/gui/OutputText.tscn" id="6"]
|
||||
|
||||
[sub_resource type="Shortcut" id="9"]
|
||||
|
||||
[sub_resource type="Image" id="Image_r56ab"]
|
||||
[sub_resource type="Image" id="Image_abbh7"]
|
||||
data = {
|
||||
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
"format": "LumAlpha8",
|
||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 93, 93, 55, 255, 97, 97, 58, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 98, 98, 47, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 94, 94, 46, 255, 93, 93, 236, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
||||
"format": "RGBA8",
|
||||
"height": 16,
|
||||
"mipmaps": false,
|
||||
"width": 16
|
||||
}
|
||||
|
||||
[sub_resource type="ImageTexture" id="2"]
|
||||
image = SubResource("Image_r56ab")
|
||||
[sub_resource type="ImageTexture" id="ImageTexture_x655i"]
|
||||
image = SubResource("Image_abbh7")
|
||||
|
||||
[node name="GutBottomPanel" type="Control"]
|
||||
custom_minimum_size = Vector2(250, 250)
|
||||
layout_mode = 3
|
||||
anchor_left = -0.0025866
|
||||
anchor_top = -0.00176575
|
||||
anchor_right = 0.997413
|
||||
|
@ -34,297 +35,206 @@ offset_bottom = 1.05945
|
|||
script = ExtResource("1")
|
||||
|
||||
[node name="layout" type="VBoxContainer" parent="."]
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
||||
[node name="ControlBar" type="HBoxContainer" parent="layout"]
|
||||
offset_right = 1023.0
|
||||
offset_bottom = 31.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="RunAll" type="Button" parent="layout/ControlBar"]
|
||||
offset_right = 85.0
|
||||
offset_bottom = 31.0
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 11
|
||||
hint_tooltip = "Run all test scripts in the suite."
|
||||
shortcut = SubResource("9")
|
||||
text = "Run All"
|
||||
icon = ExtResource("4")
|
||||
|
||||
[node name="Label" type="Label" parent="layout/ControlBar"]
|
||||
offset_left = 89.0
|
||||
offset_top = 2.0
|
||||
offset_right = 162.0
|
||||
offset_bottom = 28.0
|
||||
hint_tooltip = "When a test script is edited, buttons are displayed to
|
||||
run the opened script or an Inner-Test-Class or a
|
||||
single test. The buttons change based on the location
|
||||
of the cursor in the file.
|
||||
|
||||
These buttons will remain active when editing other
|
||||
items so that you can run tests without having to switch
|
||||
back to the test script.
|
||||
|
||||
You can assign keyboard shortcuts for these buttons
|
||||
using the \"shortcuts\" button in the GUT panel."
|
||||
layout_mode = 2
|
||||
mouse_filter = 1
|
||||
text = "Current: "
|
||||
|
||||
[node name="RunAtCursor" parent="layout/ControlBar" instance=ExtResource("3")]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = 166.0
|
||||
offset_right = 532.0
|
||||
offset_bottom = 31.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CenterContainer2" type="CenterContainer" parent="layout/ControlBar"]
|
||||
offset_left = 536.0
|
||||
offset_right = 903.0
|
||||
offset_bottom = 31.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Sep1" type="ColorRect" parent="layout/ControlBar"]
|
||||
offset_left = 907.0
|
||||
offset_right = 907.0
|
||||
offset_bottom = 31.0
|
||||
custom_minimum_size = Vector2(1, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="RunResultsBtn" type="Button" parent="layout/ControlBar"]
|
||||
offset_left = 911.0
|
||||
offset_right = 935.0
|
||||
offset_bottom = 31.0
|
||||
hint_tooltip = "Show/Hide Results Tree Panel."
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
icon = SubResource("2")
|
||||
button_pressed = true
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="OutputBtn" type="Button" parent="layout/ControlBar"]
|
||||
offset_left = 939.0
|
||||
offset_right = 963.0
|
||||
offset_bottom = 31.0
|
||||
hint_tooltip = "Show/Hide Output Panel."
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
icon = SubResource("2")
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="Settings" type="Button" parent="layout/ControlBar"]
|
||||
offset_left = 967.0
|
||||
offset_right = 991.0
|
||||
offset_bottom = 31.0
|
||||
hint_tooltip = "Show/Hide Settings Panel."
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
icon = SubResource("2")
|
||||
button_pressed = true
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="Sep2" type="ColorRect" parent="layout/ControlBar"]
|
||||
offset_left = 995.0
|
||||
offset_right = 995.0
|
||||
offset_bottom = 31.0
|
||||
custom_minimum_size = Vector2(1, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Shortcuts" type="Button" parent="layout/ControlBar"]
|
||||
offset_left = 999.0
|
||||
offset_right = 1023.0
|
||||
offset_bottom = 31.0
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 11
|
||||
hint_tooltip = "Set shortcuts for GUT buttons. Shortcuts do not work when the GUT panel is not visible."
|
||||
icon = SubResource("2")
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="RSplit" type="HSplitContainer" parent="layout"]
|
||||
offset_top = 35.0
|
||||
offset_right = 1023.0
|
||||
offset_bottom = 599.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
collapsed = true
|
||||
|
||||
[node name="sc" type="ScrollContainer" parent="layout/RSplit"]
|
||||
visible = false
|
||||
offset_left = 593.0
|
||||
offset_right = 1093.0
|
||||
offset_bottom = 555.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Settings" type="VBoxContainer" parent="layout/RSplit/sc"]
|
||||
offset_right = 500.0
|
||||
offset_bottom = 555.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="CResults" type="VBoxContainer" parent="layout/RSplit"]
|
||||
offset_right = 1023.0
|
||||
offset_bottom = 564.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="ControlBar" type="HBoxContainer" parent="layout/RSplit/CResults"]
|
||||
offset_right = 1023.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Sep2" type="ColorRect" parent="layout/RSplit/CResults/ControlBar"]
|
||||
custom_minimum_size = Vector2(1, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Light3D" type="Control" parent="layout/RSplit/CResults/ControlBar"]
|
||||
visible = false
|
||||
offset_right = 30.0
|
||||
offset_bottom = 35.0
|
||||
custom_minimum_size = Vector2(30, 30)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Passing" type="HBoxContainer" parent="layout/RSplit/CResults/ControlBar"]
|
||||
visible = false
|
||||
offset_left = 34.0
|
||||
offset_right = 107.0
|
||||
offset_bottom = 35.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Sep" type="ColorRect" parent="layout/RSplit/CResults/ControlBar/Passing"]
|
||||
offset_right = 2.0
|
||||
offset_bottom = 35.0
|
||||
custom_minimum_size = Vector2(1, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="label" type="Label" parent="layout/RSplit/CResults/ControlBar/Passing"]
|
||||
offset_left = 6.0
|
||||
offset_top = 10.0
|
||||
offset_right = 54.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "Passing"
|
||||
|
||||
[node name="value" type="Label" parent="layout/RSplit/CResults/ControlBar/Passing"]
|
||||
offset_left = 58.0
|
||||
offset_top = 10.0
|
||||
offset_right = 73.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "---"
|
||||
|
||||
[node name="Failing" type="HBoxContainer" parent="layout/RSplit/CResults/ControlBar"]
|
||||
visible = false
|
||||
offset_left = 34.0
|
||||
offset_right = 100.0
|
||||
offset_bottom = 35.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Sep" type="ColorRect" parent="layout/RSplit/CResults/ControlBar/Failing"]
|
||||
offset_right = 2.0
|
||||
offset_bottom = 35.0
|
||||
custom_minimum_size = Vector2(1, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="label" type="Label" parent="layout/RSplit/CResults/ControlBar/Failing"]
|
||||
offset_left = 6.0
|
||||
offset_top = 10.0
|
||||
offset_right = 47.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "Failing"
|
||||
|
||||
[node name="value" type="Label" parent="layout/RSplit/CResults/ControlBar/Failing"]
|
||||
offset_left = 51.0
|
||||
offset_top = 10.0
|
||||
offset_right = 66.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "---"
|
||||
|
||||
[node name="Pending" type="HBoxContainer" parent="layout/RSplit/CResults/ControlBar"]
|
||||
visible = false
|
||||
offset_left = 34.0
|
||||
offset_right = 110.0
|
||||
offset_bottom = 35.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Sep" type="ColorRect" parent="layout/RSplit/CResults/ControlBar/Pending"]
|
||||
offset_right = 2.0
|
||||
offset_bottom = 35.0
|
||||
custom_minimum_size = Vector2(1, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="label" type="Label" parent="layout/RSplit/CResults/ControlBar/Pending"]
|
||||
offset_left = 6.0
|
||||
offset_top = 10.0
|
||||
offset_right = 57.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "Pending"
|
||||
|
||||
[node name="value" type="Label" parent="layout/RSplit/CResults/ControlBar/Pending"]
|
||||
offset_left = 61.0
|
||||
offset_top = 10.0
|
||||
offset_right = 76.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "---"
|
||||
|
||||
[node name="Orphans" type="HBoxContainer" parent="layout/RSplit/CResults/ControlBar"]
|
||||
visible = false
|
||||
offset_left = 34.0
|
||||
offset_right = 110.0
|
||||
offset_bottom = 35.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Sep" type="ColorRect" parent="layout/RSplit/CResults/ControlBar/Orphans"]
|
||||
offset_right = 2.0
|
||||
offset_bottom = 35.0
|
||||
custom_minimum_size = Vector2(1, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="label" type="Label" parent="layout/RSplit/CResults/ControlBar/Orphans"]
|
||||
offset_left = 6.0
|
||||
offset_top = 10.0
|
||||
offset_right = 57.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "Orphans"
|
||||
|
||||
[node name="value" type="Label" parent="layout/RSplit/CResults/ControlBar/Orphans"]
|
||||
offset_left = 61.0
|
||||
offset_top = 10.0
|
||||
offset_right = 76.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "---"
|
||||
|
||||
[node name="Errors" type="HBoxContainer" parent="layout/RSplit/CResults/ControlBar"]
|
||||
visible = false
|
||||
offset_left = 34.0
|
||||
offset_right = 96.0
|
||||
offset_bottom = 35.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Sep" type="ColorRect" parent="layout/RSplit/CResults/ControlBar/Errors"]
|
||||
offset_right = 2.0
|
||||
offset_bottom = 35.0
|
||||
custom_minimum_size = Vector2(1, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="label" type="Label" parent="layout/RSplit/CResults/ControlBar/Errors"]
|
||||
offset_left = 6.0
|
||||
offset_top = 10.0
|
||||
offset_right = 43.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "The number of GUT errors generated. This does not include engine errors."
|
||||
layout_mode = 2
|
||||
text = "Errors"
|
||||
|
||||
[node name="value" type="Label" parent="layout/RSplit/CResults/ControlBar/Errors"]
|
||||
offset_left = 47.0
|
||||
offset_top = 10.0
|
||||
offset_right = 62.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "---"
|
||||
|
||||
[node name="Warnings" type="HBoxContainer" parent="layout/RSplit/CResults/ControlBar"]
|
||||
visible = false
|
||||
offset_left = 34.0
|
||||
offset_right = 118.0
|
||||
offset_bottom = 35.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Sep" type="ColorRect" parent="layout/RSplit/CResults/ControlBar/Warnings"]
|
||||
offset_right = 2.0
|
||||
offset_bottom = 35.0
|
||||
custom_minimum_size = Vector2(1, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="label" type="Label" parent="layout/RSplit/CResults/ControlBar/Warnings"]
|
||||
offset_left = 6.0
|
||||
offset_top = 10.0
|
||||
offset_right = 65.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "Warnings"
|
||||
|
||||
[node name="value" type="Label" parent="layout/RSplit/CResults/ControlBar/Warnings"]
|
||||
offset_left = 69.0
|
||||
offset_top = 10.0
|
||||
offset_right = 84.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = "---"
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="layout/RSplit/CResults/ControlBar"]
|
||||
offset_right = 1023.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="TabBar" type="HSplitContainer" parent="layout/RSplit/CResults"]
|
||||
offset_top = 4.0
|
||||
offset_right = 1023.0
|
||||
offset_bottom = 564.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="RunResults" parent="layout/RSplit/CResults/TabBar" instance=ExtResource("5")]
|
||||
offset_right = 505.0
|
||||
offset_bottom = 560.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="OutputText" parent="layout/RSplit/CResults/TabBar" instance=ExtResource("6")]
|
||||
offset_left = 517.0
|
||||
offset_right = 1023.0
|
||||
offset_bottom = 560.0
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="sc" type="ScrollContainer" parent="layout/RSplit"]
|
||||
custom_minimum_size = Vector2(500, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Settings" type="VBoxContainer" parent="layout/RSplit/sc"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="BottomPanelShortcuts" parent="." instance=ExtResource("2")]
|
||||
visible = false
|
||||
|
|
322
addons/gut/gui/GutControl.gd
Normal file
322
addons/gut/gui/GutControl.gd
Normal file
|
@ -0,0 +1,322 @@
|
|||
@tool
|
||||
extends Control
|
||||
|
||||
const RUNNER_JSON_PATH = "res://.gut_editor_config.json"
|
||||
|
||||
var GutConfig = load("res://addons/gut/gut_config.gd")
|
||||
var GutRunnerScene = load("res://addons/gut/gui/GutRunner.tscn")
|
||||
var GutConfigGui = load("res://addons/gut/gui/gut_config_gui.gd")
|
||||
|
||||
var _config = GutConfig.new()
|
||||
var _config_gui = null
|
||||
var _gut_runner = GutRunnerScene.instantiate()
|
||||
var _has_connected = false
|
||||
var _tree_root: TreeItem = null
|
||||
|
||||
var _script_icon = load("res://addons/gut/images/Script.svg")
|
||||
var _folder_icon = load("res://addons/gut/images/Folder.svg")
|
||||
|
||||
var _tree_scripts = {}
|
||||
var _tree_directories = {}
|
||||
|
||||
const TREE_SCRIPT = "Script"
|
||||
const TREE_DIR = "Directory"
|
||||
|
||||
@onready var _ctrls = {
|
||||
run_tests_button = $VBox/Buttons/RunTests,
|
||||
run_selected = $VBox/Buttons/RunSelected,
|
||||
test_tree = $VBox/Tabs/Tests,
|
||||
settings_vbox = $VBox/Tabs/SettingsScroll/Settings,
|
||||
tabs = $VBox/Tabs,
|
||||
bg = $Bg
|
||||
}
|
||||
|
||||
@export var bg_color: Color = Color(.36, .36, .36):
|
||||
get:
|
||||
return bg_color
|
||||
set(val):
|
||||
bg_color = val
|
||||
if is_inside_tree():
|
||||
$Bg.color = bg_color
|
||||
|
||||
|
||||
func _ready():
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
||||
$Bg.color = bg_color
|
||||
_ctrls.tabs.set_tab_title(0, "Tests")
|
||||
_ctrls.tabs.set_tab_title(1, "Settings")
|
||||
|
||||
_config_gui = GutConfigGui.new(_ctrls.settings_vbox)
|
||||
|
||||
_ctrls.test_tree.hide_root = true
|
||||
# Stop tests from kicking off when the runner is "ready" and
|
||||
# prevents it from writing results file that is used by
|
||||
# the panel.
|
||||
_gut_runner.set_cmdln_mode(true)
|
||||
add_child(_gut_runner)
|
||||
|
||||
# Becuase of the janky _utils psuedo-global script, we cannot
|
||||
# do all this in _ready. If we do this in _ready, it generates
|
||||
# a bunch of errors. The errors don't matter, but it looks bad.
|
||||
call_deferred("_post_ready")
|
||||
|
||||
|
||||
func _draw():
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
||||
var gut = _gut_runner.get_gut()
|
||||
if !gut.is_running():
|
||||
var r = Rect2(Vector2(0, 0), get_rect().size)
|
||||
draw_rect(r, Color.BLACK, false, 2)
|
||||
|
||||
|
||||
func _post_ready():
|
||||
var gut = _gut_runner.get_gut()
|
||||
gut.start_run.connect(_on_gut_run_started)
|
||||
gut.end_run.connect(_on_gut_run_ended)
|
||||
_refresh_tree_and_settings()
|
||||
|
||||
|
||||
func _set_meta_for_script_tree_item(item, script, test = null):
|
||||
var meta = {
|
||||
type = TREE_SCRIPT, script = script.path, inner_class = script.inner_class_name, test = ""
|
||||
}
|
||||
|
||||
if test != null:
|
||||
meta.test = test.name
|
||||
|
||||
item.set_metadata(0, meta)
|
||||
|
||||
|
||||
func _set_meta_for_directory_tree_item(item, path, temp_item):
|
||||
var meta = {type = TREE_DIR, path = path, temp_item = temp_item}
|
||||
item.set_metadata(0, meta)
|
||||
|
||||
|
||||
func _get_script_tree_item(script, parent_item):
|
||||
if !_tree_scripts.has(script.path):
|
||||
var item = _ctrls.test_tree.create_item(parent_item)
|
||||
item.set_text(0, script.path.get_file())
|
||||
item.set_icon(0, _script_icon)
|
||||
_tree_scripts[script.path] = item
|
||||
_set_meta_for_script_tree_item(item, script)
|
||||
|
||||
return _tree_scripts[script.path]
|
||||
|
||||
|
||||
func _get_directory_tree_item(path):
|
||||
var parent = _tree_root
|
||||
if !_tree_directories.has(path):
|
||||
var item: TreeItem = null
|
||||
if parent != _tree_root:
|
||||
item = parent.create_child(0)
|
||||
else:
|
||||
item = parent.create_child()
|
||||
|
||||
_tree_directories[path] = item
|
||||
item.collapsed = false
|
||||
item.set_text(0, path)
|
||||
item.set_icon(0, _folder_icon)
|
||||
item.set_icon_modulate(0, Color.ROYAL_BLUE)
|
||||
# temp_item is used in calls with move_before since you must use
|
||||
# move_before or move_after to reparent tree items. This ensures that
|
||||
# there is an item on all directories. These are deleted later.
|
||||
var temp_item = item.create_child()
|
||||
temp_item.set_text(0, "<temp>")
|
||||
|
||||
_set_meta_for_directory_tree_item(item, path, temp_item)
|
||||
|
||||
return _tree_directories[path]
|
||||
|
||||
|
||||
func _find_dir_item_to_move_before(path):
|
||||
var max_matching_len = 0
|
||||
var best_parent = null
|
||||
|
||||
# Go through all the directory items finding the one that has the longest
|
||||
# path that contains our path.
|
||||
for key in _tree_directories.keys():
|
||||
if path != key and path.begins_with(key) and key.length() > max_matching_len:
|
||||
max_matching_len = key.length()
|
||||
best_parent = _tree_directories[key]
|
||||
|
||||
var to_return = null
|
||||
if best_parent != null:
|
||||
to_return = best_parent.get_metadata(0).temp_item
|
||||
return to_return
|
||||
|
||||
|
||||
func _reorder_dir_items():
|
||||
var the_keys = _tree_directories.keys()
|
||||
the_keys.sort()
|
||||
for key in _tree_directories.keys():
|
||||
var to_move = _tree_directories[key]
|
||||
to_move.collapsed = false
|
||||
var move_before = _find_dir_item_to_move_before(key)
|
||||
if move_before != null:
|
||||
to_move.move_before(move_before)
|
||||
var new_text = key.substr(move_before.get_parent().get_metadata(0).path.length())
|
||||
to_move.set_text(0, new_text)
|
||||
|
||||
|
||||
func _remove_dir_temp_items():
|
||||
for key in _tree_directories.keys():
|
||||
var item = _tree_directories[key].get_metadata(0).temp_item
|
||||
_tree_directories[key].remove_child(item)
|
||||
|
||||
|
||||
func _add_dir_and_script_tree_items():
|
||||
var tree: Tree = _ctrls.test_tree
|
||||
tree.clear()
|
||||
_tree_root = _ctrls.test_tree.create_item()
|
||||
|
||||
var scripts = _gut_runner.get_gut().get_test_collector().scripts
|
||||
for script in scripts:
|
||||
var dir_item = _get_directory_tree_item(script.path.get_base_dir())
|
||||
var item = _get_script_tree_item(script, dir_item)
|
||||
|
||||
if script.inner_class_name != "":
|
||||
var inner_item = tree.create_item(item)
|
||||
inner_item.set_text(0, script.inner_class_name)
|
||||
_set_meta_for_script_tree_item(inner_item, script)
|
||||
item = inner_item
|
||||
|
||||
for test in script.tests:
|
||||
var test_item = tree.create_item(item)
|
||||
test_item.set_text(0, test.name)
|
||||
_set_meta_for_script_tree_item(test_item, script, test)
|
||||
|
||||
|
||||
func _populate_tree():
|
||||
_add_dir_and_script_tree_items()
|
||||
_tree_root.set_collapsed_recursive(true)
|
||||
_tree_root.set_collapsed(false)
|
||||
_reorder_dir_items()
|
||||
_remove_dir_temp_items()
|
||||
|
||||
|
||||
func _refresh_tree_and_settings():
|
||||
if _config.options.has("panel_options"):
|
||||
_config_gui.set_options(_config.options)
|
||||
_config.apply_options(_gut_runner.get_gut())
|
||||
_gut_runner.set_gut_config(_config)
|
||||
_populate_tree()
|
||||
|
||||
|
||||
# ---------------------------
|
||||
# Events
|
||||
# ---------------------------
|
||||
func _on_gut_run_started():
|
||||
_ctrls.run_tests_button.disabled = true
|
||||
_ctrls.run_selected.visible = false
|
||||
_ctrls.tabs.visible = false
|
||||
_ctrls.bg.visible = false
|
||||
_ctrls.run_tests_button.text = "Running"
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _on_gut_run_ended():
|
||||
_ctrls.run_tests_button.disabled = false
|
||||
_ctrls.run_selected.visible = true
|
||||
_ctrls.tabs.visible = true
|
||||
_ctrls.bg.visible = true
|
||||
_ctrls.run_tests_button.text = "Run All"
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _on_run_tests_pressed():
|
||||
run_all()
|
||||
|
||||
|
||||
func _on_run_selected_pressed():
|
||||
run_selected()
|
||||
|
||||
|
||||
func _on_tests_item_activated():
|
||||
run_selected()
|
||||
|
||||
|
||||
# ---------------------------
|
||||
# Public
|
||||
# ---------------------------
|
||||
func get_gut():
|
||||
return _gut_runner.get_gut()
|
||||
|
||||
|
||||
func get_config():
|
||||
return _config
|
||||
|
||||
|
||||
func run_all():
|
||||
_config.options.selected = ""
|
||||
_config.options.inner_class_name = ""
|
||||
_config.options.unit_test_name = ""
|
||||
run_tests()
|
||||
|
||||
|
||||
func run_tests(options = null):
|
||||
if options == null:
|
||||
_config.options = _config_gui.get_options(_config.options)
|
||||
else:
|
||||
_config.options = options
|
||||
|
||||
_gut_runner.get_gut().get_test_collector().clear()
|
||||
_gut_runner.set_gut_config(_config)
|
||||
_gut_runner.run_tests()
|
||||
|
||||
|
||||
func run_selected():
|
||||
var sel_item = _ctrls.test_tree.get_selected()
|
||||
if sel_item == null:
|
||||
return
|
||||
|
||||
var options = _config_gui.get_options(_config.options)
|
||||
var meta = sel_item.get_metadata(0)
|
||||
if meta.type == TREE_SCRIPT:
|
||||
options.selected = meta.script.get_file()
|
||||
options.inner_class_name = meta.inner_class
|
||||
options.unit_test_name = meta.test
|
||||
elif meta.type == TREE_DIR:
|
||||
options.dirs = [meta.path]
|
||||
options.include_subdirectories = true
|
||||
options.selected = ""
|
||||
options.inner_class_name = ""
|
||||
options.unit_test_name = ""
|
||||
|
||||
run_tests(options)
|
||||
|
||||
|
||||
func load_config_file(path):
|
||||
_config.load_panel_options(path)
|
||||
_config.options.selected = ""
|
||||
_config.options.inner_class_name = ""
|
||||
_config.options.unit_test_name = ""
|
||||
|
||||
# ##############################################################################
|
||||
# The MIT License (MIT)
|
||||
# =====================
|
||||
#
|
||||
# Copyright (c) 2023 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.
|
||||
#
|
||||
# ##############################################################################
|
63
addons/gut/gui/GutControl.tscn
Normal file
63
addons/gut/gui/GutControl.tscn
Normal file
|
@ -0,0 +1,63 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://4jb53yqktyfg"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/GutControl.gd" id="1_eprql"]
|
||||
|
||||
[node name="GutControl" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_right = 295.0
|
||||
offset_bottom = 419.0
|
||||
script = ExtResource("1_eprql")
|
||||
|
||||
[node name="Bg" type="ColorRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0.36, 0.36, 0.36, 1)
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Tabs" type="TabContainer" parent="VBox"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Tests" type="Tree" parent="VBox/Tabs"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
hide_root = true
|
||||
|
||||
[node name="SettingsScroll" type="ScrollContainer" parent="VBox/Tabs"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Settings" type="VBoxContainer" parent="VBox/Tabs/SettingsScroll"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Buttons" type="HBoxContainer" parent="VBox"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="RunTests" type="Button" parent="VBox/Buttons"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Run All"
|
||||
|
||||
[node name="RunSelected" type="Button" parent="VBox/Buttons"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Run Selected"
|
||||
|
||||
[connection signal="item_activated" from="VBox/Tabs/Tests" to="." method="_on_tests_item_activated"]
|
||||
[connection signal="pressed" from="VBox/Buttons/RunTests" to="." method="_on_run_tests_pressed"]
|
||||
[connection signal="pressed" from="VBox/Buttons/RunSelected" to="." method="_on_run_selected_pressed"]
|
|
@ -1,3 +1,18 @@
|
|||
# ##############################################################################
|
||||
# This class joins together GUT, GUT Gui, GutConfig and is the main way to
|
||||
# run a test suite.
|
||||
#
|
||||
# This creates its own instance of gut.gd that it manages.
|
||||
# Use set_gut_config to set the gut_config.gd that should be used to configure
|
||||
# gut.
|
||||
# This will create a GUI and wire it up and apply gut_config.gd options.
|
||||
#
|
||||
# Running tests:
|
||||
# By default, this will run tests once this control has been added to the tree.
|
||||
# You can override this by setting auto_run_tests to false prior to adding
|
||||
# this to the tree. To run tests manually, call run_tests.
|
||||
#
|
||||
# ##############################################################################
|
||||
extends Node2D
|
||||
|
||||
var Gut = load("res://addons/gut/gut.gd")
|
||||
|
@ -19,6 +34,7 @@ var _cmdln_mode = false
|
|||
@onready var _gut_layer = $GutLayer
|
||||
@onready var _gui = $GutLayer/GutScene
|
||||
|
||||
# When true, tests will be kicked off in _ready.
|
||||
var auto_run_tests = true
|
||||
|
||||
|
||||
|
@ -34,29 +50,9 @@ func _ready():
|
|||
call_deferred("run_tests")
|
||||
|
||||
|
||||
func run_tests(show_gui = true):
|
||||
func _lazy_make_gut():
|
||||
if _gut == null:
|
||||
get_gut()
|
||||
|
||||
_setup_gui(show_gui)
|
||||
|
||||
_gut.add_children_to = self
|
||||
if _gut_config.options.gut_on_top:
|
||||
_gut_layer.add_child(_gut)
|
||||
else:
|
||||
add_child(_gut)
|
||||
|
||||
if !_cmdln_mode:
|
||||
_gut.end_run.connect(
|
||||
_on_tests_finished.bind(
|
||||
_gut_config.options.should_exit, _gut_config.options.should_exit_on_success
|
||||
)
|
||||
)
|
||||
|
||||
_gut_config.config_gut(_gut)
|
||||
var run_rest_of_scripts = _gut_config.options.unit_test_name == ""
|
||||
|
||||
_gut.test_scripts(run_rest_of_scripts)
|
||||
_gut = Gut.new()
|
||||
|
||||
|
||||
func _setup_gui(show_gui):
|
||||
|
@ -76,20 +72,18 @@ func _setup_gui(show_gui):
|
|||
if opts.background_color != null and opts.background_color.is_valid_html_color():
|
||||
_gui.set_background_color(Color(opts.background_color))
|
||||
|
||||
#_tester.set_modulate(Color(1.0, 1.0, 1.0, min(1.0, float(opts.opacity) / 100)))
|
||||
_gui.set_opacity(min(1.0, float(opts.opacity) / 100))
|
||||
# if(opts.should_maximize):
|
||||
# _tester.maximize()
|
||||
#if(opts.compact_mode):
|
||||
# _tester.get_gui().compact_mode(true)
|
||||
_gui.use_compact_mode(opts.compact_mode)
|
||||
|
||||
|
||||
func _write_results():
|
||||
var content = _gui.get_textbox().text #_gut.logger.get_gui_bbcode()
|
||||
|
||||
var content = _gui.get_textbox().get_parsed_text() #_gut.logger.get_gui_bbcode()
|
||||
var f = FileAccess.open(RESULT_FILE, FileAccess.WRITE)
|
||||
if f != null:
|
||||
f.store_string(content)
|
||||
f.close()
|
||||
f = null # closes file
|
||||
else:
|
||||
push_error("Could not save bbcode, result = ", FileAccess.get_open_error())
|
||||
|
||||
|
@ -112,9 +106,33 @@ func _on_tests_finished(should_exit, should_exit_on_success):
|
|||
get_tree().quit()
|
||||
|
||||
|
||||
func run_tests(show_gui = true):
|
||||
_lazy_make_gut()
|
||||
|
||||
_setup_gui(show_gui)
|
||||
|
||||
_gut.add_children_to = self
|
||||
if _gut.get_parent() == null:
|
||||
if _gut_config.options.gut_on_top:
|
||||
_gut_layer.add_child(_gut)
|
||||
else:
|
||||
add_child(_gut)
|
||||
|
||||
if !_cmdln_mode:
|
||||
_gut.end_run.connect(
|
||||
_on_tests_finished.bind(
|
||||
_gut_config.options.should_exit, _gut_config.options.should_exit_on_success
|
||||
)
|
||||
)
|
||||
|
||||
_gut_config.apply_options(_gut)
|
||||
var run_rest_of_scripts = _gut_config.options.unit_test_name == ""
|
||||
|
||||
_gut.test_scripts(run_rest_of_scripts)
|
||||
|
||||
|
||||
func get_gut():
|
||||
if _gut == null:
|
||||
_gut = Gut.new()
|
||||
_lazy_make_gut()
|
||||
return _gut
|
||||
|
||||
|
||||
|
@ -124,3 +142,29 @@ func set_gut_config(which):
|
|||
|
||||
func set_cmdln_mode(is_it):
|
||||
_cmdln_mode = is_it
|
||||
|
||||
# ##############################################################################
|
||||
# The MIT License (MIT)
|
||||
# =====================
|
||||
#
|
||||
# Copyright (c) 2023 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.
|
||||
#
|
||||
# ##############################################################################
|
||||
|
|
File diff suppressed because one or more lines are too long
161
addons/gut/gui/MinGui.tscn
Normal file
161
addons/gut/gui/MinGui.tscn
Normal file
|
@ -0,0 +1,161 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://cnqqdfsn80ise"]
|
||||
|
||||
[ext_resource type="Theme" uid="uid://cstkhwkpajvqu" path="res://addons/gut/gui/GutSceneTheme.tres" id="1_farmq"]
|
||||
[ext_resource type="FontFile" uid="uid://bnh0lslf4yh87" path="res://addons/gut/fonts/CourierPrime-Regular.ttf" id="2_a2e2l"]
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/gut_gui.gd" id="2_eokrf"]
|
||||
[ext_resource type="PackedScene" uid="uid://bvrqqgjpyouse" path="res://addons/gut/gui/ResizeHandle.tscn" id="4_xrhva"]
|
||||
|
||||
[node name="Min" type="Panel"]
|
||||
clip_contents = true
|
||||
custom_minimum_size = Vector2(280, 145)
|
||||
offset_right = 280.0
|
||||
offset_bottom = 145.0
|
||||
theme = ExtResource("1_farmq")
|
||||
script = ExtResource("2_eokrf")
|
||||
|
||||
[node name="MainBox" type="VBoxContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
metadata/_edit_layout_mode = 1
|
||||
|
||||
[node name="TitleBar" type="Panel" parent="MainBox"]
|
||||
custom_minimum_size = Vector2(0, 25)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TitleBox" type="HBoxContainer" parent="MainBox/TitleBar"]
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = 2.0
|
||||
offset_bottom = 3.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
metadata/_edit_layout_mode = 1
|
||||
|
||||
[node name="Spacer1" type="CenterContainer" parent="MainBox/TitleBar/TitleBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Title" type="Label" parent="MainBox/TitleBar/TitleBox"]
|
||||
layout_mode = 2
|
||||
text = "Title"
|
||||
|
||||
[node name="Spacer2" type="CenterContainer" parent="MainBox/TitleBar/TitleBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="TimeLabel" type="Label" parent="MainBox/TitleBar/TitleBox"]
|
||||
layout_mode = 2
|
||||
text = "0.000s"
|
||||
|
||||
[node name="Body" type="HBoxContainer" parent="MainBox"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="LeftMargin" type="CenterContainer" parent="MainBox/Body"]
|
||||
custom_minimum_size = Vector2(5, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="BodyRows" type="VBoxContainer" parent="MainBox/Body"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ProgressBars" type="HBoxContainer" parent="MainBox/Body/BodyRows"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MainBox/Body/BodyRows/ProgressBars"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Label" type="Label" parent="MainBox/Body/BodyRows/ProgressBars/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "T:"
|
||||
|
||||
[node name="ProgressTest" type="ProgressBar" parent="MainBox/Body/BodyRows/ProgressBars/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
value = 25.0
|
||||
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="MainBox/Body/BodyRows/ProgressBars"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Label" type="Label" parent="MainBox/Body/BodyRows/ProgressBars/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
text = "S:"
|
||||
|
||||
[node name="ProgressScript" type="ProgressBar" parent="MainBox/Body/BodyRows/ProgressBars/HBoxContainer2"]
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
value = 75.0
|
||||
|
||||
[node name="PathDisplay" type="VBoxContainer" parent="MainBox/Body/BodyRows"]
|
||||
clip_contents = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Path" type="Label" parent="MainBox/Body/BodyRows/PathDisplay"]
|
||||
layout_mode = 2
|
||||
theme_override_fonts/font = ExtResource("2_a2e2l")
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "res://test/integration/whatever"
|
||||
clip_text = true
|
||||
text_overrun_behavior = 3
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MainBox/Body/BodyRows/PathDisplay"]
|
||||
clip_contents = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="S3" type="CenterContainer" parent="MainBox/Body/BodyRows/PathDisplay/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(5, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="File" type="Label" parent="MainBox/Body/BodyRows/PathDisplay/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_fonts/font = ExtResource("2_a2e2l")
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "test_this_thing.gd"
|
||||
text_overrun_behavior = 3
|
||||
|
||||
[node name="Footer" type="HBoxContainer" parent="MainBox/Body/BodyRows"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HandleLeft" parent="MainBox/Body/BodyRows/Footer" node_paths=PackedStringArray("resize_control") instance=ExtResource("4_xrhva")]
|
||||
layout_mode = 2
|
||||
orientation = 0
|
||||
resize_control = NodePath("../../../../..")
|
||||
vertical_resize = false
|
||||
|
||||
[node name="SwitchModes" type="Button" parent="MainBox/Body/BodyRows/Footer"]
|
||||
layout_mode = 2
|
||||
text = "Expand"
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="MainBox/Body/BodyRows/Footer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Continue" type="Button" parent="MainBox/Body/BodyRows/Footer"]
|
||||
layout_mode = 2
|
||||
text = "Continue
|
||||
"
|
||||
|
||||
[node name="HandleRight" parent="MainBox/Body/BodyRows/Footer" node_paths=PackedStringArray("resize_control") instance=ExtResource("4_xrhva")]
|
||||
layout_mode = 2
|
||||
resize_control = NodePath("../../../../..")
|
||||
vertical_resize = false
|
||||
|
||||
[node name="RightMargin" type="CenterContainer" parent="MainBox/Body"]
|
||||
custom_minimum_size = Vector2(5, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="MainBox"]
|
||||
custom_minimum_size = Vector2(2.08165e-12, 2)
|
||||
layout_mode = 2
|
213
addons/gut/gui/NormalGui.tscn
Normal file
213
addons/gut/gui/NormalGui.tscn
Normal file
|
@ -0,0 +1,213 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://duxblir3vu8x7"]
|
||||
|
||||
[ext_resource type="Theme" uid="uid://cstkhwkpajvqu" path="res://addons/gut/gui/GutSceneTheme.tres" id="1_5hlsm"]
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/gut_gui.gd" id="2_fue6q"]
|
||||
[ext_resource type="FontFile" uid="uid://bnh0lslf4yh87" path="res://addons/gut/fonts/CourierPrime-Regular.ttf" id="2_u5uc1"]
|
||||
[ext_resource type="PackedScene" uid="uid://bvrqqgjpyouse" path="res://addons/gut/gui/ResizeHandle.tscn" id="4_2r8a8"]
|
||||
|
||||
[node name="Large" type="Panel"]
|
||||
custom_minimum_size = Vector2(500, 150)
|
||||
offset_right = 632.0
|
||||
offset_bottom = 260.0
|
||||
theme = ExtResource("1_5hlsm")
|
||||
script = ExtResource("2_fue6q")
|
||||
|
||||
[node name="MainBox" type="VBoxContainer" parent="."]
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
metadata/_edit_layout_mode = 1
|
||||
|
||||
[node name="TitleBar" type="Panel" parent="MainBox"]
|
||||
custom_minimum_size = Vector2(0, 25)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TitleBox" type="HBoxContainer" parent="MainBox/TitleBar"]
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = 2.0
|
||||
offset_bottom = 3.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
metadata/_edit_layout_mode = 1
|
||||
|
||||
[node name="Spacer1" type="CenterContainer" parent="MainBox/TitleBar/TitleBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Title" type="Label" parent="MainBox/TitleBar/TitleBox"]
|
||||
layout_mode = 2
|
||||
text = "Title"
|
||||
|
||||
[node name="Spacer2" type="CenterContainer" parent="MainBox/TitleBar/TitleBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="TimeLabel" type="Label" parent="MainBox/TitleBar/TitleBox"]
|
||||
custom_minimum_size = Vector2(90, 0)
|
||||
layout_mode = 2
|
||||
text = "999.999s"
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MainBox"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MainBox/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="OutputBG" type="ColorRect" parent="MainBox/HBoxContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
color = Color(0.0745098, 0.0705882, 0.0784314, 1)
|
||||
metadata/_edit_layout_mode = 1
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MainBox/HBoxContainer/VBoxContainer/OutputBG"]
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="S2" type="CenterContainer" parent="MainBox/HBoxContainer/VBoxContainer/OutputBG/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(5, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TestOutput" type="RichTextLabel" parent="MainBox/HBoxContainer/VBoxContainer/OutputBG/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
focus_mode = 2
|
||||
bbcode_enabled = true
|
||||
scroll_following = true
|
||||
autowrap_mode = 0
|
||||
selection_enabled = true
|
||||
|
||||
[node name="S1" type="CenterContainer" parent="MainBox/HBoxContainer/VBoxContainer/OutputBG/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(5, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ControlBox" type="HBoxContainer" parent="MainBox/HBoxContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="S1" type="CenterContainer" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox"]
|
||||
custom_minimum_size = Vector2(5, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ProgressBars" type="VBoxContainer" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox"]
|
||||
custom_minimum_size = Vector2(2.08165e-12, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TestBox" type="HBoxContainer" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox/ProgressBars"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox/ProgressBars/TestBox"]
|
||||
custom_minimum_size = Vector2(60, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Tests"
|
||||
|
||||
[node name="ProgressTest" type="ProgressBar" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox/ProgressBars/TestBox"]
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
value = 25.0
|
||||
|
||||
[node name="ScriptBox" type="HBoxContainer" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox/ProgressBars"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox/ProgressBars/ScriptBox"]
|
||||
custom_minimum_size = Vector2(60, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Scripts"
|
||||
|
||||
[node name="ProgressScript" type="ProgressBar" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox/ProgressBars/ScriptBox"]
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
value = 75.0
|
||||
|
||||
[node name="PathDisplay" type="VBoxContainer" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Path" type="Label" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox/PathDisplay"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 6
|
||||
theme_override_fonts/font = ExtResource("2_u5uc1")
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "res://test/integration/whatever"
|
||||
text_overrun_behavior = 3
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox/PathDisplay"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="S3" type="CenterContainer" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox/PathDisplay/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(5, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="File" type="Label" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox/PathDisplay/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_fonts/font = ExtResource("2_u5uc1")
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "test_this_thing.gd"
|
||||
text_overrun_behavior = 3
|
||||
|
||||
[node name="Spacer1" type="CenterContainer" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 10
|
||||
|
||||
[node name="Continue" type="Button" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
text = "Continue
|
||||
"
|
||||
|
||||
[node name="S3" type="CenterContainer" parent="MainBox/HBoxContainer/VBoxContainer/ControlBox"]
|
||||
custom_minimum_size = Vector2(5, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="BottomPad" type="CenterContainer" parent="MainBox"]
|
||||
custom_minimum_size = Vector2(0, 5)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Footer" type="HBoxContainer" parent="MainBox"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SidePad1" type="CenterContainer" parent="MainBox/Footer"]
|
||||
custom_minimum_size = Vector2(2, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ResizeHandle3" parent="MainBox/Footer" node_paths=PackedStringArray("resize_control") instance=ExtResource("4_2r8a8")]
|
||||
custom_minimum_size = Vector2(25, 25)
|
||||
layout_mode = 2
|
||||
orientation = 0
|
||||
resize_control = NodePath("../../..")
|
||||
|
||||
[node name="SwitchModes" type="Button" parent="MainBox/Footer"]
|
||||
layout_mode = 2
|
||||
text = "Compact
|
||||
"
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="MainBox/Footer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ResizeHandle2" parent="MainBox/Footer" node_paths=PackedStringArray("resize_control") instance=ExtResource("4_2r8a8")]
|
||||
custom_minimum_size = Vector2(25, 25)
|
||||
layout_mode = 2
|
||||
resize_control = NodePath("../../..")
|
||||
|
||||
[node name="SidePad2" type="CenterContainer" parent="MainBox/Footer"]
|
||||
custom_minimum_size = Vector2(2, 2.08165e-12)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="BottomPad2" type="CenterContainer" parent="MainBox"]
|
||||
custom_minimum_size = Vector2(2.08165e-12, 2)
|
||||
layout_mode = 2
|
|
@ -1,91 +1,64 @@
|
|||
extends VBoxContainer
|
||||
@tool
|
||||
extends VBoxContainer
|
||||
|
||||
|
||||
class SearchResults:
|
||||
var L = 0
|
||||
var C = 0
|
||||
|
||||
var positions = []
|
||||
var te = null
|
||||
# ##############################################################################
|
||||
# Keeps search results from the TextEdit
|
||||
# ##############################################################################
|
||||
class TextEditSearcher:
|
||||
var te: TextEdit
|
||||
var _last_term = ""
|
||||
var _last_pos = Vector2(-1, -1)
|
||||
var _ignore_caret_change = false
|
||||
|
||||
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
|
||||
func set_text_edit(which):
|
||||
te = which
|
||||
te.caret_changed.connect(_on_caret_changed)
|
||||
|
||||
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
|
||||
func _on_caret_changed():
|
||||
if _ignore_caret_change:
|
||||
_ignore_caret_change = false
|
||||
else:
|
||||
_last_pos = _get_caret()
|
||||
|
||||
func _get_caret():
|
||||
return Vector2(te.get_caret_column(), te.get_caret_line())
|
||||
|
||||
func _set_caret_and_sel(pos, len):
|
||||
te.set_caret_line(pos.y)
|
||||
te.set_caret_column(pos.x)
|
||||
if len > 0:
|
||||
te.select(pos.y, pos.x, pos.y, pos.x + len)
|
||||
|
||||
func _find(term, search_flags):
|
||||
var pos = _get_caret()
|
||||
if term == _last_term:
|
||||
if search_flags == 0:
|
||||
pos = _last_pos
|
||||
pos.x += 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
|
||||
pos = _last_pos
|
||||
pos.x -= 1
|
||||
|
||||
_last_term = text
|
||||
te.center_viewport_to_caret()
|
||||
return result
|
||||
var result = te.search(term, search_flags, pos.y, pos.x)
|
||||
# print('searching from ', pos, ' for "', term, '" = ', result)
|
||||
if result.y != -1:
|
||||
_ignore_caret_change = true
|
||||
_set_caret_and_sel(result, term.length())
|
||||
_last_pos = 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
|
||||
_last_term = term
|
||||
|
||||
func find_next(term):
|
||||
return _search_te(term, _cursor_to_pos())
|
||||
_find(term, 0)
|
||||
|
||||
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
|
||||
_find(term, te.SEARCH_BACKWARDS)
|
||||
|
||||
|
||||
# ##############################################################################
|
||||
# Start OutputText control code
|
||||
# ##############################################################################
|
||||
@onready var _ctrls = {
|
||||
output = $Output,
|
||||
copy_button = $Toolbar/CopyButton,
|
||||
|
@ -93,42 +66,83 @@ class SearchResults:
|
|||
clear_button = $Toolbar/ClearButton,
|
||||
word_wrap = $Toolbar/WordWrap,
|
||||
show_search = $Toolbar/ShowSearch,
|
||||
caret_position = $Toolbar/LblPosition,
|
||||
search_bar =
|
||||
{
|
||||
bar = $Search,
|
||||
search_term = $Search/SearchTerm,
|
||||
}
|
||||
}
|
||||
var _sr = SearchResults.new()
|
||||
|
||||
var _sr = TextEditSearcher.new()
|
||||
var _highlighter: CodeHighlighter
|
||||
var _font_name = null
|
||||
|
||||
|
||||
# Automatically used when running the OutputText scene from the editor. Changes
|
||||
# to this method only affect test-running the control through the editor.
|
||||
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)
|
||||
set_font_size(30)
|
||||
|
||||
_ctrls.output.queue_redraw()
|
||||
load_file("user://.gut_editor.bbcode")
|
||||
await get_tree().process_frame
|
||||
|
||||
show_search(true)
|
||||
_ctrls.output.set_caret_line(0)
|
||||
_ctrls.output.scroll_vertical = 0
|
||||
_ctrls.output.caret_changed.connect(_on_caret_changed)
|
||||
|
||||
|
||||
func _ready():
|
||||
_sr.te = _ctrls.output
|
||||
_sr.set_text_edit(_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()
|
||||
_ctrls.use_colors.button_pressed = true
|
||||
_use_highlighting(true)
|
||||
|
||||
if get_parent() == get_tree().root:
|
||||
_test_running_setup()
|
||||
|
||||
|
||||
func _on_caret_changed():
|
||||
var txt = str(
|
||||
"line:", _ctrls.output.get_caret_line(), " col:", _ctrls.output.get_caret_column()
|
||||
)
|
||||
_ctrls.caret_position.text = str(txt)
|
||||
|
||||
|
||||
# ------------------
|
||||
# Private
|
||||
# ------------------
|
||||
func _setup_colors():
|
||||
_ctrls.output.clear()
|
||||
|
||||
|
||||
# Call this after changes in colors and the like to get them to apply. reloads
|
||||
# the text of the output control.
|
||||
func _refresh_output():
|
||||
var orig_pos = _ctrls.output.scroll_vertical
|
||||
var text = _ctrls.output.text
|
||||
|
||||
_ctrls.output.text = text
|
||||
_ctrls.output.scroll_vertical = orig_pos
|
||||
|
||||
|
||||
func _create_highlighter(default_color = Color(1, 1, 1, 1)):
|
||||
var to_return = CodeHighlighter.new()
|
||||
|
||||
to_return.function_color = default_color
|
||||
to_return.number_color = default_color
|
||||
to_return.symbol_color = default_color
|
||||
to_return.member_variable_color = default_color
|
||||
|
||||
var keywords = [
|
||||
["Failed", Color.RED],
|
||||
["Passed", Color.GREEN],
|
||||
|
@ -139,34 +153,30 @@ func _setup_colors():
|
|||
]
|
||||
|
||||
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])
|
||||
to_return.add_keyword_color(keyword[0], keyword[1])
|
||||
|
||||
return to_return
|
||||
|
||||
|
||||
func _setup_colors():
|
||||
_ctrls.output.clear()
|
||||
|
||||
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)
|
||||
|
||||
_highlighter = _create_highlighter()
|
||||
_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)
|
||||
func _use_highlighting(should):
|
||||
if should:
|
||||
_ctrls.output.syntax_highlighter = _highlighter
|
||||
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)
|
||||
_ctrls.output.syntax_highlighter = null
|
||||
_refresh_output()
|
||||
|
||||
|
||||
# ------------------
|
||||
|
@ -177,7 +187,7 @@ func _on_CopyButton_pressed():
|
|||
|
||||
|
||||
func _on_UseColors_pressed():
|
||||
_ctrls.output.syntax_highlighter = _ctrls.use_colors.button_pressed
|
||||
_use_highlighting(_ctrls.use_colors.button_pressed)
|
||||
|
||||
|
||||
func _on_ClearButton_pressed():
|
||||
|
@ -215,12 +225,16 @@ func _on_SearchTerm_text_entered(new_text):
|
|||
|
||||
|
||||
func _on_SearchTerm_gui_input(event):
|
||||
if event is InputEventKey and !event.pressed and event.scancode == KEY_ESCAPE:
|
||||
if event is InputEventKey and !event.pressed and event.keycode == KEY_ESCAPE:
|
||||
show_search(false)
|
||||
|
||||
|
||||
func _on_WordWrap_pressed():
|
||||
_ctrls.output.wrap_enabled = _ctrls.word_wrap.pressed
|
||||
if _ctrls.word_wrap.button_pressed:
|
||||
_ctrls.output.wrap_mode = TextEdit.LINE_WRAPPING_BOUNDARY
|
||||
else:
|
||||
_ctrls.output.wrap_mode = TextEdit.LINE_WRAPPING_NONE
|
||||
|
||||
_ctrls.output.queue_redraw()
|
||||
|
||||
|
||||
|
@ -240,40 +254,57 @@ func search(text, start_pos, highlight = true):
|
|||
|
||||
|
||||
func copy_to_clipboard():
|
||||
var selected = _ctrls.output.get_selection_text()
|
||||
var selected = _ctrls.output.get_selected_text()
|
||||
if selected != "":
|
||||
OS.clipboard = selected
|
||||
DisplayServer.clipboard_set(selected)
|
||||
else:
|
||||
OS.clipboard = _ctrls.output.text
|
||||
DisplayServer.clipboard_set(_ctrls.output.text)
|
||||
|
||||
|
||||
func clear():
|
||||
_ctrls.output.text = ""
|
||||
|
||||
|
||||
func _set_font(font_name, custom_name):
|
||||
var rtl = _ctrls.output
|
||||
if font_name == null:
|
||||
rtl.add_theme_font_override(custom_name, null)
|
||||
else:
|
||||
var dyn_font = FontFile.new()
|
||||
dyn_font.load_dynamic_font("res://addons/gut/fonts/" + font_name + ".ttf")
|
||||
rtl.add_theme_font_override(custom_name, dyn_font)
|
||||
|
||||
|
||||
func set_all_fonts(base_name):
|
||||
_font_name = GutUtils.nvl(base_name, "Default")
|
||||
|
||||
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')
|
||||
_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')
|
||||
_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.set("theme_override_font_sizes/font_size", new_size)
|
||||
|
||||
|
||||
# rtl.add_theme_font_size_override("font", new_size)
|
||||
# rtl.add_theme_font_size_override("normal_font", new_size)
|
||||
# rtl.add_theme_font_size_override("bold_font", new_size)
|
||||
# rtl.add_theme_font_size_override("italics_font", new_size)
|
||||
# rtl.add_theme_font_size_override("bold_italics_font", new_size)
|
||||
|
||||
# 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
|
||||
|
@ -298,7 +329,7 @@ func load_file(path):
|
|||
return
|
||||
|
||||
var t = f.get_as_text()
|
||||
f.close()
|
||||
f = null # closes file
|
||||
_ctrls.output.text = t
|
||||
_ctrls.output.scroll_vertical = _ctrls.output.get_line_count()
|
||||
_ctrls.output.set_deferred("scroll_vertical", _ctrls.output.get_line_count())
|
||||
|
|
|
@ -1,113 +1,107 @@
|
|||
[gd_scene load_steps=4 format=2]
|
||||
[gd_scene load_steps=5 format=3 uid="uid://bqmo4dj64c7yl"]
|
||||
|
||||
[ext_resource path="res://addons/gut/gui/OutputText.gd" type="Script" id=1]
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/OutputText.gd" id="1"]
|
||||
|
||||
[sub_resource type="Image" id=3]
|
||||
[sub_resource type="Image" id="Image_abbh7"]
|
||||
data = {
|
||||
"data": PackedByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
|
||||
"format": "LumAlpha8",
|
||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 93, 93, 55, 255, 97, 97, 58, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 98, 98, 47, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 94, 94, 46, 255, 93, 93, 236, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
||||
"format": "RGBA8",
|
||||
"height": 16,
|
||||
"mipmaps": false,
|
||||
"width": 16
|
||||
}
|
||||
|
||||
[sub_resource type="ImageTexture" id=2]
|
||||
flags = 4
|
||||
flags = 4
|
||||
image = SubResource( 3 )
|
||||
size = Vector2( 16, 16 )
|
||||
[sub_resource type="ImageTexture" id="ImageTexture_x655i"]
|
||||
image = SubResource("Image_abbh7")
|
||||
|
||||
[sub_resource type="CodeHighlighter" id="CodeHighlighter_4pcgd"]
|
||||
number_color = Color(1, 1, 1, 1)
|
||||
symbol_color = Color(1, 1, 1, 1)
|
||||
function_color = Color(1, 1, 1, 1)
|
||||
member_variable_color = Color(1, 1, 1, 1)
|
||||
keyword_colors = {
|
||||
"ERROR": Color(1, 0, 0, 1),
|
||||
"Failed": Color(1, 0, 0, 1),
|
||||
"Orphans": Color(1, 1, 0, 1),
|
||||
"Passed": Color(0, 1, 0, 1),
|
||||
"Pending": Color(1, 1, 0, 1),
|
||||
"WARNING": Color(1, 1, 0, 1)
|
||||
}
|
||||
|
||||
[node name="OutputText" type="VBoxContainer"]
|
||||
offset_right = 862.0
|
||||
offset_bottom = 523.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource( 1 )
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="Toolbar" type="HBoxContainer" parent="."]
|
||||
offset_right = 862.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ShowSearch" type="Button" parent="Toolbar"]
|
||||
offset_right = 28.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
tooltip_text = "Search"
|
||||
toggle_mode = true
|
||||
icon = SubResource( 2 )
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="UseColors" type="Button" parent="Toolbar"]
|
||||
offset_left = 32.0
|
||||
offset_right = 60.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Colorize output.
|
||||
It's not the same as everywhere else (long story),
|
||||
but it is better than nothing."
|
||||
layout_mode = 2
|
||||
tooltip_text = "Colorized Text"
|
||||
toggle_mode = true
|
||||
pressed = true
|
||||
icon = SubResource( 2 )
|
||||
button_pressed = true
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="WordWrap" type="Button" parent="Toolbar"]
|
||||
offset_left = 64.0
|
||||
offset_right = 92.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Word wrap"
|
||||
layout_mode = 2
|
||||
tooltip_text = "Word Wrap"
|
||||
toggle_mode = true
|
||||
icon = SubResource( 2 )
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="Toolbar"]
|
||||
offset_left = 96.0
|
||||
offset_right = 743.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="LblPosition" type="Label" parent="Toolbar"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="CopyButton" type="Button" parent="Toolbar"]
|
||||
offset_left = 747.0
|
||||
offset_right = 798.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Copy to clipboard"
|
||||
layout_mode = 2
|
||||
text = " Copy "
|
||||
|
||||
[node name="ClearButton" type="Button" parent="Toolbar"]
|
||||
offset_left = 802.0
|
||||
offset_right = 862.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
text = " Clear "
|
||||
|
||||
[node name="Output" type="TextEdit" parent="."]
|
||||
offset_top = 28.0
|
||||
offset_right = 862.0
|
||||
offset_bottom = 523.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
readonly = true
|
||||
text = "Hello World
|
||||
This is a bunch of text
|
||||
That exists for you to see."
|
||||
deselect_on_focus_loss_enabled = false
|
||||
virtual_keyboard_enabled = false
|
||||
middle_mouse_paste_enabled = false
|
||||
highlight_all_occurrences = true
|
||||
highlight_current_line = true
|
||||
syntax_highlighter = true
|
||||
show_line_numbers = true
|
||||
smooth_scrolling = true
|
||||
syntax_highlighter = SubResource("CodeHighlighter_4pcgd")
|
||||
scroll_smooth = true
|
||||
|
||||
[node name="Search" type="HBoxContainer" parent="."]
|
||||
visible = false
|
||||
offset_top = 499.0
|
||||
offset_right = 862.0
|
||||
offset_bottom = 523.0
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SearchTerm" type="LineEdit" parent="Search"]
|
||||
offset_right = 804.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="SearchNext" type="Button" parent="Search"]
|
||||
offset_left = 808.0
|
||||
offset_right = 862.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Find next (enter)"
|
||||
layout_mode = 2
|
||||
text = "Next"
|
||||
|
||||
[node name="SearchPrev" type="Button" parent="Search"]
|
||||
offset_left = 808.0
|
||||
offset_right = 820.0
|
||||
offset_bottom = 20.0
|
||||
hint_tooltip = "Find previous (shift + enter)"
|
||||
layout_mode = 2
|
||||
text = "Prev"
|
||||
|
||||
[connection signal="pressed" from="Toolbar/ShowSearch" to="." method="_on_ShowSearch_pressed"]
|
||||
|
|
108
addons/gut/gui/ResizeHandle.gd
Normal file
108
addons/gut/gui/ResizeHandle.gd
Normal file
|
@ -0,0 +1,108 @@
|
|||
@tool
|
||||
extends ColorRect
|
||||
# #############################################################################
|
||||
# Resize Handle control. Place onto a control. Set the orientation, then
|
||||
# set the control that this should resize. Then you can resize the control
|
||||
# by dragging this thing around. It's pretty neat.
|
||||
# #############################################################################
|
||||
enum ORIENTATION { LEFT, RIGHT }
|
||||
|
||||
@export var orientation := ORIENTATION.RIGHT:
|
||||
get:
|
||||
return orientation
|
||||
set(val):
|
||||
orientation = val
|
||||
queue_redraw()
|
||||
@export var resize_control: Control = null
|
||||
@export var vertical_resize := true
|
||||
|
||||
var _line_width = .5
|
||||
var _line_color = Color(.4, .4, .4)
|
||||
var _active_line_color = Color(.3, .3, .3)
|
||||
var _invalid_line_color = Color(1, 0, 0)
|
||||
|
||||
var _grab_margin = 2
|
||||
var _line_space = 3
|
||||
var _num_lines = 8
|
||||
|
||||
var _mouse_down = false
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
|
||||
|
||||
func _draw():
|
||||
var c = _line_color
|
||||
if resize_control == null:
|
||||
c = _invalid_line_color
|
||||
elif _mouse_down:
|
||||
c = _active_line_color
|
||||
|
||||
if orientation == ORIENTATION.LEFT:
|
||||
_draw_resize_handle_left(c)
|
||||
else:
|
||||
_draw_resize_handle_right(c)
|
||||
|
||||
|
||||
func _gui_input(event):
|
||||
if resize_control == null:
|
||||
return
|
||||
|
||||
if orientation == ORIENTATION.LEFT:
|
||||
_handle_left_input(event)
|
||||
else:
|
||||
_handle_right_input(event)
|
||||
|
||||
|
||||
# Draw the lines in the corner to show where you can
|
||||
# drag to resize the dialog
|
||||
func _draw_resize_handle_right(color):
|
||||
var br = size
|
||||
|
||||
for i in range(_num_lines):
|
||||
var start = br - Vector2(i * _line_space, 0)
|
||||
var end = br - Vector2(0, i * _line_space)
|
||||
draw_line(start, end, color, _line_width, true)
|
||||
|
||||
|
||||
func _draw_resize_handle_left(color):
|
||||
var bl = Vector2(0, size.y)
|
||||
|
||||
for i in range(_num_lines):
|
||||
var start = bl + Vector2(i * _line_space, 0)
|
||||
var end = bl - Vector2(0, i * _line_space)
|
||||
draw_line(start, end, color, _line_width, true)
|
||||
|
||||
|
||||
func _handle_right_input(event: InputEvent):
|
||||
if event is InputEventMouseMotion:
|
||||
if (
|
||||
_mouse_down
|
||||
and event.global_position.x > 0
|
||||
and event.global_position.y < DisplayServer.window_get_size().y
|
||||
):
|
||||
if vertical_resize:
|
||||
resize_control.size.y += event.relative.y
|
||||
resize_control.size.x += event.relative.x
|
||||
elif event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT:
|
||||
_mouse_down = event.pressed
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _handle_left_input(event: InputEvent):
|
||||
if event is InputEventMouseMotion:
|
||||
if (
|
||||
_mouse_down
|
||||
and event.global_position.x > 0
|
||||
and event.global_position.y < DisplayServer.window_get_size().y
|
||||
):
|
||||
var start_size = resize_control.size
|
||||
resize_control.size.x -= event.relative.x
|
||||
if resize_control.size.x != start_size.x:
|
||||
resize_control.global_position.x += event.relative.x
|
||||
|
||||
if vertical_resize:
|
||||
resize_control.size.y += event.relative.y
|
||||
elif event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT:
|
||||
_mouse_down = event.pressed
|
||||
queue_redraw()
|
8
addons/gut/gui/ResizeHandle.tscn
Normal file
8
addons/gut/gui/ResizeHandle.tscn
Normal file
|
@ -0,0 +1,8 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://bvrqqgjpyouse"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/ResizeHandle.gd" id="1_oi5ed"]
|
||||
|
||||
[node name="ResizeHandle" type="ColorRect"]
|
||||
custom_minimum_size = Vector2(20, 20)
|
||||
color = Color(1, 1, 1, 0)
|
||||
script = ExtResource("1_oi5ed")
|
360
addons/gut/gui/ResultsTree.gd
Normal file
360
addons/gut/gui/ResultsTree.gd
Normal file
|
@ -0,0 +1,360 @@
|
|||
@tool
|
||||
extends Control
|
||||
|
||||
var _show_orphans = true
|
||||
var show_orphans = true:
|
||||
get:
|
||||
return _show_orphans
|
||||
set(val):
|
||||
_show_orphans = val
|
||||
|
||||
var _hide_passing = true
|
||||
var hide_passing = true:
|
||||
get:
|
||||
return _hide_passing
|
||||
set(val):
|
||||
_hide_passing = val
|
||||
|
||||
var _icons = {
|
||||
red = load("res://addons/gut/images/red.png"),
|
||||
green = load("res://addons/gut/images/green.png"),
|
||||
yellow = load("res://addons/gut/images/yellow.png"),
|
||||
}
|
||||
const _col_1_bg_color = Color(0, 0, 0, .1)
|
||||
var _max_icon_width = 10
|
||||
var _root: TreeItem
|
||||
|
||||
@onready var _ctrls = {tree = $Tree, lbl_overlay = $Tree/TextOverlay}
|
||||
|
||||
signal item_selected(script_path, inner_class, test_name, line_number)
|
||||
|
||||
|
||||
# -------------------
|
||||
# Private
|
||||
# -------------------
|
||||
func _ready():
|
||||
_root = _ctrls.tree.create_item()
|
||||
_root = _ctrls.tree.create_item()
|
||||
_ctrls.tree.set_hide_root(true)
|
||||
_ctrls.tree.columns = 2
|
||||
_ctrls.tree.set_column_expand(0, true)
|
||||
_ctrls.tree.set_column_expand(1, false)
|
||||
_ctrls.tree.set_column_clip_content(0, true)
|
||||
|
||||
$Tree.item_selected.connect(_on_tree_item_selected)
|
||||
|
||||
if get_parent() == get_tree().root:
|
||||
_test_running_setup()
|
||||
|
||||
|
||||
func _test_running_setup():
|
||||
load_json_file("user://.gut_editor.json")
|
||||
|
||||
|
||||
func _on_tree_item_selected():
|
||||
var item = _ctrls.tree.get_selected()
|
||||
var item_meta = item.get_metadata(0)
|
||||
var item_type = null
|
||||
|
||||
# Only select the left side of the tree item, cause I like that better.
|
||||
# you can still click the right, but only the left gets highlighted.
|
||||
if item.is_selected(1):
|
||||
item.deselect(1)
|
||||
item.select(0)
|
||||
|
||||
if item_meta == null:
|
||||
return
|
||||
else:
|
||||
item_type = item_meta.type
|
||||
|
||||
var script_path = ""
|
||||
var line = -1
|
||||
var test_name = ""
|
||||
var inner_class = ""
|
||||
|
||||
if item_type == "test":
|
||||
var s_item = item.get_parent()
|
||||
script_path = s_item.get_metadata(0)["path"]
|
||||
inner_class = s_item.get_metadata(0)["inner_class"]
|
||||
line = -1
|
||||
test_name = item.get_text(0)
|
||||
elif item_type == "assert":
|
||||
var s_item = item.get_parent().get_parent()
|
||||
script_path = s_item.get_metadata(0)["path"]
|
||||
inner_class = s_item.get_metadata(0)["inner_class"]
|
||||
line = _get_line_number_from_assert_msg(item.get_text(0))
|
||||
test_name = item.get_parent().get_text(0)
|
||||
elif item_type == "script":
|
||||
script_path = item.get_metadata(0)["path"]
|
||||
if item.get_parent() != _root:
|
||||
inner_class = item.get_text(0)
|
||||
line = -1
|
||||
test_name = ""
|
||||
else:
|
||||
return
|
||||
|
||||
item_selected.emit(script_path, inner_class, test_name, line)
|
||||
|
||||
|
||||
func _get_line_number_from_assert_msg(msg):
|
||||
var line = -1
|
||||
if msg.find("at line") > 0:
|
||||
line = msg.split("at line")[-1].split(" ")[-1].to_int()
|
||||
return line
|
||||
|
||||
|
||||
func _get_path_and_inner_class_name_from_test_path(path):
|
||||
var to_return = {path = "", inner_class = ""}
|
||||
|
||||
to_return.path = path
|
||||
if !path.ends_with(".gd"):
|
||||
var loc = path.find(".gd")
|
||||
to_return.inner_class = path.split(".")[-1]
|
||||
to_return.path = path.substr(0, loc + 3)
|
||||
return to_return
|
||||
|
||||
|
||||
func _find_script_item_with_path(path):
|
||||
var items = _root.get_children()
|
||||
var to_return = null
|
||||
|
||||
var idx = 0
|
||||
while idx < items.size() and to_return == null:
|
||||
var item = items[idx]
|
||||
if item.get_metadata(0).path == path:
|
||||
to_return = item
|
||||
else:
|
||||
idx += 1
|
||||
|
||||
return to_return
|
||||
|
||||
|
||||
func _add_script_tree_item(script_path, script_json):
|
||||
var path_info = _get_path_and_inner_class_name_from_test_path(script_path)
|
||||
var item_text = script_path
|
||||
var parent = _root
|
||||
|
||||
if path_info.inner_class != "":
|
||||
parent = _find_script_item_with_path(path_info.path)
|
||||
item_text = path_info.inner_class
|
||||
if parent == null:
|
||||
parent = _add_script_tree_item(path_info.path, {})
|
||||
|
||||
parent.get_metadata(0).inner_tests += script_json["props"]["tests"]
|
||||
parent.get_metadata(0).inner_passing += script_json["props"]["tests"]
|
||||
parent.get_metadata(0).inner_passing -= script_json["props"]["failures"]
|
||||
parent.get_metadata(0).inner_passing -= script_json["props"]["pending"]
|
||||
|
||||
var total_text = str("All ", parent.get_metadata(0).inner_tests, " passed")
|
||||
if parent.get_metadata(0).inner_passing != parent.get_metadata(0).inner_tests:
|
||||
total_text = str(
|
||||
parent.get_metadata(0).inner_passing,
|
||||
"/",
|
||||
parent.get_metadata(0).inner_tests,
|
||||
" passed."
|
||||
)
|
||||
parent.set_text(1, total_text)
|
||||
|
||||
var item = _ctrls.tree.create_item(parent)
|
||||
item.set_text(0, item_text)
|
||||
var meta = {
|
||||
"type": "script",
|
||||
"path": path_info.path,
|
||||
"inner_class": path_info.inner_class,
|
||||
"json": script_json,
|
||||
"inner_passing": 0,
|
||||
"inner_tests": 0
|
||||
}
|
||||
item.set_metadata(0, meta)
|
||||
item.set_custom_bg_color(1, _col_1_bg_color)
|
||||
|
||||
return item
|
||||
|
||||
|
||||
func _add_assert_item(text, icon, parent_item):
|
||||
# print(' * adding assert')
|
||||
var assert_item = _ctrls.tree.create_item(parent_item)
|
||||
assert_item.set_icon_max_width(0, _max_icon_width)
|
||||
assert_item.set_text(0, text)
|
||||
assert_item.set_metadata(0, {"type": "assert"})
|
||||
assert_item.set_icon(0, icon)
|
||||
assert_item.set_custom_bg_color(1, _col_1_bg_color)
|
||||
|
||||
return assert_item
|
||||
|
||||
|
||||
func _add_test_tree_item(test_name, test_json, script_item):
|
||||
# print(' * adding test ', test_name)
|
||||
var no_orphans_to_show = !_show_orphans or (_show_orphans and test_json.orphans == 0)
|
||||
if _hide_passing and test_json["status"] == "pass" and no_orphans_to_show:
|
||||
return
|
||||
|
||||
var item = _ctrls.tree.create_item(script_item)
|
||||
var status = test_json["status"]
|
||||
var meta = {"type": "test", "json": test_json}
|
||||
|
||||
item.set_text(0, test_name)
|
||||
item.set_text(1, status)
|
||||
item.set_text_alignment(1, HORIZONTAL_ALIGNMENT_RIGHT)
|
||||
item.set_custom_bg_color(1, _col_1_bg_color)
|
||||
|
||||
item.set_metadata(0, meta)
|
||||
item.set_icon_max_width(0, _max_icon_width)
|
||||
|
||||
var orphan_text = "orphans"
|
||||
if test_json.orphans == 1:
|
||||
orphan_text = "orphan"
|
||||
orphan_text = str(test_json.orphans, " ", orphan_text)
|
||||
|
||||
if status == "pass" and no_orphans_to_show:
|
||||
item.set_icon(0, _icons.green)
|
||||
elif status == "pass" and !no_orphans_to_show:
|
||||
item.set_icon(0, _icons.yellow)
|
||||
item.set_text(1, orphan_text)
|
||||
elif status == "fail":
|
||||
item.set_icon(0, _icons.red)
|
||||
else:
|
||||
item.set_icon(0, _icons.yellow)
|
||||
|
||||
if !_hide_passing:
|
||||
for passing in test_json.passing:
|
||||
_add_assert_item("pass: " + passing, _icons.green, item)
|
||||
|
||||
for failure in test_json.failing:
|
||||
_add_assert_item("fail: " + failure.replace("\n", ""), _icons.red, item)
|
||||
|
||||
for pending in test_json.pending:
|
||||
_add_assert_item("pending: " + pending.replace("\n", ""), _icons.yellow, item)
|
||||
|
||||
if status != "pass" and !no_orphans_to_show:
|
||||
_add_assert_item(orphan_text, _icons.yellow, item)
|
||||
|
||||
return item
|
||||
|
||||
|
||||
func _add_script_to_tree(key, script_json):
|
||||
var tests = script_json["tests"]
|
||||
var test_keys = tests.keys()
|
||||
var s_item = _add_script_tree_item(key, script_json)
|
||||
var bad_count = 0
|
||||
|
||||
for test_key in test_keys:
|
||||
var t_item = _add_test_tree_item(test_key, tests[test_key], s_item)
|
||||
if tests[test_key].status != "pass":
|
||||
bad_count += 1
|
||||
elif t_item != null:
|
||||
t_item.collapsed = true
|
||||
|
||||
if s_item.get_children().size() == 0:
|
||||
s_item.free()
|
||||
else:
|
||||
var total_text = str("All ", test_keys.size(), " passed")
|
||||
if bad_count == 0:
|
||||
s_item.collapsed = true
|
||||
else:
|
||||
total_text = str(test_keys.size() - bad_count, "/", test_keys.size(), " passed")
|
||||
s_item.set_text(1, total_text)
|
||||
|
||||
|
||||
func _free_childless_scripts():
|
||||
var items = _root.get_children()
|
||||
for item in items:
|
||||
var next_item = item.get_next()
|
||||
if item.get_children().size() == 0:
|
||||
item.free()
|
||||
item = next_item
|
||||
|
||||
|
||||
func _show_all_passed():
|
||||
if _root.get_children().size() == 0:
|
||||
add_centered_text("Everything passed!")
|
||||
|
||||
|
||||
func _load_result_tree(j):
|
||||
var scripts = j["test_scripts"]["scripts"]
|
||||
var script_keys = scripts.keys()
|
||||
# if we made it here, the json is valid and we did something, otherwise the
|
||||
# 'nothing to see here' should be visible.
|
||||
clear_centered_text()
|
||||
|
||||
for key in script_keys:
|
||||
if scripts[key]["props"]["tests"] > 0:
|
||||
_add_script_to_tree(key, scripts[key])
|
||||
|
||||
_free_childless_scripts()
|
||||
_show_all_passed()
|
||||
|
||||
|
||||
# -------------------
|
||||
# Public
|
||||
# -------------------
|
||||
func load_json_file(path):
|
||||
var file = FileAccess.open(path, FileAccess.READ)
|
||||
var text = ""
|
||||
if file != null:
|
||||
text = file.get_as_text()
|
||||
|
||||
if text != "":
|
||||
var test_json_conv = JSON.new()
|
||||
var result = test_json_conv.parse(text)
|
||||
if result != OK:
|
||||
add_centered_text(
|
||||
str(
|
||||
path,
|
||||
" has invalid json in it \n",
|
||||
"Error ",
|
||||
result,
|
||||
"@",
|
||||
test_json_conv.get_error_line(),
|
||||
"\n",
|
||||
test_json_conv.get_error_message()
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
var data = test_json_conv.get_data()
|
||||
load_json_results(data)
|
||||
else:
|
||||
add_centered_text(str(path, " was empty or does not exist."))
|
||||
|
||||
|
||||
func load_json_results(j):
|
||||
clear()
|
||||
_load_result_tree(j)
|
||||
|
||||
|
||||
func clear():
|
||||
_ctrls.tree.clear()
|
||||
_root = _ctrls.tree.create_item()
|
||||
|
||||
|
||||
func set_summary_min_width(width):
|
||||
_ctrls.tree.set_column_custom_minimum_width(1, width)
|
||||
|
||||
|
||||
func add_centered_text(t):
|
||||
_ctrls.lbl_overlay.visible = true
|
||||
_ctrls.lbl_overlay.text = t
|
||||
|
||||
|
||||
func clear_centered_text():
|
||||
_ctrls.lbl_overlay.visible = false
|
||||
_ctrls.lbl_overlay.text = ""
|
||||
|
||||
|
||||
func collapse_all():
|
||||
set_collapsed_on_all(_root, true)
|
||||
|
||||
|
||||
func expand_all():
|
||||
set_collapsed_on_all(_root, false)
|
||||
|
||||
|
||||
func set_collapsed_on_all(item, value):
|
||||
item.set_collapsed_recursive(value)
|
||||
if item == _root and value:
|
||||
item.set_collapsed(false)
|
||||
|
||||
|
||||
func get_selected():
|
||||
return _ctrls.tree.get_selected()
|
32
addons/gut/gui/ResultsTree.tscn
Normal file
32
addons/gut/gui/ResultsTree.tscn
Normal file
|
@ -0,0 +1,32 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://dls5r5f6157nq"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/ResultsTree.gd" id="1_b4uub"]
|
||||
|
||||
[node name="ResultsTree" type="VBoxContainer"]
|
||||
custom_minimum_size = Vector2(10, 10)
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_right = -70.0
|
||||
offset_bottom = -104.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource("1_b4uub")
|
||||
|
||||
[node name="Tree" type="Tree" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
columns = 2
|
||||
hide_root = true
|
||||
|
||||
[node name="TextOverlay" type="Label" parent="Tree"]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
|
@ -16,7 +16,7 @@ var _editors = null
|
|||
var _cur_editor = null
|
||||
var _last_line = -1
|
||||
var _cur_script_path = null
|
||||
var _last_info = null
|
||||
var _last_info = {script = null, inner_class = null, test_method = null}
|
||||
|
||||
signal run_tests(what)
|
||||
|
||||
|
@ -26,6 +26,8 @@ func _ready():
|
|||
_ctrls.btn_script.visible = false
|
||||
_ctrls.btn_inner.visible = false
|
||||
_ctrls.btn_method.visible = false
|
||||
_ctrls.arrow_1.visible = false
|
||||
_ctrls.arrow_2.visible = false
|
||||
|
||||
|
||||
# ----------------
|
||||
|
@ -34,11 +36,13 @@ func _ready():
|
|||
func _set_editor(which):
|
||||
_last_line = -1
|
||||
if _cur_editor != null and _cur_editor.get_ref():
|
||||
_cur_editor.get_ref().disconnect("cursor_changed", Callable(self, "_on_cursor_changed"))
|
||||
# _cur_editor.get_ref().disconnect('cursor_changed',Callable(self,'_on_cursor_changed'))
|
||||
_cur_editor.get_ref().caret_changed.disconnect(_on_cursor_changed)
|
||||
|
||||
if which != null:
|
||||
_cur_editor = weakref(which)
|
||||
which.connect("cursor_changed", Callable(self, "_on_cursor_changed"), [which])
|
||||
which.caret_changed.connect(_on_cursor_changed.bind(which))
|
||||
# which.connect('cursor_changed',Callable(self,'_on_cursor_changed'),[which])
|
||||
|
||||
_last_line = which.get_caret_line()
|
||||
_last_info = _editors.get_line_info()
|
||||
|
@ -52,12 +56,12 @@ func _update_buttons(info):
|
|||
_ctrls.btn_inner.visible = info.inner_class != null
|
||||
_ctrls.arrow_1.visible = info.inner_class != null
|
||||
_ctrls.btn_inner.text = str(info.inner_class)
|
||||
_ctrls.btn_inner.hint_tooltip = str("Run all tests in Inner-Test-Class ", info.inner_class)
|
||||
_ctrls.btn_inner.tooltip_text = str("Run all tests in Inner-Test-Class ", info.inner_class)
|
||||
|
||||
_ctrls.btn_method.visible = info.test_method != null
|
||||
_ctrls.arrow_2.visible = info.test_method != null
|
||||
_ctrls.btn_method.text = str(info.test_method)
|
||||
_ctrls.btn_method.hint_tooltip = str("Run test ", info.test_method)
|
||||
_ctrls.btn_method.tooltip_text = str("Run test ", info.test_method)
|
||||
|
||||
# The button's new size won't take effect until the next frame.
|
||||
# This appears to be what was causing the button to not be clickable the
|
||||
|
@ -66,7 +70,7 @@ func _update_buttons(info):
|
|||
|
||||
|
||||
func _update_size():
|
||||
custom_minimum_size.x = _ctrls.btn_method.size.x + _ctrls.btn_method.rect_position.x
|
||||
custom_minimum_size.x = _ctrls.btn_method.size.x + _ctrls.btn_method.position.x
|
||||
|
||||
|
||||
# ----------------
|
||||
|
@ -110,9 +114,12 @@ func set_script_text_editors(value):
|
|||
func activate_for_script(path):
|
||||
_ctrls.btn_script.visible = true
|
||||
_ctrls.btn_script.text = path.get_file()
|
||||
_ctrls.btn_script.hint_tooltip = str("Run all tests in script ", path)
|
||||
_ctrls.btn_script.tooltip_text = str("Run all tests in script ", path)
|
||||
_cur_script_path = path
|
||||
_editors.refresh()
|
||||
# We have to wait a beat for the visibility to change on
|
||||
# the editors, otherwise we always get the first one.
|
||||
await get_tree().process_frame
|
||||
_set_editor(_editors.get_current_text_edit())
|
||||
|
||||
|
||||
|
@ -145,7 +152,4 @@ func search_current_editor_for_text(txt):
|
|||
var result = te.search(txt, 0, 0, 0)
|
||||
var to_return = -1
|
||||
|
||||
if result.size() > 0:
|
||||
to_return = result[TextEdit.SEARCH_RESULT_LINE]
|
||||
|
||||
return to_return
|
||||
|
|
|
@ -1,79 +1,64 @@
|
|||
[gd_scene load_steps=4 format=2]
|
||||
[gd_scene load_steps=4 format=3 uid="uid://0yunjxtaa8iw"]
|
||||
|
||||
[ext_resource path="res://addons/gut/gui/RunAtCursor.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/gut/gui/play.png" type="Texture2D" id=2]
|
||||
[ext_resource path="res://addons/gut/gui/arrow.png" type="Texture2D" id=3]
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/RunAtCursor.gd" id="1"]
|
||||
[ext_resource type="Texture2D" uid="uid://cr6tvdv0ve6cv" path="res://addons/gut/gui/play.png" id="2"]
|
||||
[ext_resource type="Texture2D" uid="uid://6wra5rxmfsrl" path="res://addons/gut/gui/arrow.png" id="3"]
|
||||
|
||||
[node name="RunAtCursor" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 1.0
|
||||
offset_bottom = -527.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="HBox" type="HBoxContainer" parent="."]
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="LblNoneSelected" type="Label" parent="HBox"]
|
||||
offset_top = 29.0
|
||||
offset_right = 50.0
|
||||
offset_bottom = 43.0
|
||||
layout_mode = 2
|
||||
text = "<None>"
|
||||
|
||||
[node name="BtnRunScript" type="Button" parent="HBox"]
|
||||
visible = false
|
||||
offset_left = 54.0
|
||||
offset_right = 140.0
|
||||
offset_bottom = 73.0
|
||||
layout_mode = 2
|
||||
text = "<script>"
|
||||
icon = ExtResource( 2 )
|
||||
icon = ExtResource("2")
|
||||
|
||||
[node name="Arrow1" type="TextureButton" parent="HBox"]
|
||||
visible = false
|
||||
offset_left = 54.0
|
||||
offset_right = 78.0
|
||||
offset_bottom = 73.0
|
||||
custom_minimum_size = Vector2( 24, 0 )
|
||||
texture_normal = ExtResource( 3 )
|
||||
expand = true
|
||||
custom_minimum_size = Vector2(24, 0)
|
||||
layout_mode = 2
|
||||
texture_normal = ExtResource("3")
|
||||
stretch_mode = 3
|
||||
|
||||
[node name="BtnRunInnerClass" type="Button" parent="HBox"]
|
||||
visible = false
|
||||
offset_left = 134.0
|
||||
offset_right = 243.0
|
||||
offset_bottom = 73.0
|
||||
layout_mode = 2
|
||||
text = "<inner class>"
|
||||
icon = ExtResource( 2 )
|
||||
icon = ExtResource("2")
|
||||
|
||||
[node name="Arrow2" type="TextureButton" parent="HBox"]
|
||||
visible = false
|
||||
offset_left = 54.0
|
||||
offset_right = 78.0
|
||||
offset_bottom = 73.0
|
||||
custom_minimum_size = Vector2( 24, 0 )
|
||||
texture_normal = ExtResource( 3 )
|
||||
expand = true
|
||||
custom_minimum_size = Vector2(24, 0)
|
||||
layout_mode = 2
|
||||
texture_normal = ExtResource("3")
|
||||
stretch_mode = 3
|
||||
|
||||
[node name="BtnRunMethod" type="Button" parent="HBox"]
|
||||
visible = false
|
||||
offset_left = 247.0
|
||||
offset_right = 337.0
|
||||
offset_bottom = 73.0
|
||||
layout_mode = 2
|
||||
text = "<method>"
|
||||
icon = ExtResource( 2 )
|
||||
icon = ExtResource("2")
|
||||
|
||||
[connection signal="pressed" from="HBox/BtnRunScript" to="." method="_on_BtnRunScript_pressed"]
|
||||
[connection signal="pressed" from="HBox/BtnRunInnerClass" to="." method="_on_BtnRunInnerClass_pressed"]
|
||||
|
|
|
@ -1,31 +1,14 @@
|
|||
extends Control
|
||||
@tool
|
||||
extends Control
|
||||
|
||||
var _interface = null
|
||||
var _utils = load("res://addons/gut/utils.gd").new()
|
||||
var _hide_passing = true
|
||||
var _font = null
|
||||
var _font_size = null
|
||||
var _root = null
|
||||
var _max_icon_width = 10
|
||||
var _editors = null # script_text_editor_controls.gd
|
||||
var _show_orphans = true
|
||||
var _output_control = null
|
||||
|
||||
const _col_1_bg_color = Color(0, 0, 0, .1)
|
||||
|
||||
var _icons = {
|
||||
red = load("res://addons/gut/images/red.png"),
|
||||
green = load("res://addons/gut/images/green.png"),
|
||||
yellow = load("res://addons/gut/images/yellow.png"),
|
||||
}
|
||||
|
||||
signal search_for_text(text)
|
||||
|
||||
@onready var _ctrls = {
|
||||
tree = $VBox/Output/Scroll/Tree,
|
||||
lbl_overlay = $VBox/Output/OverlayMessage,
|
||||
chk_hide_passing = $VBox/Toolbar/HidePassing,
|
||||
toolbar =
|
||||
{
|
||||
toolbar = $VBox/Toolbar,
|
||||
|
@ -40,9 +23,36 @@ signal search_for_text(text)
|
|||
}
|
||||
|
||||
|
||||
func _ready():
|
||||
var f = null
|
||||
if $FontSampler.get_label_settings() == null:
|
||||
f = get_theme_default_font()
|
||||
else:
|
||||
f = $FontSampler.get_label_settings().font
|
||||
var s_size = f.get_string_size("000 of 000 passed")
|
||||
_ctrls.tree.set_summary_min_width(s_size.x)
|
||||
|
||||
_set_toolbutton_icon(_ctrls.toolbar.collapse, "CollapseTree", "c")
|
||||
_set_toolbutton_icon(_ctrls.toolbar.collapse_all, "CollapseTree", "c")
|
||||
_set_toolbutton_icon(_ctrls.toolbar.expand, "ExpandTree", "e")
|
||||
_set_toolbutton_icon(_ctrls.toolbar.expand_all, "ExpandTree", "e")
|
||||
_set_toolbutton_icon(_ctrls.toolbar.show_script, "Script", "ss")
|
||||
_set_toolbutton_icon(_ctrls.toolbar.scroll_output, "Font", "so")
|
||||
|
||||
_ctrls.tree.hide_passing = true
|
||||
_ctrls.toolbar.hide_passing.button_pressed = false
|
||||
_ctrls.tree.show_orphans = true
|
||||
_ctrls.tree.item_selected.connect(_on_item_selected)
|
||||
|
||||
if get_parent() == get_tree().root:
|
||||
_test_running_setup()
|
||||
|
||||
call_deferred("_update_min_width")
|
||||
|
||||
|
||||
func _test_running_setup():
|
||||
_hide_passing = true
|
||||
_show_orphans = true
|
||||
_ctrls.tree.hide_passing = true
|
||||
_ctrls.tree.show_orphans = true
|
||||
var _gut_config = load("res://addons/gut/gut_config.gd").new()
|
||||
_gut_config.load_panel_options("res://.gut_editor_config.json")
|
||||
set_font(
|
||||
|
@ -50,7 +60,7 @@ func _test_running_setup():
|
|||
)
|
||||
|
||||
_ctrls.toolbar.hide_passing.text = "[hp]"
|
||||
load_json_file("user://.gut_editor.json")
|
||||
_ctrls.tree.load_json_file("user://.gut_editor.json")
|
||||
|
||||
|
||||
func _set_toolbutton_icon(btn, icon_name, text):
|
||||
|
@ -60,51 +70,17 @@ func _set_toolbutton_icon(btn, icon_name, text):
|
|||
btn.text = str("[", text, "]")
|
||||
|
||||
|
||||
func _ready():
|
||||
var f = null
|
||||
if $FontSampler.get_label_settings() == null:
|
||||
f = get_theme_default_font()
|
||||
else:
|
||||
f = $FontSampler.get_label_settings().font
|
||||
var s_size = f.get_string_size("000 of 000 passed")
|
||||
_root = _ctrls.tree.create_item()
|
||||
_ctrls.tree.set_hide_root(true)
|
||||
_ctrls.tree.columns = 2
|
||||
_ctrls.tree.set_column_expand(0, true)
|
||||
_ctrls.tree.set_column_expand(1, false)
|
||||
_ctrls.tree.set_column_custom_minimum_width(1, s_size.x)
|
||||
|
||||
_set_toolbutton_icon(_ctrls.toolbar.collapse, "CollapseTree", "c")
|
||||
_set_toolbutton_icon(_ctrls.toolbar.collapse_all, "CollapseTree", "c")
|
||||
_set_toolbutton_icon(_ctrls.toolbar.expand, "ExpandTree", "e")
|
||||
_set_toolbutton_icon(_ctrls.toolbar.expand_all, "ExpandTree", "e")
|
||||
_set_toolbutton_icon(_ctrls.toolbar.show_script, "Script", "ss")
|
||||
_set_toolbutton_icon(_ctrls.toolbar.scroll_output, "Font", "so")
|
||||
|
||||
_ctrls.toolbar.hide_passing.set(
|
||||
"custom_icons/checked", get_theme_icon("GuiVisibilityHidden", "EditorIcons")
|
||||
)
|
||||
_ctrls.toolbar.hide_passing.set(
|
||||
"custom_icons/unchecked", get_theme_icon("GuiVisibilityVisible", "EditorIcons")
|
||||
)
|
||||
|
||||
if get_parent() == get_tree().root:
|
||||
_test_running_setup()
|
||||
|
||||
call_deferred("_update_min_width")
|
||||
|
||||
|
||||
func _update_min_width():
|
||||
custom_minimum_size.x = _ctrls.toolbar.toolbar.size.x
|
||||
|
||||
|
||||
func _open_file(path, line_number):
|
||||
func _open_script_in_editor(path, line_number):
|
||||
if _interface == null:
|
||||
print("Too soon, wait a bit and try again.")
|
||||
return
|
||||
|
||||
var r = load(path)
|
||||
if line_number != -1:
|
||||
if line_number != null and line_number != -1:
|
||||
_interface.edit_script(r, line_number)
|
||||
else:
|
||||
_interface.edit_script(r)
|
||||
|
@ -113,211 +89,6 @@ func _open_file(path, line_number):
|
|||
_interface.set_main_screen_editor("Script")
|
||||
|
||||
|
||||
func _add_script_tree_item(script_path, script_json):
|
||||
var path_info = _get_path_and_inner_class_name_from_test_path(script_path)
|
||||
# print('* adding script ', path_info)
|
||||
var item_text = script_path
|
||||
var parent = _root
|
||||
|
||||
if path_info.inner_class != "":
|
||||
parent = _find_script_item_with_path(path_info.path)
|
||||
item_text = path_info.inner_class
|
||||
if parent == null:
|
||||
parent = _add_script_tree_item(path_info.path, {})
|
||||
|
||||
var item = _ctrls.tree.create_item(parent)
|
||||
item.set_text(0, item_text)
|
||||
var meta = {
|
||||
"type": "script",
|
||||
"path": path_info.path,
|
||||
"inner_class": path_info.inner_class,
|
||||
"json": script_json
|
||||
}
|
||||
item.set_metadata(0, meta)
|
||||
item.set_custom_bg_color(1, _col_1_bg_color)
|
||||
|
||||
return item
|
||||
|
||||
|
||||
func _add_assert_item(text, icon, parent_item):
|
||||
# print(' * adding assert')
|
||||
var assert_item = _ctrls.tree.create_item(parent_item)
|
||||
assert_item.set_icon_max_width(0, _max_icon_width)
|
||||
assert_item.set_text(0, text)
|
||||
assert_item.set_metadata(0, {"type": "assert"})
|
||||
assert_item.set_icon(0, icon)
|
||||
assert_item.set_custom_bg_color(1, _col_1_bg_color)
|
||||
|
||||
return assert_item
|
||||
|
||||
|
||||
func _add_test_tree_item(test_name, test_json, script_item):
|
||||
# print(' * adding test ', test_name)
|
||||
var no_orphans_to_show = !_show_orphans or (_show_orphans and test_json.orphans == 0)
|
||||
if _hide_passing and test_json["status"] == "pass" and no_orphans_to_show:
|
||||
return
|
||||
|
||||
var item = _ctrls.tree.create_item(script_item)
|
||||
var status = test_json["status"]
|
||||
var meta = {"type": "test", "json": test_json}
|
||||
|
||||
item.set_text(0, test_name)
|
||||
item.set_text(1, status)
|
||||
item.set_text_alignment(1, HORIZONTAL_ALIGNMENT_RIGHT)
|
||||
item.set_custom_bg_color(1, _col_1_bg_color)
|
||||
|
||||
item.set_metadata(0, meta)
|
||||
item.set_icon_max_width(0, _max_icon_width)
|
||||
|
||||
var orphan_text = "orphans"
|
||||
if test_json.orphans == 1:
|
||||
orphan_text = "orphan"
|
||||
orphan_text = str(test_json.orphans, " ", orphan_text)
|
||||
|
||||
if status == "pass" and no_orphans_to_show:
|
||||
item.set_icon(0, _icons.green)
|
||||
elif status == "pass" and !no_orphans_to_show:
|
||||
item.set_icon(0, _icons.yellow)
|
||||
item.set_text(1, orphan_text)
|
||||
elif status == "fail":
|
||||
item.set_icon(0, _icons.red)
|
||||
else:
|
||||
item.set_icon(0, _icons.yellow)
|
||||
|
||||
if !_hide_passing:
|
||||
for passing in test_json.passing:
|
||||
_add_assert_item("pass: " + passing, _icons.green, item)
|
||||
|
||||
for failure in test_json.failing:
|
||||
_add_assert_item("fail: " + failure.replace("\n", ""), _icons.red, item)
|
||||
|
||||
for pending in test_json.pending:
|
||||
_add_assert_item("pending: " + pending.replace("\n", ""), _icons.yellow, item)
|
||||
|
||||
if status != "pass" and !no_orphans_to_show:
|
||||
_add_assert_item(orphan_text, _icons.yellow, item)
|
||||
|
||||
return item
|
||||
|
||||
|
||||
func _load_result_tree(j):
|
||||
var scripts = j["test_scripts"]["scripts"]
|
||||
var script_keys = scripts.keys()
|
||||
# if we made it here, the json is valid and we did something, otherwise the
|
||||
# 'nothing to see here' should be visible.
|
||||
clear_centered_text()
|
||||
|
||||
var _last_script_item = null
|
||||
for key in script_keys:
|
||||
var tests = scripts[key]["tests"]
|
||||
var test_keys = tests.keys()
|
||||
var s_item = _add_script_tree_item(key, scripts[key])
|
||||
var bad_count = 0
|
||||
|
||||
for test_key in test_keys:
|
||||
var t_item = _add_test_tree_item(test_key, tests[test_key], s_item)
|
||||
if tests[test_key].status != "pass":
|
||||
bad_count += 1
|
||||
elif t_item != null:
|
||||
t_item.collapsed = true
|
||||
|
||||
# get_children returns the first child or null. its a dumb name.
|
||||
if s_item.get_children() == null:
|
||||
# var m = s_item.get_metadata(0)
|
||||
# print('!! Deleting ', m.path, ' ', m.inner_class)
|
||||
s_item.free()
|
||||
else:
|
||||
var total_text = str(test_keys.size(), " passed")
|
||||
# s_item.set_text_alignment(1, s_item.ALIGN_LEFT)
|
||||
if bad_count == 0:
|
||||
s_item.collapsed = true
|
||||
else:
|
||||
total_text = str(test_keys.size() - bad_count, " of ", test_keys.size(), " passed")
|
||||
s_item.set_text(1, total_text)
|
||||
|
||||
_free_childless_scripts()
|
||||
_show_all_passed()
|
||||
|
||||
|
||||
func _free_childless_scripts():
|
||||
var items = _root.get_children()
|
||||
for item in items:
|
||||
var next_item = item.get_next()
|
||||
if item.get_children() == null:
|
||||
item.free()
|
||||
item = next_item
|
||||
|
||||
|
||||
func _find_script_item_with_path(path):
|
||||
var items = _root.get_children()
|
||||
var to_return = null
|
||||
|
||||
var idx = 0
|
||||
while idx < items.size() and to_return == null:
|
||||
var item = items[idx]
|
||||
if item.get_metadata(0).path == path:
|
||||
to_return = item
|
||||
else:
|
||||
idx += 1
|
||||
|
||||
return to_return
|
||||
|
||||
|
||||
func _get_line_number_from_assert_msg(msg):
|
||||
var line = -1
|
||||
if msg.find("at line") > 0:
|
||||
line = msg.split("at line")[-1].split(" ")[-1].to_int()
|
||||
return line
|
||||
|
||||
|
||||
func _get_path_and_inner_class_name_from_test_path(path):
|
||||
var to_return = {path = "", inner_class = ""}
|
||||
|
||||
to_return.path = path
|
||||
if !path.ends_with(".gd"):
|
||||
var loc = path.find(".gd")
|
||||
to_return.inner_class = path.split(".")[-1]
|
||||
to_return.path = path.substr(0, loc + 3)
|
||||
return to_return
|
||||
|
||||
|
||||
func _handle_tree_item_select(item, force_scroll):
|
||||
var item_type = item.get_metadata(0).type
|
||||
|
||||
var path = ""
|
||||
var line = -1
|
||||
var method_name = ""
|
||||
var inner_class = ""
|
||||
|
||||
if item_type == "test":
|
||||
var s_item = item.get_parent()
|
||||
path = s_item.get_metadata(0)["path"]
|
||||
inner_class = s_item.get_metadata(0)["inner_class"]
|
||||
line = -1
|
||||
method_name = item.get_text(0)
|
||||
elif item_type == "assert":
|
||||
var s_item = item.get_parent().get_parent()
|
||||
path = s_item.get_metadata(0)["path"]
|
||||
inner_class = s_item.get_metadata(0)["inner_class"]
|
||||
|
||||
line = _get_line_number_from_assert_msg(item.get_text(0))
|
||||
method_name = item.get_parent().get_text(0)
|
||||
elif item_type == "script":
|
||||
path = item.get_metadata(0)["path"]
|
||||
if item.get_parent() != _root:
|
||||
inner_class = item.get_text(0)
|
||||
line = -1
|
||||
method_name = ""
|
||||
else:
|
||||
return
|
||||
|
||||
var path_info = _get_path_and_inner_class_name_from_test_path(path)
|
||||
if force_scroll or _ctrls.toolbar.show_script.pressed:
|
||||
_goto_code(path, line, method_name, inner_class)
|
||||
if force_scroll or _ctrls.toolbar.scroll_output.pressed:
|
||||
_goto_output(path, method_name, inner_class)
|
||||
|
||||
|
||||
# starts at beginning of text edit and searches for each search term, moving
|
||||
# through the text as it goes; ensuring that, when done, it found the first
|
||||
# occurance of the last srting that happend after the first occurance of
|
||||
|
@ -325,9 +96,12 @@ func _handle_tree_item_select(item, force_scroll):
|
|||
# inner class that may have be a duplicate of a method name in a different
|
||||
# inner class)
|
||||
func _get_line_number_for_seq_search(search_strings, te):
|
||||
# var te = _editors.get_current_text_edit()
|
||||
if te == null:
|
||||
print("No Text editor to get line number for")
|
||||
return 0
|
||||
|
||||
var result = null
|
||||
var line = Vector2i(-1, -1)
|
||||
var line = Vector2i(0, 0)
|
||||
var s_flags = 0
|
||||
|
||||
var i = 0
|
||||
|
@ -348,7 +122,7 @@ func _goto_code(path, line, method_name = "", inner_class = ""):
|
|||
print("going to ", [path, line, method_name, inner_class])
|
||||
return
|
||||
|
||||
_open_file(path, line)
|
||||
_open_script_in_editor(path, line)
|
||||
if line == -1:
|
||||
var search_strings = []
|
||||
if inner_class != "":
|
||||
|
@ -357,8 +131,9 @@ func _goto_code(path, line, method_name = "", inner_class = ""):
|
|||
if method_name != "":
|
||||
search_strings.append(method_name)
|
||||
|
||||
await get_tree().process_frame
|
||||
line = _get_line_number_for_seq_search(search_strings, _editors.get_current_text_edit())
|
||||
if line != -1:
|
||||
if line != null and line != -1:
|
||||
_interface.get_script_editor().goto_line(line)
|
||||
|
||||
|
||||
|
@ -375,44 +150,13 @@ func _goto_output(path, method_name, inner_class):
|
|||
search_strings.append(method_name)
|
||||
|
||||
var line = _get_line_number_for_seq_search(search_strings, _output_control.get_rich_text_edit())
|
||||
if line != -1:
|
||||
if line != null and line != -1:
|
||||
_output_control.scroll_to_line(line)
|
||||
|
||||
|
||||
func _show_all_passed():
|
||||
if _root.get_children() == null:
|
||||
add_centered_text("Everything passed!")
|
||||
|
||||
|
||||
func _set_collapsed_on_all(item, value):
|
||||
if item == _root:
|
||||
var node = _root.get_children()
|
||||
while node != null:
|
||||
node.call_recursive("set_collapsed", value)
|
||||
node = node.get_next()
|
||||
else:
|
||||
item.call_recursive("set_collapsed", value)
|
||||
|
||||
|
||||
# --------------
|
||||
# Events
|
||||
# --------------
|
||||
func _on_Tree_item_selected():
|
||||
# do not force scroll
|
||||
var item = _ctrls.tree.get_selected()
|
||||
_handle_tree_item_select(item, false)
|
||||
# it just looks better if the left is always selected.
|
||||
if item.is_selected(1):
|
||||
item.deselect(1)
|
||||
item.select(0)
|
||||
|
||||
|
||||
func _on_Tree_item_activated():
|
||||
# force scroll
|
||||
print("double clicked")
|
||||
_handle_tree_item_select(_ctrls.tree.get_selected(), true)
|
||||
|
||||
|
||||
func _on_Collapse_pressed():
|
||||
collapse_selected()
|
||||
|
||||
|
@ -430,55 +174,30 @@ func _on_ExpandAll_pressed():
|
|||
|
||||
|
||||
func _on_Hide_Passing_pressed():
|
||||
_hide_passing = _ctrls.toolbar.hide_passing.button_pressed
|
||||
_ctrls.tree.hide_passing = !_ctrls.toolbar.hide_passing.button_pressed
|
||||
_ctrls.tree.load_json_file("user://.gut_editor.json")
|
||||
|
||||
|
||||
func _on_item_selected(script_path, inner_class, test_name, line):
|
||||
if _ctrls.toolbar.show_script.button_pressed:
|
||||
_goto_code(script_path, line, test_name, inner_class)
|
||||
if _ctrls.toolbar.scroll_output.button_pressed:
|
||||
_goto_output(script_path, test_name, inner_class)
|
||||
|
||||
|
||||
# --------------
|
||||
# Public
|
||||
# --------------
|
||||
func load_json_file(path):
|
||||
var text = _utils.get_file_as_text(path)
|
||||
if text != "":
|
||||
var test_json_conv = JSON.new()
|
||||
test_json_conv.parse(text)
|
||||
var result = test_json_conv.get_data()
|
||||
if result.error != OK:
|
||||
add_centered_text(
|
||||
str(
|
||||
path,
|
||||
" has invalid json in it \n",
|
||||
"Error ",
|
||||
result.error,
|
||||
"@",
|
||||
result.error_line,
|
||||
"\n",
|
||||
result.error_string
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
load_json_results(result.result)
|
||||
else:
|
||||
add_centered_text(str(path, " was empty or does not exist."))
|
||||
|
||||
|
||||
func load_json_results(j):
|
||||
clear()
|
||||
add_centered_text("Nothing Here")
|
||||
_load_result_tree(j)
|
||||
|
||||
|
||||
func add_centered_text(t):
|
||||
_ctrls.lbl_overlay.text = t
|
||||
_ctrls.tree.add_centered_text(t)
|
||||
|
||||
|
||||
func clear_centered_text():
|
||||
_ctrls.lbl_overlay.text = ""
|
||||
_ctrls.tree.clear_centered_text()
|
||||
|
||||
|
||||
func clear():
|
||||
_ctrls.tree.clear()
|
||||
_root = _ctrls.tree.create_item()
|
||||
clear_centered_text()
|
||||
|
||||
|
||||
|
@ -491,27 +210,27 @@ func set_script_text_editors(value):
|
|||
|
||||
|
||||
func collapse_all():
|
||||
_set_collapsed_on_all(_root, true)
|
||||
_ctrls.tree.collapse_all()
|
||||
|
||||
|
||||
func expand_all():
|
||||
_set_collapsed_on_all(_root, false)
|
||||
_ctrls.tree.expand_all()
|
||||
|
||||
|
||||
func collapse_selected():
|
||||
var item = _ctrls.tree.get_selected()
|
||||
if item != null:
|
||||
_set_collapsed_on_all(item, true)
|
||||
_ctrls.tree.set_collapsed_on_all(item, true)
|
||||
|
||||
|
||||
func expand_selected():
|
||||
var item = _ctrls.tree.get_selected()
|
||||
if item != null:
|
||||
_set_collapsed_on_all(item, false)
|
||||
_ctrls.tree.set_collapsed_on_all(item, false)
|
||||
|
||||
|
||||
func set_show_orphans(should):
|
||||
_show_orphans = should
|
||||
_ctrls.tree.show_orphans = should
|
||||
|
||||
|
||||
func set_font(font_name, size):
|
||||
|
@ -531,3 +250,7 @@ func set_font(font_name, size):
|
|||
|
||||
func set_output_control(value):
|
||||
_output_control = value
|
||||
|
||||
|
||||
func load_json_results(j):
|
||||
_ctrls.tree.load_json_results(j)
|
||||
|
|
|
@ -1,157 +1,110 @@
|
|||
[gd_scene load_steps=4 format=2]
|
||||
[gd_scene load_steps=5 format=3 uid="uid://4gyyn12um08h"]
|
||||
|
||||
[ext_resource path="res://addons/gut/gui/RunResults.gd" type="Script" id=1]
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/RunResults.gd" id="1"]
|
||||
[ext_resource type="PackedScene" uid="uid://dls5r5f6157nq" path="res://addons/gut/gui/ResultsTree.tscn" id="2_o808v"]
|
||||
|
||||
[sub_resource type="Image" id=3]
|
||||
[sub_resource type="Image" id="Image_abbh7"]
|
||||
data = {
|
||||
"data": PackedByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
|
||||
"format": "LumAlpha8",
|
||||
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 131, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 128, 128, 4, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 93, 93, 55, 255, 97, 97, 58, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 98, 98, 47, 255, 97, 97, 42, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 94, 94, 46, 255, 93, 93, 236, 255, 93, 93, 233, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 93, 93, 252, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
|
||||
"format": "RGBA8",
|
||||
"height": 16,
|
||||
"mipmaps": false,
|
||||
"width": 16
|
||||
}
|
||||
|
||||
[sub_resource type="ImageTexture" id=2]
|
||||
flags = 4
|
||||
flags = 4
|
||||
image = SubResource( 3 )
|
||||
size = Vector2( 16, 16 )
|
||||
[sub_resource type="ImageTexture" id="ImageTexture_x655i"]
|
||||
image = SubResource("Image_abbh7")
|
||||
|
||||
[node name="RunResults" type="Control"]
|
||||
offset_right = 595.0
|
||||
offset_bottom = 459.0
|
||||
custom_minimum_size = Vector2( 302, 0 )
|
||||
script = ExtResource( 1 )
|
||||
custom_minimum_size = Vector2(345, 0)
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_right = 709.0
|
||||
offset_bottom = 321.0
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="."]
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
||||
[node name="Toolbar" type="HBoxContainer" parent="VBox"]
|
||||
offset_right = 296.0
|
||||
offset_bottom = 24.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
|
||||
[node name="Expand" type="Button" parent="VBox/Toolbar"]
|
||||
offset_right = 28.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Expand selected item and all children."
|
||||
icon = SubResource( 2 )
|
||||
layout_mode = 2
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="Collapse" type="Button" parent="VBox/Toolbar"]
|
||||
offset_left = 32.0
|
||||
offset_right = 60.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Collapse selected item and all children."
|
||||
icon = SubResource( 2 )
|
||||
layout_mode = 2
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="Sep" type="ColorRect" parent="VBox/Toolbar"]
|
||||
offset_left = 64.0
|
||||
offset_right = 66.0
|
||||
offset_bottom = 24.0
|
||||
custom_minimum_size = Vector2( 2, 0 )
|
||||
custom_minimum_size = Vector2(2, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="LblAll" type="Label" parent="VBox/Toolbar"]
|
||||
offset_left = 70.0
|
||||
offset_top = 5.0
|
||||
offset_right = 91.0
|
||||
offset_bottom = 19.0
|
||||
layout_mode = 2
|
||||
text = "All:"
|
||||
align = 1
|
||||
|
||||
[node name="ExpandAll" type="Button" parent="VBox/Toolbar"]
|
||||
offset_left = 95.0
|
||||
offset_right = 123.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Expand All."
|
||||
icon = SubResource( 2 )
|
||||
layout_mode = 2
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="CollapseAll" type="Button" parent="VBox/Toolbar"]
|
||||
offset_left = 127.0
|
||||
offset_right = 155.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Collapse all."
|
||||
icon = SubResource( 2 )
|
||||
layout_mode = 2
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="Sep2" type="ColorRect" parent="VBox/Toolbar"]
|
||||
offset_left = 159.0
|
||||
offset_right = 161.0
|
||||
offset_bottom = 24.0
|
||||
custom_minimum_size = Vector2( 2, 0 )
|
||||
custom_minimum_size = Vector2(2, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HidePassing" type="CheckBox" parent="VBox/Toolbar"]
|
||||
offset_left = 165.0
|
||||
offset_right = 189.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Show/Hide passing tests. Takes effect on next run."
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
custom_icons/checked = SubResource( 2 )
|
||||
custom_icons/unchecked = SubResource( 2 )
|
||||
pressed = true
|
||||
__meta__ = {
|
||||
"_editor_description_": ""
|
||||
}
|
||||
text = "Passing"
|
||||
|
||||
[node name="Sep3" type="ColorRect" parent="VBox/Toolbar"]
|
||||
offset_left = 193.0
|
||||
offset_right = 195.0
|
||||
offset_bottom = 24.0
|
||||
custom_minimum_size = Vector2( 2, 0 )
|
||||
custom_minimum_size = Vector2(2, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="LblSync" type="Label" parent="VBox/Toolbar"]
|
||||
offset_left = 199.0
|
||||
offset_top = 5.0
|
||||
offset_right = 232.0
|
||||
offset_bottom = 19.0
|
||||
layout_mode = 2
|
||||
text = "Sync:"
|
||||
align = 1
|
||||
|
||||
[node name="ShowScript" type="Button" parent="VBox/Toolbar"]
|
||||
offset_left = 236.0
|
||||
offset_right = 264.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Open script and scroll to line when a tree item is clicked."
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
pressed = true
|
||||
icon = SubResource( 2 )
|
||||
button_pressed = true
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="ScrollOutput" type="Button" parent="VBox/Toolbar"]
|
||||
offset_left = 268.0
|
||||
offset_right = 296.0
|
||||
offset_bottom = 24.0
|
||||
hint_tooltip = "Scroll to related line in the output panel when tree item clicked."
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
pressed = true
|
||||
icon = SubResource( 2 )
|
||||
button_pressed = true
|
||||
icon = SubResource("ImageTexture_x655i")
|
||||
|
||||
[node name="Output" type="Panel" parent="VBox"]
|
||||
self_modulate = Color( 1, 1, 1, 0.541176 )
|
||||
offset_top = 28.0
|
||||
offset_right = 595.0
|
||||
offset_bottom = 459.0
|
||||
self_modulate = Color(1, 1, 1, 0.541176)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Scroll" type="ScrollContainer" parent="VBox/Output"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Tree" type="Tree" parent="VBox/Output/Scroll"]
|
||||
offset_right = 595.0
|
||||
offset_bottom = 431.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
columns = 2
|
||||
hide_root = true
|
||||
|
||||
[node name="OverlayMessage" type="Label" parent="VBox/Output"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
align = 1
|
||||
valign = 1
|
||||
[node name="Tree" parent="VBox/Output/Scroll" instance=ExtResource("2_o808v")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="FontSampler" type="Label" parent="."]
|
||||
visible = false
|
||||
layout_mode = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 14.0
|
||||
text = "000 of 000 passed"
|
||||
|
@ -161,5 +114,3 @@ text = "000 of 000 passed"
|
|||
[connection signal="pressed" from="VBox/Toolbar/ExpandAll" to="." method="_on_ExpandAll_pressed"]
|
||||
[connection signal="pressed" from="VBox/Toolbar/CollapseAll" to="." method="_on_CollapseAll_pressed"]
|
||||
[connection signal="pressed" from="VBox/Toolbar/HidePassing" to="." method="_on_Hide_Passing_pressed"]
|
||||
[connection signal="item_activated" from="VBox/Output/Scroll/Tree" to="." method="_on_Tree_item_activated"]
|
||||
[connection signal="item_selected" from="VBox/Output/Scroll/Tree" to="." method="_on_Tree_item_selected"]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene format=2]
|
||||
[gd_scene format=3 uid="uid://cvvvtsah38l0e"]
|
||||
|
||||
[node name="Settings" type="VBoxContainer"]
|
||||
offset_right = 388.0
|
||||
|
|
|
@ -36,24 +36,13 @@ func _display_shortcut():
|
|||
func _is_shift_only_modifier():
|
||||
return (
|
||||
_source_event.shift_pressed
|
||||
and !(
|
||||
_source_event.alt_pressed
|
||||
or _source_event.command_pressed
|
||||
or _source_event.ctrl_pressed
|
||||
or _source_event.meta_pressed
|
||||
)
|
||||
and !(_source_event.alt_pressed or _source_event.ctrl_pressed or _source_event.meta_pressed)
|
||||
and !_is_modifier(_source_event.keycode)
|
||||
)
|
||||
|
||||
|
||||
func _has_modifier(event):
|
||||
return (
|
||||
event.alt_pressed
|
||||
or event.command_pressed
|
||||
or event.ctrl_pressed
|
||||
or event.meta_pressed
|
||||
or event.shift_pressed
|
||||
)
|
||||
return event.alt_pressed or event.ctrl_pressed or event.meta_pressed or event.shift_pressed
|
||||
|
||||
|
||||
func _is_modifier(keycode):
|
||||
|
|
|
@ -1,77 +1,52 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
[gd_scene load_steps=2 format=3 uid="uid://sfb1fw8j6ufu"]
|
||||
|
||||
[ext_resource path="res://addons/gut/gui/ShortcutButton.gd" type="Script" id=1]
|
||||
[ext_resource type="Script" path="res://addons/gut/gui/ShortcutButton.gd" id="1"]
|
||||
|
||||
[node name="ShortcutButton" type="Control"]
|
||||
custom_minimum_size = Vector2(210, 30)
|
||||
layout_mode = 3
|
||||
anchor_right = 0.123
|
||||
anchor_bottom = 0.04
|
||||
offset_right = 33.048
|
||||
offset_bottom = 1.0
|
||||
custom_minimum_size = Vector2( 125, 25 )
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
offset_right = 68.304
|
||||
offset_bottom = 6.08
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="Layout" type="HBoxContainer" parent="."]
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="lblShortcut" type="Label" parent="Layout"]
|
||||
offset_right = 50.0
|
||||
offset_bottom = 25.0
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 7
|
||||
text = "<None>"
|
||||
align = 2
|
||||
valign = 1
|
||||
horizontal_alignment = 2
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="Layout"]
|
||||
offset_left = 54.0
|
||||
offset_right = 64.0
|
||||
offset_bottom = 25.0
|
||||
custom_minimum_size = Vector2( 10, 0 )
|
||||
custom_minimum_size = Vector2(10, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SetButton" type="Button" parent="Layout"]
|
||||
offset_left = 68.0
|
||||
offset_right = 128.0
|
||||
offset_bottom = 25.0
|
||||
custom_minimum_size = Vector2( 60, 0 )
|
||||
custom_minimum_size = Vector2(60, 0)
|
||||
layout_mode = 2
|
||||
text = "Set"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="SaveButton" type="Button" parent="Layout"]
|
||||
visible = false
|
||||
offset_left = 82.0
|
||||
offset_right = 142.0
|
||||
offset_bottom = 25.0
|
||||
custom_minimum_size = Vector2( 60, 0 )
|
||||
custom_minimum_size = Vector2(60, 0)
|
||||
layout_mode = 2
|
||||
text = "Save"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="CancelButton" type="Button" parent="Layout"]
|
||||
visible = false
|
||||
offset_left = 82.0
|
||||
offset_right = 142.0
|
||||
offset_bottom = 25.0
|
||||
custom_minimum_size = Vector2( 60, 0 )
|
||||
custom_minimum_size = Vector2(60, 0)
|
||||
layout_mode = 2
|
||||
text = "Cancel"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="ClearButton" type="Button" parent="Layout"]
|
||||
offset_left = 132.0
|
||||
offset_right = 192.0
|
||||
offset_bottom = 25.0
|
||||
custom_minimum_size = Vector2( 60, 0 )
|
||||
custom_minimum_size = Vector2(60, 0)
|
||||
layout_mode = 2
|
||||
text = "Clear"
|
||||
|
||||
[connection signal="pressed" from="Layout/SetButton" to="." method="_on_SetButton_pressed"]
|
||||
|
|
|
@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/arrow.png-2b5b2d838b5b3467cf300ac2da1630d9.ct
|
|||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
# Choose an existing directory from res://. Dialog allows for creating a
|
||||
# directory.
|
||||
# ------------------------------------------------------------------------------
|
||||
class DirectoryCtrl:
|
||||
extends HBoxContainer
|
||||
|
@ -9,20 +11,20 @@ class DirectoryCtrl:
|
|||
set(val):
|
||||
_txt_path.text = val
|
||||
|
||||
var _txt_path = LineEdit.new()
|
||||
var _btn_dir = Button.new()
|
||||
var _dialog = FileDialog.new()
|
||||
var _txt_path := LineEdit.new()
|
||||
var _btn_dir := Button.new()
|
||||
var _dialog := FileDialog.new()
|
||||
|
||||
func _init():
|
||||
_btn_dir.text = "..."
|
||||
_btn_dir.connect("pressed", Callable(self, "_on_dir_button_pressed"))
|
||||
_btn_dir.pressed.connect(_on_dir_button_pressed)
|
||||
|
||||
_txt_path.size_flags_horizontal = _txt_path.SIZE_EXPAND_FILL
|
||||
|
||||
_dialog.mode = _dialog.FILE_MODE_OPEN_DIR
|
||||
_dialog.file_mode = _dialog.FILE_MODE_OPEN_DIR
|
||||
_dialog.unresizable = false
|
||||
_dialog.connect("dir_selected", Callable(self, "_on_selected"))
|
||||
_dialog.connect("file_selected", Callable(self, "_on_selected"))
|
||||
_dialog.dir_selected.connect(_on_selected)
|
||||
_dialog.file_selected.connect(_on_selected)
|
||||
_dialog.size = Vector2(1000, 700)
|
||||
|
||||
func _on_selected(path):
|
||||
|
@ -42,12 +44,27 @@ class DirectoryCtrl:
|
|||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Choose an existing file in res://
|
||||
# ------------------------------------------------------------------------------
|
||||
class FileCtrl:
|
||||
extends DirectoryCtrl
|
||||
|
||||
func _init():
|
||||
_dialog.mode = _dialog.FILE_MODE_OPEN_FILE
|
||||
super._init()
|
||||
_dialog.file_mode = _dialog.FILE_MODE_OPEN_FILE
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Choose a save location. Can pick anywhere on file system. Will warn if you
|
||||
# pick a file that already exists.
|
||||
# ------------------------------------------------------------------------------
|
||||
class SaveFileAnywhere:
|
||||
extends DirectoryCtrl
|
||||
|
||||
func _init():
|
||||
super._init()
|
||||
_dialog.file_mode = _dialog.FILE_MODE_SAVE_FILE
|
||||
_dialog.access = _dialog.ACCESS_FILESYSTEM
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -127,6 +144,11 @@ func _init(cont):
|
|||
_base_control.add_child(lbl)
|
||||
|
||||
|
||||
func _notification(what):
|
||||
if what == NOTIFICATION_PREDELETE:
|
||||
_base_control.free()
|
||||
|
||||
|
||||
# ------------------
|
||||
# Private
|
||||
# ------------------
|
||||
|
@ -134,7 +156,7 @@ func _new_row(key, disp_text, value_ctrl, hint):
|
|||
var ctrl = _base_control.duplicate()
|
||||
var lbl = ctrl.get_child(0)
|
||||
|
||||
lbl.hint_tooltip = hint
|
||||
lbl.tooltip_text = hint
|
||||
lbl.text = disp_text
|
||||
_base_container.add_child(ctrl)
|
||||
|
||||
|
@ -167,7 +189,7 @@ func _add_number(key, value, disp_text, v_min, v_max, hint = ""):
|
|||
value_ctrl.max_value = v_max
|
||||
_wire_select_on_focus(value_ctrl.get_line_edit())
|
||||
|
||||
_new_row(key, disp_text, value_ctrl, hint)
|
||||
return _new_row(key, disp_text, value_ctrl, hint)
|
||||
|
||||
|
||||
func _add_select(key, value, values, disp_text, hint = ""):
|
||||
|
@ -180,7 +202,7 @@ func _add_select(key, value, values, disp_text, hint = ""):
|
|||
value_ctrl.selected = select_idx
|
||||
value_ctrl.size_flags_horizontal = value_ctrl.SIZE_EXPAND_FILL
|
||||
|
||||
_new_row(key, disp_text, value_ctrl, hint)
|
||||
return _new_row(key, disp_text, value_ctrl, hint)
|
||||
|
||||
|
||||
func _add_value(key, value, disp_text, hint = ""):
|
||||
|
@ -189,14 +211,14 @@ func _add_value(key, value, disp_text, hint = ""):
|
|||
value_ctrl.text = value
|
||||
_wire_select_on_focus(value_ctrl)
|
||||
|
||||
_new_row(key, disp_text, value_ctrl, hint)
|
||||
return _new_row(key, disp_text, value_ctrl, hint)
|
||||
|
||||
|
||||
func _add_boolean(key, value, disp_text, hint = ""):
|
||||
var value_ctrl = CheckBox.new()
|
||||
value_ctrl.button_pressed = value
|
||||
|
||||
_new_row(key, disp_text, value_ctrl, hint)
|
||||
return _new_row(key, disp_text, value_ctrl, hint)
|
||||
|
||||
|
||||
func _add_directory(key, value, disp_text, hint = ""):
|
||||
|
@ -205,7 +227,7 @@ func _add_directory(key, value, disp_text, hint = ""):
|
|||
value_ctrl.text = value
|
||||
_wire_select_on_focus(value_ctrl.get_line_edit())
|
||||
|
||||
_new_row(key, disp_text, value_ctrl, hint)
|
||||
return _new_row(key, disp_text, value_ctrl, hint)
|
||||
|
||||
|
||||
func _add_file(key, value, disp_text, hint = ""):
|
||||
|
@ -214,7 +236,16 @@ func _add_file(key, value, disp_text, hint = ""):
|
|||
value_ctrl.text = value
|
||||
_wire_select_on_focus(value_ctrl.get_line_edit())
|
||||
|
||||
_new_row(key, disp_text, value_ctrl, hint)
|
||||
return _new_row(key, disp_text, value_ctrl, hint)
|
||||
|
||||
|
||||
func _add_save_file_anywhere(key, value, disp_text, hint = ""):
|
||||
var value_ctrl = SaveFileAnywhere.new()
|
||||
value_ctrl.size_flags_horizontal = value_ctrl.SIZE_EXPAND_FILL
|
||||
value_ctrl.text = value
|
||||
_wire_select_on_focus(value_ctrl.get_line_edit())
|
||||
|
||||
return _new_row(key, disp_text, value_ctrl, hint)
|
||||
|
||||
|
||||
func _add_color(key, value, disp_text, hint = ""):
|
||||
|
@ -222,7 +253,7 @@ func _add_color(key, value, disp_text, hint = ""):
|
|||
value_ctrl.size_flags_horizontal = value_ctrl.SIZE_EXPAND_FILL
|
||||
value_ctrl.color = value
|
||||
|
||||
_new_row(key, disp_text, value_ctrl, hint)
|
||||
return _new_row(key, disp_text, value_ctrl, hint)
|
||||
|
||||
|
||||
func _add_vector2(key, value, disp_text, hint = ""):
|
||||
|
@ -232,7 +263,7 @@ func _add_vector2(key, value, disp_text, hint = ""):
|
|||
_wire_select_on_focus(value_ctrl.x_spin.get_line_edit())
|
||||
_wire_select_on_focus(value_ctrl.y_spin.get_line_edit())
|
||||
|
||||
_new_row(key, disp_text, value_ctrl, hint)
|
||||
return _new_row(key, disp_text, value_ctrl, hint)
|
||||
|
||||
|
||||
# -----------------------------
|
||||
|
@ -242,7 +273,6 @@ func _add_vector2(key, value, disp_text, hint = ""):
|
|||
# Events
|
||||
# ------------------
|
||||
func _wire_select_on_focus(which):
|
||||
pass
|
||||
which.connect("focus_entered", _on_ctrl_focus_highlight.bind(which))
|
||||
which.connect("focus_exited", _on_ctrl_focus_unhighlight.bind(which))
|
||||
|
||||
|
@ -273,8 +303,7 @@ func get_config_issues():
|
|||
var path = _cfg_ctrls[key].text
|
||||
if path != null and path != "":
|
||||
has_directory = true
|
||||
var dir = DirAccess.open(".")
|
||||
if !dir.dir_exists(path):
|
||||
if !DirAccess.dir_exists_absolute(path):
|
||||
to_return.append(str("Test directory ", path, " does not exist."))
|
||||
|
||||
if !has_directory:
|
||||
|
@ -286,8 +315,23 @@ func get_config_issues():
|
|||
return to_return
|
||||
|
||||
|
||||
# --------------
|
||||
# SUPER dumb but VERY fun hack to hide settings. The various _add methods will
|
||||
# return what they add. If you want to hide it, just assign the result to this.
|
||||
# YES, I could have just put .visible at the end, but I didn't think of that
|
||||
# until just now, and this was fun, non-permanent and the .visible at the end
|
||||
# isn't as obvious as hide_this =
|
||||
#
|
||||
# Also, we can't just skip adding the controls because other things are looking
|
||||
# for them and things start to blow up if you don't add them.
|
||||
var hide_this = null:
|
||||
set(val):
|
||||
val.visible = false
|
||||
# --------------
|
||||
|
||||
|
||||
func set_options(options):
|
||||
_add_title("Settings")
|
||||
_add_title("Settings") # ----------------------------------
|
||||
_add_number(
|
||||
"log_level",
|
||||
options.log_level,
|
||||
|
@ -321,26 +365,48 @@ func set_options(options):
|
|||
"Exit on Success",
|
||||
"Exit if there are no failures. Does nothing if 'Exit on Finish' is enabled."
|
||||
)
|
||||
var ds = _add_select(
|
||||
"double_strategy",
|
||||
"Script Only",
|
||||
["Include Native", "Script Only"],
|
||||
"Double Strategy",
|
||||
(
|
||||
'"Include Native" will include native methods in Doubles. "Script Only" will not. '
|
||||
+ "\n"
|
||||
+ "The native method override warning is disabled when creating Doubles."
|
||||
+ "\n"
|
||||
+ "This is the default, you can override this at the script level or when creating doubles."
|
||||
)
|
||||
)
|
||||
_cfg_ctrls["double_strategy"].selected = GutUtils.get_enum_value(
|
||||
options.double_strategy, GutUtils.DOUBLE_STRATEGY, GutUtils.DOUBLE_STRATEGY.SCRIPT_ONLY
|
||||
)
|
||||
_add_boolean(
|
||||
"errors_cause_failure",
|
||||
!options.errors_do_not_cause_failure,
|
||||
"Errors cause failures.",
|
||||
"When GUT generates an error (not an engine error) it causes tests to fail."
|
||||
)
|
||||
|
||||
_add_title("Panel Output")
|
||||
_add_title("Panel Output") # ----------------------------------
|
||||
_add_select(
|
||||
"output_font_name",
|
||||
options.panel_options.font_name,
|
||||
options.panel_options.output_font_name,
|
||||
_avail_fonts,
|
||||
"Font",
|
||||
"The name of the font to use when running tests and in the output panel to the left."
|
||||
)
|
||||
_add_number(
|
||||
"output_font_size",
|
||||
options.panel_options.font_size,
|
||||
options.panel_options.output_font_size,
|
||||
"Font Size",
|
||||
5,
|
||||
100,
|
||||
"The font size to use when running tests and in the output panel to the left."
|
||||
)
|
||||
|
||||
_add_title("Runner Window")
|
||||
_add_boolean(
|
||||
_add_title("Runner Window") # ----------------------------------
|
||||
hide_this = _add_boolean(
|
||||
"gut_on_top",
|
||||
options.gut_on_top,
|
||||
"On Top",
|
||||
|
@ -349,7 +415,7 @@ func set_options(options):
|
|||
_add_number(
|
||||
"opacity", options.opacity, "Opacity", 0, 100, "The opacity of GUT when tests are running."
|
||||
)
|
||||
_add_boolean(
|
||||
hide_this = _add_boolean(
|
||||
"should_maximize",
|
||||
options.should_maximize,
|
||||
"Maximize",
|
||||
|
@ -362,7 +428,7 @@ func set_options(options):
|
|||
"The runner will be in compact mode. This overrides Maximize."
|
||||
)
|
||||
|
||||
_add_title("Runner Appearance")
|
||||
_add_title("Runner Appearance") # ----------------------------------
|
||||
_add_select(
|
||||
"font_name",
|
||||
options.font_name,
|
||||
|
@ -378,7 +444,7 @@ func set_options(options):
|
|||
100,
|
||||
"The font size for text output in the Gut Runner."
|
||||
)
|
||||
_add_color(
|
||||
hide_this = _add_color(
|
||||
"font_color",
|
||||
options.font_color,
|
||||
"Font Color",
|
||||
|
@ -397,7 +463,7 @@ func set_options(options):
|
|||
"Disable formatting and colors used in the Runner. Does not affect panel output."
|
||||
)
|
||||
|
||||
_add_title("Test Directories")
|
||||
_add_title("Test Directories") # ----------------------------------
|
||||
_add_boolean(
|
||||
"include_subdirs",
|
||||
options.include_subdirs,
|
||||
|
@ -411,11 +477,11 @@ func set_options(options):
|
|||
|
||||
_add_directory(str("directory_", i), value, str("Directory ", i))
|
||||
|
||||
_add_title("XML Output")
|
||||
_add_value(
|
||||
_add_title("XML Output") # ----------------------------------
|
||||
_add_save_file_anywhere(
|
||||
"junit_xml_file",
|
||||
options.junit_xml_file,
|
||||
"Output Path3D",
|
||||
"Output Path",
|
||||
(
|
||||
"Path3D and filename where GUT should create a JUnit compliant XML file. "
|
||||
+ "This file will contain the results of the last test run. To avoid "
|
||||
|
@ -429,7 +495,7 @@ func set_options(options):
|
|||
"Include a timestamp in the filename so that each run gets its own xml file."
|
||||
)
|
||||
|
||||
_add_title("Hooks")
|
||||
_add_title("Hooks") # ----------------------------------
|
||||
_add_file(
|
||||
"pre_run_script",
|
||||
options.pre_run_script,
|
||||
|
@ -443,7 +509,7 @@ func set_options(options):
|
|||
"This script will be run by GUT after all tests are run."
|
||||
)
|
||||
|
||||
_add_title("Misc")
|
||||
_add_title("Misc") # ----------------------------------
|
||||
_add_value(
|
||||
"prefix", options.prefix, "Script Prefix", "The filename prefix for all test scripts."
|
||||
)
|
||||
|
@ -466,7 +532,7 @@ func set_options(options):
|
|||
_cfg_ctrls.paint_after.step = .05
|
||||
_cfg_ctrls.paint_after.value = options.paint_after
|
||||
|
||||
print("paint after = ", options.paint_after)
|
||||
print("GUT config loaded")
|
||||
|
||||
|
||||
func get_options(base_opts):
|
||||
|
@ -478,11 +544,13 @@ func get_options(base_opts):
|
|||
to_return.hide_orphans = _cfg_ctrls.hide_orphans.button_pressed
|
||||
to_return.should_exit = _cfg_ctrls.should_exit.button_pressed
|
||||
to_return.should_exit_on_success = _cfg_ctrls.should_exit_on_success.button_pressed
|
||||
to_return.double_strategy = _cfg_ctrls.double_strategy.selected
|
||||
to_return.errors_do_not_cause_failure = !_cfg_ctrls.errors_cause_failure.button_pressed
|
||||
|
||||
#Output
|
||||
to_return.panel_options.font_name = (_cfg_ctrls.output_font_name.get_item_text(
|
||||
to_return.panel_options.font_name = _cfg_ctrls.output_font_name.get_item_text(
|
||||
_cfg_ctrls.output_font_name.selected
|
||||
))
|
||||
)
|
||||
to_return.panel_options.font_size = _cfg_ctrls.output_font_size.value
|
||||
|
||||
# Runner Appearance
|
||||
|
|
238
addons/gut/gui/gut_gui.gd
Normal file
238
addons/gut/gui/gut_gui.gd
Normal file
|
@ -0,0 +1,238 @@
|
|||
extends Control
|
||||
# ##############################################################################
|
||||
# This is the decoupled GUI for gut.gd
|
||||
#
|
||||
# This is a "generic" interface between a GUI and gut.gd. It assumes there are
|
||||
# certain controls with specific names. It will then interact with those
|
||||
# controls based on signals emitted from gut.gd in order to give the user
|
||||
# feedback about the progress of the test run and the results.
|
||||
#
|
||||
# Optional controls are marked as such in the _ctrls dictionary. The names
|
||||
# of the controls can be found in _populate_ctrls.
|
||||
# ##############################################################################
|
||||
var _gut = null
|
||||
|
||||
var _ctrls = {
|
||||
btn_continue = null,
|
||||
path_dir = null,
|
||||
path_file = null,
|
||||
prog_script = null,
|
||||
prog_test = null,
|
||||
rtl = null, # optional
|
||||
rtl_bg = null, # required if rtl exists
|
||||
switch_modes = null,
|
||||
time_label = null,
|
||||
title = null,
|
||||
title_bar = null,
|
||||
}
|
||||
|
||||
var _title_mouse = {down = false}
|
||||
|
||||
var _resize_mouse = {down = false}
|
||||
|
||||
var _resize_left_mouse = {down = false}
|
||||
|
||||
signal switch_modes
|
||||
|
||||
var _max_position = Vector2(100, 100)
|
||||
var _utils = null
|
||||
|
||||
|
||||
func _ready():
|
||||
_populate_ctrls()
|
||||
|
||||
_ctrls.btn_continue.visible = false
|
||||
_ctrls.btn_continue.pressed.connect(_on_continue_pressed)
|
||||
_ctrls.switch_modes.pressed.connect(_on_switch_modes_pressed)
|
||||
_ctrls.title_bar.gui_input.connect(_on_title_bar_input)
|
||||
|
||||
_ctrls.prog_script.value = 0
|
||||
_ctrls.prog_test.value = 0
|
||||
_ctrls.path_dir.text = ""
|
||||
_ctrls.path_file.text = ""
|
||||
_ctrls.time_label.text = ""
|
||||
|
||||
_max_position = get_display_size() - Vector2(30, _ctrls.title_bar.size.y)
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
if _gut != null and _gut.is_running():
|
||||
set_elapsed_time(_gut.get_elapsed_time())
|
||||
|
||||
|
||||
# ------------------
|
||||
# Private
|
||||
# ------------------
|
||||
func get_display_size():
|
||||
return get_viewport().get_visible_rect().size
|
||||
|
||||
|
||||
func _populate_ctrls():
|
||||
# Brute force, but flexible. This allows for all the controls to exist
|
||||
# anywhere, and as long as they all have the right name, they will be
|
||||
# found.
|
||||
_ctrls.btn_continue = _get_first_child_named("Continue", self)
|
||||
_ctrls.path_dir = _get_first_child_named("Path", self)
|
||||
_ctrls.path_file = _get_first_child_named("File", self)
|
||||
_ctrls.prog_script = _get_first_child_named("ProgressScript", self)
|
||||
_ctrls.prog_test = _get_first_child_named("ProgressTest", self)
|
||||
_ctrls.rtl = _get_first_child_named("TestOutput", self)
|
||||
_ctrls.rtl_bg = _get_first_child_named("OutputBG", self)
|
||||
_ctrls.switch_modes = _get_first_child_named("SwitchModes", self)
|
||||
_ctrls.time_label = _get_first_child_named("TimeLabel", self)
|
||||
_ctrls.title = _get_first_child_named("Title", self)
|
||||
_ctrls.title_bar = _get_first_child_named("TitleBar", self)
|
||||
|
||||
|
||||
func _get_first_child_named(obj_name, parent_obj):
|
||||
if parent_obj == null:
|
||||
return null
|
||||
|
||||
var kids = parent_obj.get_children()
|
||||
var index = 0
|
||||
var to_return = null
|
||||
|
||||
while index < kids.size() and to_return == null:
|
||||
if str(kids[index]).find(str(obj_name, ":")) != -1:
|
||||
to_return = kids[index]
|
||||
else:
|
||||
to_return = _get_first_child_named(obj_name, kids[index])
|
||||
if to_return == null:
|
||||
index += 1
|
||||
|
||||
return to_return
|
||||
|
||||
|
||||
# ------------------
|
||||
# Events
|
||||
# ------------------
|
||||
func _on_title_bar_input(event: InputEvent):
|
||||
if event is InputEventMouseMotion:
|
||||
if _title_mouse.down:
|
||||
position += event.relative
|
||||
position.x = clamp(position.x, 0, _max_position.x)
|
||||
position.y = clamp(position.y, 0, _max_position.y)
|
||||
elif event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT:
|
||||
_title_mouse.down = event.pressed
|
||||
|
||||
|
||||
func _on_continue_pressed():
|
||||
_gut.end_teardown_pause()
|
||||
|
||||
|
||||
func _on_gut_start_run():
|
||||
if _ctrls.rtl != null:
|
||||
_ctrls.rtl.clear()
|
||||
set_num_scripts(_gut.get_test_collector().scripts.size())
|
||||
|
||||
|
||||
func _on_gut_end_run():
|
||||
_ctrls.prog_test.value = _ctrls.prog_test.max_value
|
||||
_ctrls.prog_script.value = _ctrls.prog_script.max_value
|
||||
|
||||
|
||||
func _on_gut_start_script(script_obj):
|
||||
next_script(script_obj.get_full_name(), script_obj.tests.size())
|
||||
|
||||
|
||||
func _on_gut_end_script():
|
||||
pass
|
||||
|
||||
|
||||
func _on_gut_start_test(test_name):
|
||||
next_test(test_name)
|
||||
|
||||
|
||||
func _on_gut_end_test():
|
||||
pass
|
||||
|
||||
|
||||
func _on_gut_start_pause():
|
||||
pause_before_teardown()
|
||||
|
||||
|
||||
func _on_gut_end_pause():
|
||||
_ctrls.btn_continue.visible = false
|
||||
|
||||
|
||||
func _on_switch_modes_pressed():
|
||||
switch_modes.emit()
|
||||
|
||||
|
||||
# ------------------
|
||||
# Public
|
||||
# ------------------
|
||||
func set_num_scripts(val):
|
||||
_ctrls.prog_script.value = 0
|
||||
_ctrls.prog_script.max_value = val
|
||||
|
||||
|
||||
func next_script(path, num_tests):
|
||||
_ctrls.prog_script.value += 1
|
||||
_ctrls.prog_test.value = 0
|
||||
_ctrls.prog_test.max_value = num_tests
|
||||
|
||||
_ctrls.path_dir.text = path.get_base_dir()
|
||||
_ctrls.path_file.text = path.get_file()
|
||||
|
||||
|
||||
func next_test(test_name):
|
||||
_ctrls.prog_test.value += 1
|
||||
|
||||
|
||||
func pause_before_teardown():
|
||||
_ctrls.btn_continue.visible = true
|
||||
|
||||
|
||||
func set_gut(g):
|
||||
if _gut == g:
|
||||
return
|
||||
_gut = g
|
||||
g.start_run.connect(_on_gut_start_run)
|
||||
g.end_run.connect(_on_gut_end_run)
|
||||
|
||||
g.start_script.connect(_on_gut_start_script)
|
||||
g.end_script.connect(_on_gut_end_script)
|
||||
|
||||
g.start_test.connect(_on_gut_start_test)
|
||||
g.end_test.connect(_on_gut_end_test)
|
||||
|
||||
g.start_pause_before_teardown.connect(_on_gut_start_pause)
|
||||
g.end_pause_before_teardown.connect(_on_gut_end_pause)
|
||||
|
||||
|
||||
func get_gut():
|
||||
return _gut
|
||||
|
||||
|
||||
func get_textbox():
|
||||
return _ctrls.rtl
|
||||
|
||||
|
||||
func set_elapsed_time(t):
|
||||
_ctrls.time_label.text = str("%6.1f" % t, "s")
|
||||
|
||||
|
||||
func set_bg_color(c):
|
||||
_ctrls.rtl_bg.color = c
|
||||
|
||||
|
||||
func set_title(text):
|
||||
_ctrls.title.text = text
|
||||
|
||||
|
||||
func to_top_left():
|
||||
self.position = Vector2(5, 5)
|
||||
|
||||
|
||||
func to_bottom_right():
|
||||
var win_size = get_display_size()
|
||||
self.position = win_size - Vector2(self.size) - Vector2(5, 5)
|
||||
|
||||
|
||||
func align_right():
|
||||
var win_size = get_display_size()
|
||||
self.position.x = win_size.x - self.size.x - 5
|
||||
self.position.y = 5
|
||||
self.size.y = win_size.y - 10
|
|
@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/play.png-5c90e88e8136487a183a099d67a7de24.cte
|
|||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Holds weakrefs to a ScriptTextEditor and related children nodes
|
||||
# that might be useful. Though the TextEdit is really the only one, but
|
||||
# that might be useful. Though the CodeEdit is really the only one, but
|
||||
# since the tree may change, the first TextEdit under a CodeTextEditor is
|
||||
# the one we use...so we hold a ref to the CodeTextEditor too.
|
||||
class ScriptEditorControlRef:
|
||||
|
@ -10,6 +10,7 @@ class ScriptEditorControlRef:
|
|||
func _init(script_edit):
|
||||
_script_editor = weakref(script_edit)
|
||||
_populate_controls()
|
||||
# print("_script_editor = ", script_edit, ' vis = ', is_visible())
|
||||
|
||||
func _populate_controls():
|
||||
# who knows if the tree will change so get the first instance of each
|
||||
|
@ -27,7 +28,7 @@ class ScriptEditorControlRef:
|
|||
var to_return = null
|
||||
|
||||
while index < kids.size() and to_return == null:
|
||||
if str(kids[index]).find(str("[", obj_name)) != -1:
|
||||
if str(kids[index]).find(str("<", obj_name)) != -1:
|
||||
to_return = kids[index]
|
||||
else:
|
||||
to_return = _get_first_child_named(obj_name, kids[index])
|
||||
|
@ -79,7 +80,7 @@ func _init(script_edit):
|
|||
|
||||
|
||||
func _is_script_editor(obj):
|
||||
return str(obj).find("[ScriptTextEditor") != -1
|
||||
return str(obj).find("<ScriptTextEditor") != -1
|
||||
|
||||
|
||||
# Find the first ScriptTextEditor and then get its parent. Done this way
|
||||
|
@ -106,14 +107,19 @@ func _populate_editors():
|
|||
# easier than trying to find a place where it could be used by both.
|
||||
func _get_first_child_of_type_name(obj_name, parent_obj):
|
||||
if parent_obj == null:
|
||||
# print('aborting search for ', obj_name, ' parent is null')
|
||||
return null
|
||||
|
||||
var kids = parent_obj.get_children()
|
||||
var index = 0
|
||||
var to_return = null
|
||||
|
||||
var search_for = str("<", obj_name)
|
||||
# print('searching for ', search_for, ' in ', parent_obj, ' kids ', kids.size())
|
||||
while index < kids.size() and to_return == null:
|
||||
if str(kids[index]).find(str("[", obj_name)) != -1:
|
||||
var this_one = str(kids[index])
|
||||
# print(search_for, ' :: ', this_one)
|
||||
if this_one.find(search_for) != -1:
|
||||
to_return = kids[index]
|
||||
else:
|
||||
to_return = _get_first_child_of_type_name(obj_name, kids[index])
|
||||
|
@ -140,10 +146,13 @@ func _get_class_name_from_line(text):
|
|||
func refresh():
|
||||
if _script_editors_parent == null:
|
||||
_find_script_editors_parent()
|
||||
# print("script editors parent = ", _script_editors_parent)
|
||||
|
||||
if _script_editors_parent != null:
|
||||
_populate_editors()
|
||||
|
||||
# print("script editor controls = ", _script_editor_controls)
|
||||
|
||||
|
||||
func get_current_text_edit():
|
||||
var cur_script_editor = null
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue