From e8f4d88e931b7a7baa56d4333dfba0732ed35cd7 Mon Sep 17 00:00:00 2001 From: don-tnowe <67479453+don-tnowe@users.noreply.github.com> Date: Thu, 6 Oct 2022 19:43:30 +0300 Subject: [PATCH] Implement splitting big table into pages --- .../resources_speadsheet_view/editor_view.gd | 47 +++++--- .../editor_view.tscn | 71 ++++++++--- .../resources_speadsheet_view/table_pages.gd | 110 ++++++++++++++++++ 3 files changed, 200 insertions(+), 28 deletions(-) create mode 100644 addons/resources_speadsheet_view/table_pages.gd diff --git a/addons/resources_speadsheet_view/editor_view.gd b/addons/resources_speadsheet_view/editor_view.gd index e1aa986..f9254b5 100644 --- a/addons/resources_speadsheet_view/editor_view.gd +++ b/addons/resources_speadsheet_view/editor_view.gd @@ -1,6 +1,8 @@ tool extends Control +signal grid_updated() + export var table_header_scene : PackedScene export(Array, Script) var cell_editor_classes := [] @@ -11,6 +13,7 @@ export var path_table_root := NodePath("") export var path_property_editors := NodePath("") export var path_columns := NodePath("") export var path_hide_columns_button := NodePath("") +export var path_page_manager := NodePath("") var editor_interface : EditorInterface var editor_plugin : EditorPlugin @@ -39,6 +42,8 @@ var inspector_resource : Resource var search_cond : Reference var hidden_columns := {} +var first_row := 0 +var last_row := 0 func _ready(): @@ -95,6 +100,8 @@ func display_folder(folderpath : String, sort_by : String = "", sort_reverse : b if search_cond == null: _on_SearchCond_text_entered("true") + first_row = get_node(path_page_manager).first_row + last_row = min(get_node(path_page_manager).last_row, rows.size()) _load_resources_from_folder(folderpath, sort_by, sort_reverse) if columns.size() == 0: return @@ -112,9 +119,12 @@ func display_folder(folderpath : String, sort_by : String = "", sort_reverse : b if get_node(path_table_root).get_child_count() == 0: display_folder(folderpath, sort_by, sort_reverse, force_rebuild) + else: + emit_signal("grid_updated") -func refresh(): - display_folder(current_path, sorting_by, sorting_reverse, true) + +func refresh(force_rebuild : bool = true): + display_folder(current_path, sorting_by, sorting_reverse, force_rebuild) func _load_resources_from_folder(folderpath : String, sort_by : String, sort_reverse : bool): @@ -219,14 +229,23 @@ func _create_table(columns_changed : bool): new_node.set_label(x) new_node.get_node("Button").connect("pressed", self, "_set_sorting", [x]) - var to_free = root_node.get_child_count() - rows.size() * columns.size() + var to_free = root_node.get_child_count() - (last_row - first_row) * columns.size() while to_free > 0: - root_node.get_child(columns.size()).free() + root_node.get_child(0).free() to_free -= 1 var color_rows = ProjectSettings.get_setting(SettingsGrid.SETTING_PREFIX + "color_rows") - for i in rows.size(): - _update_row(i, color_rows) + + _update_row_range( + first_row, + last_row, + color_rows + ) + + +func _update_row_range(first : int, last : int, color_rows : bool): + for i in last - first: + _update_row(first + i, color_rows) func _update_column_sizes(): @@ -267,13 +286,13 @@ func _update_row(row_index : int, color_rows : bool = true): var current_node : Control var next_color := Color.white for i in columns.size(): - if root_node.get_child_count() <= row_index * columns.size() + i: + if root_node.get_child_count() <= (row_index - first_row) * columns.size() + i: current_node = column_editors[i].create_cell(self) current_node.connect("gui_input", self, "_on_cell_gui_input", [current_node]) root_node.add_child(current_node) else: - current_node = root_node.get_child(row_index * columns.size() + i) + current_node = root_node.get_child((row_index - first_row) * columns.size() + i) current_node.hint_tooltip = ( TextEditingUtils.string_snake_to_naming_case(columns[i]) + "\n---\n" @@ -301,7 +320,7 @@ func _update_hidden_columns(): var column_visible = !hidden_columns[current_path].has(columns[i]) get_node(path_columns).get_child(i).visible = column_visible - for j in rows.size(): + for j in last_row - first_row: node_table_root.get_child(j * columns.size() + i).visible = column_visible if column_visible: @@ -408,8 +427,8 @@ func select_cells_to(cell : Control): if column_index != _get_cell_column(edited_cells[edited_cells.size() - 1]): return - var row_start = _get_cell_row(edited_cells[edited_cells.size() - 1]) - var row_end := _get_cell_row(cell) + var row_start = _get_cell_row(edited_cells[edited_cells.size() - 1]) - first_row + var row_end := _get_cell_row(cell) - first_row var edge_shift = -1 if row_start > row_end else 1 row_start += edge_shift row_end += edge_shift @@ -544,7 +563,7 @@ func _get_cell_column(cell) -> int: func _get_cell_row(cell) -> int: - return cell.get_position_in_parent() / columns.size() + return cell.get_position_in_parent() / columns.size() + first_row func _update_scroll(): @@ -723,7 +742,7 @@ func _update_resources(update_rows : Array, update_cells : Array, update_column column_editors[j + update_column].set_color( update_cells[i].get_parent().get_child( - _get_cell_row(update_cells[i]) * columns.size() + update_column + j + _get_cell_row(update_cells[i]) * columns.size() + update_column + j - first_row ), values[i] ) @@ -797,7 +816,7 @@ func _on_inspector_property_edited(property : String): var index := 0 for i in previously_edited.size(): index = _get_cell_row(previously_edited[i]) * columns.size() + new_column - _add_cell_to_selection(get_node(path_table_root).get_child(index)) + _add_cell_to_selection(get_node(path_table_root).get_child(index - first_row)) set_edited_cells_values(values) _try_open_docks(edited_cells[0]) diff --git a/addons/resources_speadsheet_view/editor_view.tscn b/addons/resources_speadsheet_view/editor_view.tscn index 02d215c..b451de2 100644 --- a/addons/resources_speadsheet_view/editor_view.tscn +++ b/addons/resources_speadsheet_view/editor_view.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=19 format=2] +[gd_scene load_steps=20 format=2] [ext_resource path="res://addons/resources_speadsheet_view/editor_view.gd" type="Script" id=1] [ext_resource path="res://addons/resources_speadsheet_view/typed_cells/cell_editor_string.gd" type="Script" id=2] @@ -16,6 +16,7 @@ [ext_resource path="res://addons/resources_speadsheet_view/settings_grid.gd" type="Script" id=14] [ext_resource path="res://addons/resources_speadsheet_view/typed_cells/cell_editor_enum_array.gd" type="Script" id=15] [ext_resource path="res://addons/resources_speadsheet_view/typed_editors/dock_enum_array.tscn" type="PackedScene" id=16] +[ext_resource path="res://addons/resources_speadsheet_view/table_pages.gd" type="Script" id=17] [sub_resource type="Image" id=3] data = { @@ -60,6 +61,7 @@ path_table_root = NodePath("HeaderContentSplit/MarginContainer/FooterContentSpli path_property_editors = NodePath("HeaderContentSplit/MarginContainer/FooterContentSplit/Footer/PropertyEditors") path_columns = NodePath("HeaderContentSplit/VBoxContainer/Columns/Columns") path_hide_columns_button = NodePath("HeaderContentSplit/VBoxContainer/HBoxContainer2/VisibleCols") +path_page_manager = NodePath("HeaderContentSplit/VBoxContainer/Pages") [node name="HeaderContentSplit" type="VBoxContainer" parent="."] margin_left = 3.0 @@ -71,7 +73,7 @@ __meta__ = { [node name="VBoxContainer" type="VBoxContainer" parent="HeaderContentSplit"] margin_right = 1018.0 -margin_bottom = 54.0 +margin_bottom = 56.0 custom_constants/separation = 2 __meta__ = { "_edit_lock_": true @@ -226,27 +228,66 @@ __meta__ = { "_edit_lock_": true } -[node name="Sep" type="Control" parent="HeaderContentSplit/VBoxContainer"] +[node name="Sep4" type="Control" parent="HeaderContentSplit/VBoxContainer"] margin_top = 50.0 margin_right = 1018.0 margin_bottom = 50.0 -[node name="Columns" type="Control" parent="HeaderContentSplit/VBoxContainer"] +[node name="Pages" type="HBoxContainer" parent="HeaderContentSplit/VBoxContainer"] +visible = false +margin_top = 50.0 +margin_right = 1018.0 +margin_bottom = 74.0 +script = ExtResource( 17 ) +path_editor_view_root = NodePath("../../..") + +[node name="Label" type="Label" parent="HeaderContentSplit/VBoxContainer/Pages"] +margin_top = 5.0 +margin_right = 34.0 +margin_bottom = 19.0 +text = "Page:" + +[node name="Pagelist" type="HBoxContainer" parent="HeaderContentSplit/VBoxContainer/Pages"] +margin_left = 38.0 +margin_right = 38.0 +margin_bottom = 24.0 + +[node name="Label2" type="Label" parent="HeaderContentSplit/VBoxContainer/Pages"] +margin_left = 42.0 +margin_top = 5.0 +margin_right = 138.0 +margin_bottom = 19.0 +text = "Rows per page:" + +[node name="LineEdit" type="SpinBox" parent="HeaderContentSplit/VBoxContainer/Pages"] +margin_left = 142.0 +margin_right = 200.0 +margin_bottom = 24.0 +min_value = 2.0 +max_value = 300.0 +value = 50.0 + +[node name="Sep3" type="Control" parent="HeaderContentSplit/VBoxContainer"] margin_top = 52.0 margin_right = 1018.0 margin_bottom = 52.0 + +[node name="Columns" type="Control" parent="HeaderContentSplit/VBoxContainer"] +margin_top = 54.0 +margin_right = 1018.0 +margin_bottom = 54.0 rect_clip_content = true [node name="Columns" type="Control" parent="HeaderContentSplit/VBoxContainer/Columns"] margin_right = 1020.0 [node name="Sep2" type="Control" parent="HeaderContentSplit/VBoxContainer"] -margin_top = 54.0 +margin_top = 56.0 margin_right = 1018.0 -margin_bottom = 54.0 +margin_bottom = 56.0 [node name="MarginContainer" type="MarginContainer" parent="HeaderContentSplit"] -margin_top = 58.0 +margin_top = 60.0 margin_right = 1018.0 margin_bottom = 597.0 mouse_filter = 2 @@ -258,7 +299,7 @@ __meta__ = { [node name="FooterContentSplit" type="VBoxContainer" parent="HeaderContentSplit/MarginContainer"] margin_right = 1018.0 -margin_bottom = 539.0 +margin_bottom = 537.0 size_flags_horizontal = 3 size_flags_vertical = 3 __meta__ = { @@ -267,7 +308,7 @@ __meta__ = { [node name="Panel" type="MarginContainer" parent="HeaderContentSplit/MarginContainer/FooterContentSplit"] margin_right = 1018.0 -margin_bottom = 489.0 +margin_bottom = 487.0 mouse_filter = 2 size_flags_vertical = 3 __meta__ = { @@ -276,14 +317,14 @@ __meta__ = { [node name="Panel" type="Panel" parent="HeaderContentSplit/MarginContainer/FooterContentSplit/Panel"] margin_right = 1018.0 -margin_bottom = 489.0 +margin_bottom = 487.0 __meta__ = { "_edit_lock_": true } [node name="Scroll" type="ScrollContainer" parent="HeaderContentSplit/MarginContainer/FooterContentSplit/Panel"] margin_right = 1018.0 -margin_bottom = 489.0 +margin_bottom = 487.0 mouse_filter = 1 size_flags_horizontal = 3 size_flags_vertical = 3 @@ -311,7 +352,7 @@ __meta__ = { [node name="Label" type="Label" parent="HeaderContentSplit/MarginContainer/FooterContentSplit/Panel"] self_modulate = Color( 1, 1, 1, 0.498039 ) margin_right = 1018.0 -margin_bottom = 489.0 +margin_bottom = 487.0 size_flags_horizontal = 3 size_flags_vertical = 3 text = "No folder selected! @@ -325,9 +366,9 @@ align = 1 valign = 1 [node name="Footer" type="VBoxContainer" parent="HeaderContentSplit/MarginContainer/FooterContentSplit"] -margin_top = 493.0 +margin_top = 491.0 margin_right = 1018.0 -margin_bottom = 539.0 +margin_bottom = 537.0 __meta__ = { "_edit_lock_": true } @@ -658,6 +699,7 @@ margin_bottom = 150.0 pressed = true text = "Enable" +[connection signal="grid_updated" from="." to="HeaderContentSplit/VBoxContainer/Pages" method="_on_Control_grid_updated"] [connection signal="about_to_show" from="HeaderContentSplit/VBoxContainer/HBoxContainer2/VisibleCols" to="." method="_on_VisibleCols_about_to_show"] [connection signal="pressed" from="HeaderContentSplit/VBoxContainer/HBoxContainer2/Settings" to="Control/Settings" method="popup_centered"] [connection signal="pressed" from="HeaderContentSplit/VBoxContainer/HBoxContainer2/Info" to="Control/Info" method="popup_centered"] @@ -666,6 +708,7 @@ text = "Enable" [connection signal="pressed" from="HeaderContentSplit/VBoxContainer/HBoxContainer/HBoxContainer/Refresh" to="." method="_on_Path_text_entered"] [connection signal="pressed" from="HeaderContentSplit/VBoxContainer/HBoxContainer/HBoxContainer/DeletePath" to="." method="remove_selected_path_from_recent"] [connection signal="item_selected" from="HeaderContentSplit/VBoxContainer/HBoxContainer/HBoxContainer2/RecentPaths" to="." method="_on_RecentPaths_item_selected"] +[connection signal="value_changed" from="HeaderContentSplit/VBoxContainer/Pages/LineEdit" to="HeaderContentSplit/VBoxContainer/Pages" method="_on_LineEdit_value_changed"] [connection signal="text_entered" from="HeaderContentSplit/MarginContainer/FooterContentSplit/Footer/Search/SearchCond" to="." method="_on_SearchCond_text_entered"] [connection signal="text_entered" from="HeaderContentSplit/MarginContainer/FooterContentSplit/Footer/Search/ProcessExpr" to="." method="_on_ProcessExpr_text_entered"] [connection signal="dir_selected" from="Control/FileDialog" to="." method="_on_FileDialog_dir_selected"] diff --git a/addons/resources_speadsheet_view/table_pages.gd b/addons/resources_speadsheet_view/table_pages.gd new file mode 100644 index 0000000..8d96d50 --- /dev/null +++ b/addons/resources_speadsheet_view/table_pages.gd @@ -0,0 +1,110 @@ +tool +extends HBoxContainer + +export var path_editor_view_root := NodePath("") + +# These can not be set externally. +var rows_per_page := 50 setget _set_none +var current_page := 0 setget _set_none +var first_row := 0 setget _set_none +var last_row := 50 setget _set_none + + +func _set_none(v): pass + + +func _on_Control_grid_updated(): + var root = get_node(path_editor_view_root) + visible = true + + var page_count = (root.rows.size() - 1) / rows_per_page + 1 + first_row = min(current_page, page_count) * rows_per_page + last_row = min(first_row + rows_per_page, root.rows.size()) + + var pagelist_node = $"Pagelist" + for x in pagelist_node.get_children(): + x.queue_free() + + var button_group = ButtonGroup.new() + var btns = [] + btns.resize(page_count) + for i in page_count: + var btn = Button.new() + btns[i] = btn + btn.toggle_mode = true + btn.group = button_group + btn.text = str(i + 1) + btn.connect("pressed", self, "_on_button_pressed", [btn]) + pagelist_node.add_child(btn) + + btns[current_page].pressed = true + + var sort_property = root.sorting_by + if sort_property == "": sort_property = "resource_path" + var sort_type = root.column_types[root.columns.find(sort_property)] + var property_values = [] + property_values.resize(page_count) + for i in page_count: + property_values[i] = root.rows[i * rows_per_page].get(sort_property) + + if sort_type == TYPE_REAL or sort_type == TYPE_INT: + for i in page_count: + btns[i].text = str(property_values[i]) + + elif sort_type == TYPE_COLOR: + for i in page_count: + btns[i].self_modulate = property_values[i] * 0.75 + Color(0.25, 0.25, 0.25, 1.0) + + elif sort_type == TYPE_STRING: + var strings = [] + strings.resize(page_count) + for i in page_count: + strings[i] = property_values[i].get_file() + if strings[i] == "": + strings[i] = str(i) + + _fill_buttons_with_prefixes(btns, strings, page_count) + + elif sort_type == TYPE_OBJECT: + var strings = [] + strings.resize(page_count + 1) + for i in page_count: + if is_instance_valid(property_values[i]): + strings[i] = property_values[i].resource_path.get_file() + + _fill_buttons_with_prefixes(btns, strings, page_count) + + +func _fill_buttons_with_prefixes(btns, strings, page_count): + for i in page_count: + if i == 0: + btns[0].text = strings[0][0] + continue + + for j in strings[i].length(): + if strings[i].ord_at(j) != strings[i - 1].ord_at(j): + btns[i].text = strings[i].left(j + 1) + btns[i - 1].text = strings[i - 1].left(max(j + 1, btns[i - 1].text.length())) + break + + for i in page_count - 1: + btns[i].text = btns[i].text + "-" + btns[i + 1].text + + btns[page_count - 1].text += "-[End]" + + +func _on_button_pressed(button): + button.pressed = true + current_page = button.get_position_in_parent() + _update_view() + + +func _on_LineEdit_value_changed(value): + rows_per_page = value + _update_view() + + +func _update_view(): + _on_Control_grid_updated() + var view = get_node(path_editor_view_root) + view.refresh(false)