Huge text cursor and cell selection improvements

This commit is contained in:
don-tnowe 2023-06-06 13:21:04 +03:00
parent 5047462af5
commit 6a05d7827c
4 changed files with 103 additions and 45 deletions

View File

@ -466,10 +466,13 @@ text = "Edit Resources as Spreadsheet
Possible inputs:
- Ctrl + Click / Cmd + Click - Select multiple cells in one column
- Shift + Click - Select all cells between A and B in one column
- Up / Down / Shift+Tab / Tab - move cell selection up/down/left/right
- Left/Right - Move cursor along cell text
- Backspace/Delete - Erase text Left / Right from cursor
- Home/End - Move cursor to start/end of cell
- Ctrl + <move/erase> / Cmd + <move/erase> - Move through / Erase whole word
- Ctrl/Cmd + C/V - Copy cells / Paste text into cells
- Ctrl/Cmd + (Shift) + Z - The Savior
If clipboard contains as many lines as there are cells selected, each line is pasted into a separate cell.
@ -507,7 +510,9 @@ offset_bottom = 117.0
[node name="InputHandler" type="Node" parent="."]
script = ExtResource("14_2t57a")
[node name="SelectionManager" type="Node" parent="." node_paths=PackedStringArray("node_property_editors")]
[node name="SelectionManager" type="Control" parent="." node_paths=PackedStringArray("node_property_editors")]
layout_mode = 2
mouse_filter = 2
script = ExtResource("15_mx6qn")
cell_editor_classes = Array[Script]([ExtResource("16_p7n52"), ExtResource("17_sofdw"), ExtResource("18_oeewr"), ExtResource("19_7x44x"), ExtResource("20_swsbn"), ExtResource("21_58wf8"), ExtResource("22_bni8r")])
node_property_editors = NodePath("../HeaderContentSplit/MarginContainer/FooterContentSplit/Footer/PropertyEditors")

View File

@ -11,17 +11,14 @@ const SelectionManager = preload("res://addons/resources_spreadsheet_view/main_s
func _on_cell_gui_input(event : InputEvent, cell : Control):
if event is InputEventMouseButton:
editor_view.grab_focus()
if event.button_index != MOUSE_BUTTON_LEFT:
if event.button_index == MOUSE_BUTTON_RIGHT && event.is_pressed():
if !cell in selection.edited_cells:
selection.deselect_all_cells()
selection.select_cell(cell)
if event.button_index == MOUSE_BUTTON_RIGHT and event.pressed:
if !cell in selection.edited_cells:
selection.deselect_all_cells()
selection.select_cell(cell)
selection.rightclick_cells()
selection.rightclick_cells()
return
if event.pressed:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
if Input.is_key_pressed(KEY_CTRL):
if cell in selection.edited_cells:
selection.deselect_cell(cell)
@ -39,15 +36,13 @@ func _on_cell_gui_input(event : InputEvent, cell : Control):
func _gui_input(event : InputEvent):
if event is InputEventMouseButton:
if event.button_index != MOUSE_BUTTON_LEFT:
if event.button_index == MOUSE_BUTTON_RIGHT && event.is_pressed():
selection.rightclick_cells()
if event.button_index == MOUSE_BUTTON_RIGHT and event.is_pressed():
selection.rightclick_cells()
return
editor_view.grab_focus()
if !event.pressed:
selection.deselect_all_cells()
if event.button_index == MOUSE_BUTTON_LEFT:
editor_view.grab_focus()
if !event.pressed:
selection.deselect_all_cells()
func _input(event : InputEvent):
@ -128,7 +123,7 @@ func _key_specific_action(event : InputEvent):
# Ctrl + C (so you can edit in a proper text editor instead of this wacky nonsense)
elif ctrl_pressed and event.keycode == KEY_C:
TextEditingUtils.multi_copy(selection.edited_cells_text)
get_tree().set_input_as_handled()
get_viewport().set_input_as_handled()
# The following actions do not work on non-editable cells.
if !selection.column_editors[column].is_text() or editor_view.columns[column] == "resource_path":
@ -139,7 +134,7 @@ func _key_specific_action(event : InputEvent):
editor_view.set_edited_cells_values(TextEditingUtils.multi_paste(
selection.edited_cells_text, selection.edit_cursor_positions
))
get_tree().set_input_as_handled()
get_viewport().set_input_as_handled()
# ERASING
elif event.keycode == KEY_BACKSPACE:
@ -164,14 +159,18 @@ func _key_specific_action(event : InputEvent):
char(event.unicode), selection.edited_cells_text, selection.edit_cursor_positions
))
selection.queue_redraw()
func _move_selection_on_grid(move_h : int, move_v : int):
var cell = selection.edited_cells[0]
var selected_cells := selection.edited_cells.duplicate()
for i in selected_cells.size():
selected_cells[i] = editor_view.node_table_root.get_child(
selected_cells[i].get_index()
+ move_h
+ move_v * editor_view.columns.size()
)
editor_view.grab_focus()
selection.deselect_all_cells()
selection.select_cell(
editor_view.node_table_root.get_child(
cell.get_index()
+ move_h + move_v * editor_view.columns.size()
)
)
selection.select_cells(selected_cells)

View File

@ -1,5 +1,5 @@
@tool
extends Node
extends Control
signal cells_selected(cells)
signal cells_rightclicked(cells)
@ -9,12 +9,13 @@ const EditorView = preload("res://addons/resources_spreadsheet_view/editor_view.
@export var cell_editor_classes : Array[Script] = []
@export @onready var node_property_editors : VBoxContainer = $"../HeaderContentSplit/MarginContainer/FooterContentSplit/Footer/PropertyEditors"
@export @onready var scrollbar : ScrollContainer = $"../HeaderContentSplit/MarginContainer/FooterContentSplit/Panel/Scroll"
@onready var editor_view : EditorView = get_parent()
var edited_cells := []
var edited_cells_text := []
var edit_cursor_positions := []
var edited_cells = []
var edited_cells_text : Array[String] = []
var edit_cursor_positions : Array[int] = []
var all_cell_editors : Array[Object]
var column_editors := []
@ -33,6 +34,38 @@ func _ready():
.property_edited\
.connect(_on_inspector_property_edited)
scrollbar.get_h_scroll_bar().value_changed.connect(queue_redraw.unbind(1), CONNECT_DEFERRED)
scrollbar.get_v_scroll_bar().value_changed.connect(queue_redraw.unbind(1), CONNECT_DEFERRED)
func _draw():
var font := get_theme_font("font", "Label")
var font_size := get_theme_font_size("font", "Label")
var label_padding_left := 2.0
var newline_char := 10
for i in edited_cells.size():
if edit_cursor_positions[i] >= edited_cells_text[i].length():
continue
var char_size := Vector2(0, font.get_ascent(font_size))
var cursor_pos := Vector2(label_padding_left, 0)
var cell_text := edited_cells_text[i]
var cell : Control = edited_cells[i]
if cell is Label and cell.horizontal_alignment == HORIZONTAL_ALIGNMENT_RIGHT:
cursor_pos.x += cell.size.x - font.get_multiline_string_size(edited_cells[i].text, HORIZONTAL_ALIGNMENT_RIGHT, -1, font_size).x
for j in max(edit_cursor_positions[i], 0) + 1:
if j == 0: continue
if cell_text.unicode_at(j - 1) == newline_char:
cursor_pos.x = label_padding_left
cursor_pos.y += font.get_ascent(font_size)
continue
char_size = font.get_char_size(cell_text.unicode_at(j - 1), font_size)
cursor_pos.x += char_size.x
draw_rect(Rect2(cursor_pos + cell.global_position - global_position, Vector2(2, char_size.y)), Color(1, 1, 1, 0.5))
func initialize_editors(column_values, column_types, column_hints):
deselect_all_cells()
@ -55,7 +88,7 @@ func deselect_all_cells():
edited_cells.clear()
edited_cells_text.clear()
edit_cursor_positions.clear()
cells_selected.emit([])
_selection_changed()
func deselect_cell(cell : Control):
@ -68,7 +101,7 @@ func deselect_cell(cell : Control):
edited_cells_text.remove_at(idx)
edit_cursor_positions.remove_at(idx)
cells_selected.emit(edited_cells)
_selection_changed()
func select_cell(cell : Control):
@ -81,7 +114,18 @@ func select_cell(cell : Control):
# inspector_resource.resource_path = ""
editor_view.editor_plugin.get_editor_interface().edit_resource(inspector_resource)
cells_selected.emit(edited_cells)
_selection_changed()
func select_cells(cells : Array):
var last_selectible = null
for x in cells:
if can_select_cell(x):
_add_cell_to_selection(x)
last_selectible = x
if last_selectible != null:
select_cell(last_selectible)
func select_cells_to(cell : Control):
@ -108,7 +152,7 @@ func select_cells_to(cell : Control):
edited_cells_text.append(str(cur_cell.text))
edit_cursor_positions.append(cur_cell.text.length())
cells_selected.emit(edited_cells)
_selection_changed()
func rightclick_cells():
@ -118,16 +162,13 @@ func rightclick_cells():
func can_select_cell(cell : Control) -> bool:
if edited_cells.size() == 0:
return true
if !Input.is_key_pressed(KEY_CTRL):
return false
if (
get_cell_column(cell)
!= get_cell_column(edited_cells[0])
):
return false
return !cell in edited_cells
@ -148,6 +189,11 @@ func get_edited_rows() -> Array[int]:
return rows
func _selection_changed():
queue_redraw()
cells_selected.emit(edited_cells)
func _add_cell_to_selection(cell : Control):
var column_editor = column_editors[get_cell_column(cell)]
column_editor.set_selected(cell, true)

View File

@ -13,6 +13,7 @@ const whitespace_chars := [
41, # ")"
46, # "."
182, # "¶" Linefeed
10, # "\n" Actual Linefeed
967, # "●" Whitespace
]
@ -128,15 +129,22 @@ static func multi_input(input_char : String, values : Array, cursor_positions :
static func _step_cursor(text : String, start : int, step : int = 1, ctrl_pressed : bool = false) -> int:
var cur := start
if ctrl_pressed and is_character_whitespace(text, cur + step):
cur += step
while true:
start += step
if !ctrl_pressed or is_character_whitespace(text, start):
if start > text.length():
cur += step
if !ctrl_pressed or is_character_whitespace(text, cur):
if cur > text.length():
return text.length()
if start < 0:
if cur <= 0:
return 0
return start
if ctrl_pressed and step < 0:
return cur + 1
return cur
return 0