hide grid cells by default, show during drag; fix frozen-on-gap with cell-bounds check and drop-to-source fallback
This commit is contained in:
parent
6198fd556f
commit
92110cfee7
1 changed files with 88 additions and 51 deletions
|
|
@ -25,8 +25,8 @@ var _drag_mouse_offset: Vector2 = Vector2.ZERO
|
|||
var _hover_col: int = -1
|
||||
var _hover_row: int = -1
|
||||
|
||||
# Styles cached per-cell so we can modify them during drag
|
||||
var _cell_styles: Dictionary = {} # cell -> StyleBoxFlat
|
||||
# Visible cell styles cached per-cell so we can modify them during drag
|
||||
var _cell_styles: Dictionary = {} # "col,row" -> StyleBoxFlat
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -127,10 +127,13 @@ func _begin_drag(mouse_pos: Vector2) -> void:
|
|||
_drag_source_col = col
|
||||
_drag_source_row = row
|
||||
|
||||
# Show grid cells so the user can see drop zones
|
||||
_show_cells(true)
|
||||
|
||||
# Calculate where the module sits in grid coordinates before reparenting.
|
||||
# module.position is relative to the cell; cell.position is relative to us (the grid).
|
||||
var cell: PanelContainer = _cells[row][col]
|
||||
var module_origin_in_grid := cell.position + module.position
|
||||
var cell_ref: PanelContainer = _cells[row][col]
|
||||
var module_origin_in_grid := cell_ref.position + module.position
|
||||
_drag_mouse_offset = mouse_pos - module_origin_in_grid
|
||||
|
||||
_drag_module = _take_module_from_cell(col, row)
|
||||
|
|
@ -168,26 +171,30 @@ func _end_drag(mouse_pos: Vector2) -> void:
|
|||
return
|
||||
|
||||
_clear_hover()
|
||||
_show_cells(false)
|
||||
_drag_module.modulate = Color(1, 1, 1, 1)
|
||||
|
||||
var cell_pos := _cell_at_position(mouse_pos)
|
||||
var target_col := cell_pos.x
|
||||
var target_row := cell_pos.y
|
||||
|
||||
# Dropped on the same cell — just put it back
|
||||
if target_col == _drag_source_col and target_row == _drag_source_row:
|
||||
_place_module_in_cell(_drag_module, target_col, target_row)
|
||||
module_placed.emit(_drag_module, target_col, target_row)
|
||||
# Check whether the mouse is actually inside the cell bounds (not in the gap)
|
||||
var on_cell := false
|
||||
if _is_valid_cell(target_col, target_row):
|
||||
var cell_ref: PanelContainer = _cells[target_row][target_col]
|
||||
on_cell = Rect2(Vector2.ZERO, cell_ref.size).has_point(mouse_pos - cell_ref.position)
|
||||
|
||||
if not on_cell or not _is_valid_cell(target_col, target_row):
|
||||
_drop_to_source()
|
||||
_finish_drag()
|
||||
return
|
||||
|
||||
# Remove the module from its temporary home (the grid itself)
|
||||
# Remove from its temporary parent (the grid)
|
||||
_drag_module.get_parent().remove_child(_drag_module)
|
||||
|
||||
if _is_valid_cell(target_col, target_row):
|
||||
var existing := _get_cell_module(target_col, target_row)
|
||||
if existing != null:
|
||||
# SWAP: put existing module in source cell, drag module in target
|
||||
# SWAP: put existing in source, dragged module in target
|
||||
existing.get_parent().remove_child(existing)
|
||||
var was_source_valid := _is_valid_cell(_drag_source_col, _drag_source_row)
|
||||
if was_source_valid:
|
||||
|
|
@ -199,19 +206,23 @@ func _end_drag(mouse_pos: Vector2) -> void:
|
|||
_place_module_in_cell(_drag_module, target_col, target_row)
|
||||
module_placed.emit(_drag_module, target_col, target_row)
|
||||
else:
|
||||
# Place in the empty cell directly — you get full control of positioning
|
||||
# Place in the empty cell
|
||||
_place_module_in_cell(_drag_module, target_col, target_row)
|
||||
module_placed.emit(_drag_module, target_col, target_row)
|
||||
else:
|
||||
# Dropped outside the grid — return to source if still valid
|
||||
|
||||
_finish_drag()
|
||||
|
||||
|
||||
func _drop_to_source() -> void:
|
||||
if _drag_module == null:
|
||||
return
|
||||
if _is_valid_cell(_drag_source_col, _drag_source_row):
|
||||
_drag_module.get_parent().remove_child(_drag_module)
|
||||
_place_module_in_cell(_drag_module, _drag_source_col, _drag_source_row)
|
||||
module_placed.emit(_drag_module, _drag_source_col, _drag_source_row)
|
||||
else:
|
||||
_drag_module.queue_free()
|
||||
|
||||
_finish_drag()
|
||||
|
||||
|
||||
func _finish_drag() -> void:
|
||||
_drag_module = null
|
||||
|
|
@ -235,16 +246,13 @@ func _highlight_cell(col: int, row: int, highlighted: bool) -> void:
|
|||
if not _is_valid_cell(col, row):
|
||||
return
|
||||
var cell: PanelContainer = _cells[row][col]
|
||||
var style_key: String = "%d,%d" % [col, row]
|
||||
var style: StyleBoxFlat = _cell_styles.get(style_key)
|
||||
var style: StyleBoxFlat = cell.get_meta("visible_style")
|
||||
if style == null:
|
||||
return
|
||||
if highlighted:
|
||||
style.border_color = Color(0.5, 0.6, 1.0, 1.0)
|
||||
else:
|
||||
style.border_color = Color(0.25, 0.25, 0.35, 1.0)
|
||||
cell.add_theme_stylebox_override("panel", style)
|
||||
cell.add_theme_stylebox_override("panel_focused", style)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
|
@ -409,11 +417,12 @@ func _cancel_drag() -> void:
|
|||
_place_module_in_cell(_drag_module, _drag_source_col, _drag_source_row)
|
||||
else:
|
||||
_drag_module.queue_free()
|
||||
_show_cells(false)
|
||||
_clear_hover()
|
||||
_drag_module = null
|
||||
_is_dragging = false
|
||||
_drag_source_col = -1
|
||||
_drag_source_row = -1
|
||||
_clear_hover()
|
||||
|
||||
|
||||
func _build_cells() -> void:
|
||||
|
|
@ -430,20 +439,48 @@ func _build_cells() -> void:
|
|||
|
||||
|
||||
func _style_cell(cell: PanelContainer, col: int, row: int) -> void:
|
||||
var style := StyleBoxFlat.new()
|
||||
style.bg_color = Color(0.14, 0.14, 0.18, 1.0)
|
||||
style.border_width_left = 1
|
||||
style.border_width_top = 1
|
||||
style.border_width_right = 1
|
||||
style.border_width_bottom = 1
|
||||
style.border_color = Color(0.25, 0.25, 0.35, 1.0)
|
||||
style.corner_radius_top_left = 6
|
||||
style.corner_radius_top_right = 6
|
||||
style.corner_radius_bottom_right = 6
|
||||
style.corner_radius_bottom_left = 6
|
||||
# Hidden style — used when not dragging
|
||||
var hidden := StyleBoxFlat.new()
|
||||
hidden.bg_color = Color.TRANSPARENT
|
||||
hidden.border_width_left = 1
|
||||
hidden.border_width_top = 1
|
||||
hidden.border_width_right = 1
|
||||
hidden.border_width_bottom = 1
|
||||
hidden.border_color = Color.TRANSPARENT
|
||||
hidden.corner_radius_top_left = 6
|
||||
hidden.corner_radius_top_right = 6
|
||||
hidden.corner_radius_bottom_right = 6
|
||||
hidden.corner_radius_bottom_left = 6
|
||||
|
||||
# Visible style — used during drag, may be modified by highlights
|
||||
var visible := StyleBoxFlat.new()
|
||||
visible.bg_color = Color(0.14, 0.14, 0.18, 1.0)
|
||||
visible.border_width_left = 1
|
||||
visible.border_width_top = 1
|
||||
visible.border_width_right = 1
|
||||
visible.border_width_bottom = 1
|
||||
visible.border_color = Color(0.25, 0.25, 0.35, 1.0)
|
||||
visible.corner_radius_top_left = 6
|
||||
visible.corner_radius_top_right = 6
|
||||
visible.corner_radius_bottom_right = 6
|
||||
visible.corner_radius_bottom_left = 6
|
||||
|
||||
cell.add_theme_stylebox_override("panel", hidden)
|
||||
cell.add_theme_stylebox_override("panel_focused", hidden)
|
||||
cell.set_meta("hidden_style", hidden)
|
||||
cell.set_meta("visible_style", visible)
|
||||
_cell_styles["%d,%d" % [col, row]] = visible
|
||||
|
||||
|
||||
func _show_cells(show: bool) -> void:
|
||||
for row_idx in range(_cells.size()):
|
||||
for col_idx in range(_cells[row_idx].size()):
|
||||
var cell: PanelContainer = _cells[row_idx][col_idx]
|
||||
if not is_instance_valid(cell):
|
||||
continue
|
||||
var style: StyleBoxFlat = cell.get_meta("visible_style") if show else cell.get_meta("hidden_style")
|
||||
cell.add_theme_stylebox_override("panel", style)
|
||||
cell.add_theme_stylebox_override("panel_focused", style)
|
||||
_cell_styles["%d,%d" % [col, row]] = style
|
||||
|
||||
|
||||
func _teardown_cells() -> void:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue