diff --git a/MainWindow.gd b/MainWindow.gd index 2eae59a..e5c690e 100644 --- a/MainWindow.gd +++ b/MainWindow.gd @@ -446,12 +446,8 @@ func get_suggestion_list() -> void: soundtracks = [] Settings.delete_children(inspiration_list) soundtracks.append_array(array) - for soundtrack: String in soundtracks: - var inspiration_label: Label = Label.new() - inspiration_label.add_theme_font_size_override("font_size", 20) - inspiration_label.text = soundtrack - inspiration_label.autowrap_mode = TextServer.AUTOWRAP_WORD - inspiration_list.add_child(inspiration_label) + for i: int in soundtracks.size(): + inspiration_list.add_child(ListRow.create(soundtracks[i], i, 20)) else: print("Unexpected data") MusicServerClient.fetch_all_soundtracks(populate_list) @@ -572,7 +568,5 @@ func dir_contents(path: String) -> void: else: print("An error occurred when trying to access the path.") - for soundtrack: String in soundtracks: - var local_inspiration_label: Label = Label.new() - local_inspiration_label.text = soundtrack - inspiration_list.add_child(local_inspiration_label) + for i: int in soundtracks.size(): + inspiration_list.add_child(ListRow.create(soundtracks[i], i, 20)) diff --git a/list_row.gd b/list_row.gd new file mode 100644 index 0000000..c9fd8eb --- /dev/null +++ b/list_row.gd @@ -0,0 +1,57 @@ +class_name ListRow +extends PanelContainer +## One item in a list of names, such as the inspiration list or a sync result column. +## +## Every row has its own background, alternating between two shades, so it is clear +## where an item starts even when its text wraps over several lines. + +const EVEN_BACKGROUND: Color = Color(1, 1, 1, 0.05) +const ODD_BACKGROUND: Color = Color(1, 1, 1, 0.11) + +static var _even_style: StyleBoxFlat +static var _odd_style: StyleBoxFlat + +## The label showing the item's text. +var label: Label + +## The item's text. +var text: String: + get: + return label.text + + +## Creates the row for item number [param row] (counting from 0) in a list. +static func create( + item_text: String, + row: int, + font_size: int, + alignment: HorizontalAlignment = HORIZONTAL_ALIGNMENT_LEFT, +) -> ListRow: + var list_row: ListRow = ListRow.new() + list_row.add_theme_stylebox_override("panel", _style(row % 2 != 0)) + list_row.label = Label.new() + list_row.label.add_theme_font_size_override("font_size", font_size) + list_row.label.text = item_text + list_row.label.horizontal_alignment = alignment + list_row.label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART + list_row.add_child(list_row.label) + return list_row + + +# Rows share two styles instead of each creating its own +static func _style(odd: bool) -> StyleBoxFlat: + if _even_style == null: + _even_style = _make_style(EVEN_BACKGROUND) + _odd_style = _make_style(ODD_BACKGROUND) + return _odd_style if odd else _even_style + + +static func _make_style(background: Color) -> StyleBoxFlat: + var style: StyleBoxFlat = StyleBoxFlat.new() + style.bg_color = background + style.set_corner_radius_all(4) + style.content_margin_left = 8 + style.content_margin_right = 8 + style.content_margin_top = 2 + style.content_margin_bottom = 2 + return style diff --git a/list_row.gd.uid b/list_row.gd.uid new file mode 100644 index 0000000..c92d518 --- /dev/null +++ b/list_row.gd.uid @@ -0,0 +1 @@ +uid://c2o2qunso5n8l diff --git a/sync_window.gd b/sync_window.gd index 352e768..34869cb 100644 --- a/sync_window.gd +++ b/sync_window.gd @@ -126,10 +126,9 @@ func on_sync_finished(data_received: Dictionary) -> void: make_header_label(soundtracks_changed_title_vbox, "Changed Title") var row: int = 0 for old_soundtrack_title: String in data_received.soundtracks_changed_title: - var label: Label = make_soundtrack_label(old_soundtrack_title + "\nchanged title to\n" + data_received.soundtracks_changed_title[old_soundtrack_title]) - if row % 2 != 0: - label.add_theme_color_override("font_color", Color(1, 0.5, 0)) - soundtracks_changed_title_vbox.add_child(label) + var new_soundtrack_title: String = data_received.soundtracks_changed_title[old_soundtrack_title] + soundtracks_changed_title_vbox.add_child(make_soundtrack_row( + old_soundtrack_title + "\nchanged title to\n" + new_soundtrack_title, row)) row += 1 soundtracks_changed_title_vbox.visible = true @@ -194,13 +193,12 @@ func make_header_label(vbox: VBoxContainer, text: String) -> void: label.text = text vbox.add_child(label) -func make_soundtrack_label(text: String) -> Label: - var label: Label = Label.new() - label.add_theme_font_size_override("font_size", 18) - label.text = text - label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - return label +# Items alternate between white and orange text as well as background shade +func make_soundtrack_row(text: String, row: int) -> ListRow: + var list_row: ListRow = ListRow.create(text, row, 18, HORIZONTAL_ALIGNMENT_CENTER) + if row % 2 != 0: + list_row.label.add_theme_color_override("font_color", Color(1, 0.5, 0)) + return list_row func reset_sync_result() -> void: sync_progress_bar.value = 0 @@ -222,13 +220,8 @@ func reset_sync_result() -> void: func make_list(list: Array, vbox: VBoxContainer, text: String) -> void: Settings.delete_children(vbox) make_header_label(vbox, text) - var row: int = 0 - for soundtrack: String in list: - var label: Label = make_soundtrack_label(soundtrack) - if row % 2 != 0: - label.add_theme_color_override("font_color", Color(1, 0.5, 0)) - vbox.add_child(label) - row += 1 + for row: int in list.size(): + vbox.add_child(make_soundtrack_row(list[row], row)) func show_sync_result() -> void: sync_title_label.text = "Sync Result" diff --git a/tests/integration/test_main_window.gd b/tests/integration/test_main_window.gd index 0b29042..390d221 100644 --- a/tests/integration/test_main_window.gd +++ b/tests/integration/test_main_window.gd @@ -240,3 +240,12 @@ func test_log_adds_one_row_per_point_with_padded_time() -> void: var time_pattern: RegEx = RegEx.create_from_string("^\\d\\d:\\d\\d:\\d\\d Crono got a point$") assert_object(time_pattern.search((log_box.get_child(0) as Label).text)).is_not_null() assert_str((log_box.get_child(1) as Label).text).ends_with("Crono lost a point") + + +func test_inspiration_list_alternates_row_backgrounds() -> void: + var rows: Array[Node] = _window.get_node("ScrollContainer/VBoxContainer").get_children() + + assert_int(rows.size()).is_equal(2) + assert_str((rows[0] as ListRow).text).is_equal("Chrono Trigger") + assert_that((rows[0] as ListRow).get_theme_stylebox("panel")) \ + .is_not_equal((rows[1] as ListRow).get_theme_stylebox("panel")) diff --git a/tests/integration/test_sync_window.gd b/tests/integration/test_sync_window.gd index b64371a..60e3dfa 100644 --- a/tests/integration/test_sync_window.gd +++ b/tests/integration/test_sync_window.gd @@ -113,7 +113,7 @@ func test_changed_titles_list_old_and_new_title() -> void: var vbox: Control = _node("SoundtracksChangedTitleVBox") assert_bool(vbox.visible).is_true() - assert_str((vbox.get_child(1) as Label).text).is_equal( + assert_str((vbox.get_child(1) as ListRow).text).is_equal( "FF7\nchanged title to\nFinal Fantasy VII") diff --git a/tests/unit/test_list_row.gd b/tests/unit/test_list_row.gd new file mode 100644 index 0000000..d25bb06 --- /dev/null +++ b/tests/unit/test_list_row.gd @@ -0,0 +1,26 @@ +extends GdUnitTestSuite + + +func _background(list_row: ListRow) -> Color: + return (list_row.get_theme_stylebox("panel") as StyleBoxFlat).bg_color + + +func test_row_shows_text() -> void: + var list_row: ListRow = auto_free(ListRow.create("Chrono Trigger", 0, 20)) + + assert_str(list_row.text).is_equal("Chrono Trigger") + + +func test_neighbouring_rows_have_different_backgrounds() -> void: + var first: ListRow = auto_free(ListRow.create("Chrono Trigger", 0, 20)) + var second: ListRow = auto_free(ListRow.create("Chrono Cross", 1, 20)) + var third: ListRow = auto_free(ListRow.create("Xenogears", 2, 20)) + + assert_that(_background(first)).is_not_equal(_background(second)) + assert_that(_background(first)).is_equal(_background(third)) + + +func test_long_text_wraps() -> void: + var list_row: ListRow = auto_free(ListRow.create("Castlevania: Symphony of the Night", 0, 20)) + + assert_int(list_row.label.autowrap_mode).is_equal(TextServer.AUTOWRAP_WORD_SMART) diff --git a/tests/unit/test_list_row.gd.uid b/tests/unit/test_list_row.gd.uid new file mode 100644 index 0000000..70b4210 --- /dev/null +++ b/tests/unit/test_list_row.gd.uid @@ -0,0 +1 @@ +uid://bouligcywd5se