mirror of
https://github.com/Relintai/godot-resources-as-sheets-plugin.git
synced 2025-04-08 17:41:50 +02:00
Huge text cursor and cell selection improvements
This commit is contained in:
parent
5047462af5
commit
6a05d7827c
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user