Skip to content

Commit

Permalink
GD-449: Implement tree sort modes
Browse files Browse the repository at this point in the history
# Why
We want to have the tree sorted by certain criteria, alphabetic, natural, execution time.

# What
- Enable sorting by names ascending/descending and by test elapsed time
- move visualization of test elapsed time into a separate column to improve the tree readability
- fix small bug in the settings dialog to load the current setting on open
  • Loading branch information
MikeSchulze committed May 19, 2024
1 parent dd9bd46 commit 6fcb406
Show file tree
Hide file tree
Showing 10 changed files with 318 additions and 159 deletions.
15 changes: 13 additions & 2 deletions addons/gdUnit4/src/core/GdUnitSettings.gd
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ static func setup() -> void:
# inspector
create_property_if_need(INSPECTOR_NODE_COLLAPSE, true,
"Enables/Disables that the testsuite node is closed after a successful test run.")
create_property_if_need(INSPECTOR_TREE_VIEW_MODE, GdUnitInspectorTreeConstants.VIEW_MODE.TREE,
create_property_if_need(INSPECTOR_TREE_VIEW_MODE, GdUnitInspectorTreeConstants.VIEW_MODE.Tree,
"Sets the inspector panel presentation.", GdUnitInspectorTreeConstants.VIEW_MODE.keys())
create_property_if_need(INSPECTOR_TREE_SORT_MODE, GdUnitInspectorTreeConstants.SORT_MODE.NATURAL,
create_property_if_need(INSPECTOR_TREE_SORT_MODE, GdUnitInspectorTreeConstants.SORT_MODE.NAME_ASCENDING,
"Sets the inspector panel presentation.", GdUnitInspectorTreeConstants.SORT_MODE.keys())
create_property_if_need(INSPECTOR_TOOLBAR_BUTTON_RUN_OVERALL, false,
"Shows/Hides the 'Run overall Tests' button in the inspector toolbar.")
Expand Down Expand Up @@ -188,6 +188,17 @@ static func set_log_path(path :String) -> void:
ProjectSettings.save()


static func set_inspector_tree_sort_mode(sort_mode: GdUnitInspectorTreeConstants.SORT_MODE) -> void:
var property := get_property(INSPECTOR_TREE_SORT_MODE)
property.set_value(sort_mode)
update_property(property)


static func get_inspector_tree_sort_mode() -> GdUnitInspectorTreeConstants.SORT_MODE:
var property := get_property(INSPECTOR_TREE_SORT_MODE)
return property.value()


# the configured server connection timeout in ms
static func server_timeout() -> int:
return get_setting(SERVER_TIMEOUT, DEFAULT_SERVER_TIMEOUT) * 60 * 1000
Expand Down
2 changes: 1 addition & 1 deletion addons/gdUnit4/src/ui/GdUnitInspector.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ size_flags_vertical = 1
[node name="ProgressBar" parent="VBoxContainer/Header" instance=ExtResource("2")]
layout_mode = 2
size_flags_horizontal = 5
max_value = 0.0

[node name="StatusBar" parent="VBoxContainer/Header" instance=ExtResource("3")]
layout_mode = 2
Expand All @@ -53,7 +54,6 @@ layout_mode = 2
[connection signal="failure_next" from="VBoxContainer/Header/StatusBar" to="VBoxContainer/MainPanel" method="select_next_failure"]
[connection signal="failure_prevous" from="VBoxContainer/Header/StatusBar" to="VBoxContainer/MainPanel" method="select_previous_failure"]
[connection signal="request_discover_tests" from="VBoxContainer/Header/StatusBar" to="." method="_on_status_bar_request_discover_tests"]
[connection signal="tree_sort_mode_changed" from="VBoxContainer/Header/StatusBar" to="VBoxContainer/MainPanel" method="_on_status_bar_tree_sort_mode_changed"]
[connection signal="tree_view_mode_changed" from="VBoxContainer/Header/StatusBar" to="VBoxContainer/MainPanel" method="_on_status_bar_tree_view_mode_changed"]
[connection signal="run_testcase" from="VBoxContainer/MainPanel" to="." method="_on_MainPanel_run_testcase"]
[connection signal="run_testsuite" from="VBoxContainer/MainPanel" to="." method="_on_MainPanel_run_testsuite"]
Expand Down
8 changes: 4 additions & 4 deletions addons/gdUnit4/src/ui/GdUnitInspectorTreeConstants.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ extends RefCounted

# the inspector panel presantation
enum VIEW_MODE {
TREE,
FLAT
Tree,
Flat
}


# The inspector sort modes
enum SORT_MODE {
NATURAL,
NAME_ASCENDING,
NAME_DESCENDING
NAME_DESCENDING,
EXECUTION_TIME
}
34 changes: 31 additions & 3 deletions addons/gdUnit4/src/ui/GdUnitUiTools.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,34 @@ extends RefCounted
static var _spinner: AnimatedTexture


## Returns the icon property defined by name and theme_type, if it exists.
static func get_icon(icon_name: String, color:=Color.BLACK) -> Texture2D:
enum ImageFlipMode {
HORIZONTAl,
VERITCAL
}


## Returns the icon by name, if it exists.
static func get_icon(icon_name: String, color: = Color.BLACK) -> Texture2D:
if not Engine.is_editor_hint():
return null
var icon := EditorInterface.get_base_control().get_theme_icon(icon_name, "EditorIcons")
if icon == null:
return null
if color != Color.BLACK:
return _modulate_texture(icon, color)
icon = _modulate_texture(icon, color)
return icon


## Returns the icon flipped
static func get_flipped_icon(icon_name: String, mode: = ImageFlipMode.HORIZONTAl) -> Texture2D:
if not Engine.is_editor_hint():
return null
var icon := EditorInterface.get_base_control().get_theme_icon(icon_name, "EditorIcons")
if icon == null:
return null
return ImageTexture.create_from_image(_flip_image(icon, mode))


static func get_spinner() -> AnimatedTexture:
if _spinner != null:
return _spinner
Expand Down Expand Up @@ -119,6 +137,16 @@ static func _merge_images_scaled(image1: Image, offset1: Vector2i, image2: Image
return merged_image


static func _flip_image(texture: Texture2D, mode: ImageFlipMode) -> Image:
var flipped_image := Image.new()
flipped_image.copy_from(texture.get_image())
if mode == ImageFlipMode.VERITCAL:
flipped_image.flip_x()
else:
flipped_image.flip_y()
return flipped_image


static func _to_color(data: PackedByteArray, position: int) -> Color:
var pixel_a := Color()
pixel_a.r8 = data[position + 0]
Expand Down
47 changes: 44 additions & 3 deletions addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ extends PanelContainer
signal failure_next()
signal failure_prevous()
signal request_discover_tests()
signal tree_sort_mode_changed(asscending :bool)

signal tree_view_mode_changed(flat :bool)

@onready var _errors := %error_value
Expand All @@ -17,10 +17,18 @@ signal tree_view_mode_changed(flat :bool)
@onready var _button_view_mode := %btn_tree_mode
@onready var _button_sort_mode := %btn_tree_sort


var total_failed := 0
var total_errors := 0


var sort_mappings := {
GdUnitInspectorTreeConstants.SORT_MODE.NAME_ASCENDING : GdUnitUiTools.get_icon("Sort"),
GdUnitInspectorTreeConstants.SORT_MODE.NAME_DESCENDING : GdUnitUiTools.get_flipped_icon("Sort"),
GdUnitInspectorTreeConstants.SORT_MODE.EXECUTION_TIME : GdUnitUiTools.get_icon("History"),
}


func _ready() -> void:
GdUnitSignals.instance().gdunit_event.connect(_on_gdunit_event)
_failures.text = "0"
Expand All @@ -32,6 +40,33 @@ func _ready() -> void:
_button_sync.icon = GdUnitUiTools.get_icon("Loop")
_button_view_mode.icon = GdUnitUiTools.get_icon("Tree", Color.GHOST_WHITE)
_button_sort_mode.icon = GdUnitUiTools.get_icon("Sort")
_set_sort_mode_menu_options()
GdUnitSignals.instance().gdunit_settings_changed.connect(_on_settings_changed)


func _set_sort_mode_menu_options() -> void:
# construct context sort menu according to the available modes
var context_menu :PopupMenu = _button_sort_mode.get_popup()
context_menu.clear()

if not context_menu.index_pressed.is_connected(_on_sort_mode_changed):
context_menu.index_pressed.connect(_on_sort_mode_changed)

var sort_mode_property := GdUnitSettings.get_property(GdUnitSettings.INSPECTOR_TREE_SORT_MODE)
var selected_sort_mode :int = sort_mode_property.value()
for sort_mode in sort_mode_property.value_set():
var enum_value :int = GdUnitInspectorTreeConstants.SORT_MODE.get(sort_mode)
var icon :Texture2D = sort_mappings[enum_value]
context_menu.add_icon_check_item(icon, normalise(sort_mode), enum_value)
context_menu.set_item_checked(enum_value, selected_sort_mode == enum_value)


func normalise(value: String) -> String:
var parts := value.split("_")
var output := "By"
for p in parts:
output += " " + p.capitalize()
return output


func status_changed(errors: int, failed: int) -> void:
Expand Down Expand Up @@ -79,5 +114,11 @@ func _on_btn_tree_mode_toggled(toggled_on: bool) -> void:
tree_view_mode_changed.emit(toggled_on)


func _on_btn_tree_sort_toggled(toggled_on: bool) -> void:
tree_sort_mode_changed.emit(toggled_on)
func _on_sort_mode_changed(index: int) -> void:
var selected_sort_mode :GdUnitInspectorTreeConstants.SORT_MODE = GdUnitInspectorTreeConstants.SORT_MODE.values()[index]
GdUnitSettings.set_inspector_tree_sort_mode(selected_sort_mode)


func _on_settings_changed(property :GdUnitProperty) -> void:
if property.name() == GdUnitSettings.INSPECTOR_TREE_SORT_MODE:
_set_sort_mode_menu_options()
Loading

0 comments on commit 6fcb406

Please sign in to comment.