1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 09:09:47 +00:00

Allow multiple Grids (#1122)

* Allow upto 10 grids

* Fixed more stuff

* fixed a bug

* formatting

* removed some left over stuff

* linting

* formatting and a bugfix
This commit is contained in:
Variable 2024-11-25 18:57:13 +05:00 committed by GitHub
parent 6459151549
commit 6224d06428
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 351 additions and 134 deletions

View file

@ -337,55 +337,8 @@ var default_height := 64 ## Found in Preferences. The default height of startup
var default_fill_color := Color(0, 0, 0, 0)
## Found in Preferences. The distance to the guide or grig below which cursor snapping activates.
var snapping_distance := 32.0
## Found in Preferences. The grid type defined by [enum GridTypes] enum.
var grid_type := GridTypes.CARTESIAN:
set(value):
if value == grid_type:
return
grid_type = value
if is_instance_valid(canvas.grid):
canvas.grid.queue_redraw()
## Found in Preferences. The size of rectangular grid.
var grid_size := Vector2i(2, 2):
set(value):
if value == grid_size:
return
grid_size = value
if is_instance_valid(canvas.grid):
canvas.grid.queue_redraw()
## Found in Preferences. The size of isometric grid.
var isometric_grid_size := Vector2i(16, 8):
set(value):
if value == isometric_grid_size:
return
isometric_grid_size = value
if is_instance_valid(canvas.grid):
canvas.grid.queue_redraw()
## Found in Preferences. The grid offset from top-left corner of the canvas.
var grid_offset := Vector2i.ZERO:
set(value):
if value == grid_offset:
return
grid_offset = value
if is_instance_valid(canvas.grid):
canvas.grid.queue_redraw()
## Found in Preferences. If [code]true[/code], The grid draws over the area extended by
## tile-mode as well.
var grid_draw_over_tile_mode := false:
set(value):
if value == grid_draw_over_tile_mode:
return
grid_draw_over_tile_mode = value
if is_instance_valid(canvas.grid):
canvas.grid.queue_redraw()
## Found in Preferences. The color of grid.
var grid_color := Color.BLACK:
set(value):
if value == grid_color:
return
grid_color = value
if is_instance_valid(canvas.grid):
canvas.grid.queue_redraw()
## Contains dictionaries of individual grids.
var grids: Array[Grid] = []
## Found in Preferences. The minimum zoom after which pixel grid gets drawn if enabled.
var pixel_grid_show_at_zoom := 1500.0: # percentage
set(value):
@ -677,6 +630,62 @@ var cel_button_scene: PackedScene = load("res://src/UI/Timeline/CelButton.tscn")
@onready var error_dialog: AcceptDialog = control.find_child("ErrorDialog")
class Grid:
var grid_type := GridTypes.CARTESIAN:
set(value):
if value == grid_type:
return
grid_type = value
if is_instance_valid(Global.canvas.grid):
Global.canvas.grid.queue_redraw()
## Found in Preferences. The size of rectangular grid.
var grid_size := Vector2i(2, 2):
set(value):
if value == grid_size:
return
grid_size = value
if is_instance_valid(Global.canvas.grid):
Global.canvas.grid.queue_redraw()
## Found in Preferences. The size of isometric grid.
var isometric_grid_size := Vector2i(16, 8):
set(value):
if value == isometric_grid_size:
return
isometric_grid_size = value
if is_instance_valid(Global.canvas.grid):
Global.canvas.grid.queue_redraw()
## Found in Preferences. The grid offset from top-left corner of the canvas.
var grid_offset := Vector2i.ZERO:
set(value):
if value == grid_offset:
return
grid_offset = value
if is_instance_valid(Global.canvas.grid):
Global.canvas.grid.queue_redraw()
## Found in Preferences. If [code]true[/code], The grid draws over the area extended by
## tile-mode as well.
var grid_draw_over_tile_mode := false:
set(value):
if value == grid_draw_over_tile_mode:
return
grid_draw_over_tile_mode = value
if is_instance_valid(Global.canvas.grid):
Global.canvas.grid.queue_redraw()
## Found in Preferences. The color of grid.
var grid_color := Color.BLACK:
set(value):
if value == grid_color:
return
grid_color = value
if is_instance_valid(Global.canvas.grid):
Global.canvas.grid.queue_redraw()
func _init(properties := {}) -> void:
Global.grids.append(self)
for prop in properties.keys():
set(prop, properties[prop])
func _init() -> void:
# Load settings from the config file
config_cache.load(CONFIG_PATH)
@ -713,6 +722,8 @@ func _init() -> void:
func _ready() -> void:
# Initialize Grid
Grid.new() # gets auto added to grids array
_initialize_keychain()
default_width = config_cache.get_value("preferences", "default_width", default_width)
default_height = config_cache.get_value("preferences", "default_height", default_height)
@ -729,13 +740,23 @@ func _ready() -> void:
if get(pref) == null:
continue
var value = config_cache.get_value("preferences", pref)
set(pref, value)
if pref == "grids":
if value:
update_grids(value)
else:
set(pref, value)
if OS.is_sandboxed():
Global.use_native_file_dialogs = true
await get_tree().process_frame
project_switched.emit()
func update_grids(grids_data: Dictionary):
grids.clear()
for grid_idx in grids_data.size():
Grid.new(grids_data[grid_idx]) # gets auto added to grids array
func _initialize_keychain() -> void:
Keychain.config_file = config_cache
Keychain.actions = {

View file

@ -0,0 +1,163 @@
extends GridContainer
var grid_preferences: Array[GridPreference] = [
GridPreference.new("grid_type", "GridType", "selected", Global.GridTypes.CARTESIAN),
GridPreference.new("grid_size", "GridSizeValue", "value", Vector2i(2, 2)),
GridPreference.new("isometric_grid_size", "IsometricGridSizeValue", "value", Vector2i(16, 8)),
GridPreference.new("grid_offset", "GridOffsetValue", "value", Vector2i.ZERO),
GridPreference.new("grid_draw_over_tile_mode", "GridDrawOverTileMode", "button_pressed", false),
GridPreference.new("grid_color", "GridColor", "color", Color.BLACK),
]
var grid_selected: int = 0:
set(key):
grid_selected = key
for child: BaseButton in grids_select_container.get_children():
if child.get_index() == grid_selected:
child.self_modulate = Color.WHITE
else:
child.self_modulate = Color.DIM_GRAY
var grids: Dictionary = Global.config_cache.get_value(
"preferences", "grids", {0: create_default_properties()}
)
if grids.has(key):
update_pref_ui(grids[key])
@onready var grids_select_container: HFlowContainer = $GridsSelectContainer
class GridPreference:
var prop_name: String
var node_path: String
var value_type: String
var default_value
func _init(
_prop_name: String,
_node_path: String,
_value_type: String,
_default_value = null,
_require_restart := false
) -> void:
prop_name = _prop_name
node_path = _node_path
value_type = _value_type
if _default_value != null:
default_value = _default_value
func _ready() -> void:
var grids = Global.config_cache.get_value(
"preferences", "grids", {0: create_default_properties()}
)
Global.config_cache.set_value("preferences", "grids", grids)
$GridsCount.value = grids.size()
if grids.size() == 1:
add_remove_select_button(0)
for pref in grid_preferences:
if not has_node(pref.node_path):
continue
var node := get_node(pref.node_path)
var restore_default_button := RestoreDefaultButton.new()
restore_default_button.pressed.connect(
_on_grid_pref_value_changed.bind(pref.default_value, pref, restore_default_button)
)
restore_default_button.setting_name = pref.prop_name
restore_default_button.value_type = pref.value_type
restore_default_button.default_value = pref.default_value
restore_default_button.node = node
var node_position := node.get_index()
node.get_parent().add_child(restore_default_button)
node.get_parent().move_child(restore_default_button, node_position)
match pref.value_type:
"button_pressed":
node.toggled.connect(_on_grid_pref_value_changed.bind(pref, restore_default_button))
"value":
node.value_changed.connect(
_on_grid_pref_value_changed.bind(pref, restore_default_button)
)
"color":
node.get_picker().presets_visible = false
node.color_changed.connect(
_on_grid_pref_value_changed.bind(pref, restore_default_button)
)
"selected":
node.item_selected.connect(
_on_grid_pref_value_changed.bind(pref, restore_default_button)
)
grid_selected = 0
func _on_grid_pref_value_changed(value, pref: GridPreference, button: RestoreDefaultButton) -> void:
var grids: Dictionary = Global.config_cache.get_value(
"preferences", "grids", {0: create_default_properties()}
)
if grids.has(grid_selected): # Failsafe (Always true)
var grid_info: Dictionary = grids[grid_selected]
var prop := pref.prop_name
grid_info[prop] = value
grids[grid_selected] = grid_info
Global.update_grids(grids)
var default_value = pref.default_value
var disable: bool = Global.grids[grid_selected].get(prop) == default_value
if typeof(value) == TYPE_COLOR:
disable = value.is_equal_approx(default_value)
disable_restore_default_button(button, disable)
Global.config_cache.set_value("preferences", "grids", grids)
func _on_grids_count_value_changed(value: float) -> void:
var grid_idx = int(value - 1)
var grids: Dictionary = Global.config_cache.get_value(
"preferences", "grids", {0: create_default_properties()}
)
if grid_idx >= grids_select_container.get_child_count():
for key in range(grids_select_container.get_child_count(), grid_idx + 1):
if not grids.has(key):
grids[key] = create_default_properties()
add_remove_select_button(key)
else:
for key: int in range(grid_idx + 1, grids.size()):
grids.erase(key)
add_remove_select_button(key, true)
Global.update_grids(grids)
Global.config_cache.set_value("preferences", "grids", grids)
func create_default_properties() -> Dictionary:
var grid_info = {}
for pref in grid_preferences:
grid_info[pref.prop_name] = pref.default_value
return grid_info
func disable_restore_default_button(button: RestoreDefaultButton, disable: bool) -> void:
button.disabled = disable
if disable:
button.mouse_default_cursor_shape = Control.CURSOR_ARROW
button.tooltip_text = ""
else:
button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
button.tooltip_text = "Restore default value"
func add_remove_select_button(grid_idx: int, remove := false):
if not remove:
var select_button = Button.new()
select_button.text = str(grid_idx)
grids_select_container.add_child(select_button)
select_button.pressed.connect(func(): grid_selected = grid_idx)
else:
if grid_idx < grids_select_container.get_child_count():
grids_select_container.get_child(grid_idx).queue_free()
grid_selected = min(grid_selected, grid_idx - 1)
func update_pref_ui(grid_data: Dictionary):
for pref in grid_preferences:
var key = pref.prop_name
if grid_data.has(key):
var node := get_node(pref.node_path)
node.set(pref.value_type, grid_data[key])

View file

@ -94,21 +94,6 @@ var preferences: Array[Preference] = [
Preference.new("smooth_zoom", "Canvas/ZoomOptions/SmoothZoom", "button_pressed", true),
Preference.new("integer_zoom", "Canvas/ZoomOptions/IntegerZoom", "button_pressed", false),
Preference.new("snapping_distance", "Canvas/SnappingOptions/DistanceValue", "value", 32.0),
Preference.new(
"grid_type", "Canvas/GridOptions/GridType", "selected", Global.GridTypes.CARTESIAN
),
Preference.new("grid_size", "Canvas/GridOptions/GridSizeValue", "value", Vector2i(2, 2)),
Preference.new(
"isometric_grid_size", "Canvas/GridOptions/IsometricGridSizeValue", "value", Vector2i(16, 8)
),
Preference.new("grid_offset", "Canvas/GridOptions/GridOffsetValue", "value", Vector2i.ZERO),
Preference.new(
"grid_draw_over_tile_mode",
"Canvas/GridOptions/GridDrawOverTileMode",
"button_pressed",
false
),
Preference.new("grid_color", "Canvas/GridOptions/GridColor", "color", Color.BLACK),
Preference.new(
"pixel_grid_show_at_zoom", "Canvas/PixelGridOptions/ShowAtZoom", "value", 1500.0
),

View file

@ -1,8 +1,10 @@
[gd_scene load_steps=9 format=3 uid="uid://b3hkjj3s6pe4x"]
[gd_scene load_steps=11 format=3 uid="uid://b3hkjj3s6pe4x"]
[ext_resource type="Script" path="res://src/Preferences/PreferencesDialog.gd" id="1"]
[ext_resource type="PackedScene" uid="uid://bq7ibhm0txl5p" path="res://addons/keychain/ShortcutEdit.tscn" id="3"]
[ext_resource type="Script" path="res://src/Preferences/ThemesPreferences.gd" id="3_nvl8k"]
[ext_resource type="Script" path="res://src/Preferences/GridPreferences.gd" id="4_76iff"]
[ext_resource type="PackedScene" uid="uid://yjhp0ssng2mp" path="res://src/UI/Nodes/ValueSlider.tscn" id="5_rlmsh"]
[ext_resource type="PackedScene" path="res://src/UI/Nodes/ValueSliderV2.tscn" id="7"]
[ext_resource type="Script" path="res://src/Preferences/ExtensionsPreferences.gd" id="7_8ume5"]
[ext_resource type="Script" path="res://src/UI/Nodes/ValueSlider.gd" id="8"]
@ -482,6 +484,30 @@ layout_mode = 2
theme_override_constants/h_separation = 4
theme_override_constants/v_separation = 4
columns = 3
script = ExtResource("4_76iff")
[node name="GridsCountLabel" type="Label" parent="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Canvas/GridOptions"]
layout_mode = 2
text = "Grids Visible:"
[node name="Spacer" type="Control" parent="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Canvas/GridOptions"]
layout_mode = 2
[node name="GridsCount" parent="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Canvas/GridOptions" instance=ExtResource("5_rlmsh")]
layout_mode = 2
min_value = 1.0
max_value = 10.0
value = 1.0
[node name="GridsSelectLabel" type="Label" parent="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Canvas/GridOptions"]
layout_mode = 2
text = "Editing Grid:"
[node name="Spacer2" type="Control" parent="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Canvas/GridOptions"]
layout_mode = 2
[node name="GridsSelectContainer" type="HFlowContainer" parent="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Canvas/GridOptions"]
layout_mode = 2
[node name="GridTypeLabel" type="Label" parent="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Canvas/GridOptions"]
layout_mode = 2
@ -1478,6 +1504,7 @@ dialog_text = "Are you sure you want to reset the selected options? There will b
[connection signal="pressed" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Language/System Language" to="." method="_on_language_pressed" binds= [1]]
[connection signal="pressed" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Interface/InterfaceOptions/ShrinkContainer/ShrinkApplyButton" to="." method="_on_shrink_apply_button_pressed"]
[connection signal="pressed" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Interface/InterfaceOptions/FontSizeContainer/FontSizeApplyButton" to="." method="_on_font_size_apply_button_pressed"]
[connection signal="value_changed" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Canvas/GridOptions/GridsCount" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Canvas/GridOptions" method="_on_grids_count_value_changed"]
[connection signal="pressed" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions/ExtensionsHeader/Explore" to="Store" method="_on_explore_pressed"]
[connection signal="empty_clicked" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions/InstalledExtensions" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions" method="_on_InstalledExtensions_empty_clicked"]
[connection signal="item_selected" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions/InstalledExtensions" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions" method="_on_InstalledExtensions_item_selected"]

View file

@ -159,16 +159,17 @@ func draw_move(pos: Vector2i) -> void:
else:
pos.x = _start_pos.x
if Input.is_action_pressed("transform_snap_grid"):
_offset = _offset.snapped(Global.grid_size)
_offset = _offset.snapped(Global.grids[0].grid_size)
var prev_pos: Vector2i = selection_node.big_bounding_rectangle.position
selection_node.big_bounding_rectangle.position = prev_pos.snapped(Global.grid_size)
selection_node.big_bounding_rectangle.position = prev_pos.snapped(Global.grids[0].grid_size)
selection_node.marching_ants_outline.offset += Vector2(
selection_node.big_bounding_rectangle.position - prev_pos
)
pos = pos.snapped(Global.grid_size)
var grid_offset := Global.grid_offset
pos = pos.snapped(Global.grids[0].grid_size)
var grid_offset := Global.grids[0].grid_offset
grid_offset = Vector2i(
fmod(grid_offset.x, Global.grid_size.x), fmod(grid_offset.y, Global.grid_size.y)
fmod(grid_offset.x, Global.grids[0].grid_size.x),
fmod(grid_offset.y, Global.grids[0].grid_size.y)
)
pos += grid_offset

View file

@ -129,19 +129,20 @@ func draw_preview() -> void:
func snap_position(pos: Vector2) -> Vector2:
var snapping_distance := Global.snapping_distance / Global.camera.zoom.x
if Global.snap_to_rectangular_grid_boundary:
var grid_pos := pos.snapped(Global.grid_size)
grid_pos += Vector2(Global.grid_offset)
var grid_pos := pos.snapped(Global.grids[0].grid_size)
grid_pos += Vector2(Global.grids[0].grid_offset)
# keeping grid_pos as is would have been fine but this adds extra accuracy as to
# which snap point (from the list below) is closest to mouse and occupy THAT point
var t_l := grid_pos + Vector2(-Global.grid_size.x, -Global.grid_size.y)
var t_c := grid_pos + Vector2(0, -Global.grid_size.y) # t_c is for "top centre" and so on
var t_r := grid_pos + Vector2(Global.grid_size.x, -Global.grid_size.y)
var m_l := grid_pos + Vector2(-Global.grid_size.x, 0)
# t_l is for "top left" and so on
var t_l := grid_pos + Vector2(-Global.grids[0].grid_size.x, -Global.grids[0].grid_size.y)
var t_c := grid_pos + Vector2(0, -Global.grids[0].grid_size.y)
var t_r := grid_pos + Vector2(Global.grids[0].grid_size.x, -Global.grids[0].grid_size.y)
var m_l := grid_pos + Vector2(-Global.grids[0].grid_size.x, 0)
var m_c := grid_pos
var m_r := grid_pos + Vector2(Global.grid_size.x, 0)
var b_l := grid_pos + Vector2(-Global.grid_size.x, Global.grid_size.y)
var b_c := grid_pos + Vector2(0, Global.grid_size.y)
var b_r := grid_pos + Vector2(Global.grid_size)
var m_r := grid_pos + Vector2(Global.grids[0].grid_size.x, 0)
var b_l := grid_pos + Vector2(-Global.grids[0].grid_size.x, Global.grids[0].grid_size.y)
var b_c := grid_pos + Vector2(0, Global.grids[0].grid_size.y)
var b_r := grid_pos + Vector2(Global.grids[0].grid_size)
var vec_arr: PackedVector2Array = [t_l, t_c, t_r, m_l, m_c, m_r, b_l, b_c, b_r]
for vec in vec_arr:
if vec.distance_to(pos) < grid_pos.distance_to(pos):
@ -152,19 +153,22 @@ func snap_position(pos: Vector2) -> Vector2:
pos = grid_point.floor()
if Global.snap_to_rectangular_grid_center:
var grid_center := pos.snapped(Global.grid_size) + Vector2(Global.grid_size / 2)
grid_center += Vector2(Global.grid_offset)
var grid_center := (
pos.snapped(Global.grids[0].grid_size) + Vector2(Global.grids[0].grid_size / 2)
)
grid_center += Vector2(Global.grids[0].grid_offset)
# keeping grid_center as is would have been fine but this adds extra accuracy as to
# which snap point (from the list below) is closest to mouse and occupy THAT point
var t_l := grid_center + Vector2(-Global.grid_size.x, -Global.grid_size.y)
var t_c := grid_center + Vector2(0, -Global.grid_size.y) # t_c is for "top centre" and so on
var t_r := grid_center + Vector2(Global.grid_size.x, -Global.grid_size.y)
var m_l := grid_center + Vector2(-Global.grid_size.x, 0)
# t_l is for "top left" and so on
var t_l := grid_center + Vector2(-Global.grids[0].grid_size.x, -Global.grids[0].grid_size.y)
var t_c := grid_center + Vector2(0, -Global.grids[0].grid_size.y)
var t_r := grid_center + Vector2(Global.grids[0].grid_size.x, -Global.grids[0].grid_size.y)
var m_l := grid_center + Vector2(-Global.grids[0].grid_size.x, 0)
var m_c := grid_center
var m_r := grid_center + Vector2(Global.grid_size.x, 0)
var b_l := grid_center + Vector2(-Global.grid_size.x, Global.grid_size.y)
var b_c := grid_center + Vector2(0, Global.grid_size.y)
var b_r := grid_center + Vector2(Global.grid_size)
var m_r := grid_center + Vector2(Global.grids[0].grid_size.x, 0)
var b_l := grid_center + Vector2(-Global.grids[0].grid_size.x, Global.grids[0].grid_size.y)
var b_c := grid_center + Vector2(0, Global.grids[0].grid_size.y)
var b_r := grid_center + Vector2(Global.grids[0].grid_size)
var vec_arr := [t_l, t_c, t_r, m_l, m_c, m_r, b_l, b_c, b_r]
for vec in vec_arr:
if vec.distance_to(pos) < grid_center.distance_to(pos):

View file

@ -16,17 +16,17 @@ func _input(event: InputEvent) -> void:
return
if event.is_action_pressed("transform_snap_grid"):
_snap_to_grid = true
_offset = _offset.snapped(Global.grid_size)
_offset = _offset.snapped(Global.grids[0].grid_size)
if Global.current_project.has_selection and selection_node.is_moving_content:
var prev_pos: Vector2i = selection_node.big_bounding_rectangle.position
selection_node.big_bounding_rectangle.position = Vector2i(
prev_pos.snapped(Global.grid_size)
prev_pos.snapped(Global.grids[0].grid_size)
)
# The first time transform_snap_grid is enabled then _snap_position() is not called
# and the selection had wrong offset, so do selection offsetting here
var grid_offset := Vector2i(
fmod(Global.grid_offset.x, Global.grid_size.x),
fmod(Global.grid_offset.y, Global.grid_size.y)
fmod(Global.grids[0].grid_offset.x, Global.grids[0].grid_size.x),
fmod(Global.grids[0].grid_offset.y, Global.grids[0].grid_size.y)
)
selection_node.big_bounding_rectangle.position += grid_offset
selection_node.marching_ants_outline.offset += Vector2(
@ -110,16 +110,18 @@ func _snap_position(pos: Vector2) -> Vector2:
else:
pos.x = _start_pos.x
if _snap_to_grid: # Snap to grid
pos = pos.snapped(Global.grid_size)
pos = pos.snapped(Global.grids[0].grid_size)
# The part below only corrects the offset for situations when there is no selection
# Offsets when there is selection is controlled in _input() function
if !Global.current_project.has_selection:
var move_offset := Vector2.ZERO
move_offset.x = (
_start_pos.x - (_start_pos.x / Global.grid_size.x) * Global.grid_size.x
_start_pos.x
- (_start_pos.x / Global.grids[0].grid_size.x) * Global.grids[0].grid_size.x
)
move_offset.y = (
_start_pos.y - (_start_pos.y / Global.grid_size.y) * Global.grid_size.y
_start_pos.y
- (_start_pos.y / Global.grids[0].grid_size.y) * Global.grids[0].grid_size.y
)
pos += move_offset

View file

@ -1,5 +1,8 @@
extends Node2D
var unique_rect_lines := PackedVector2Array()
var unique_iso_lines := PackedVector2Array()
func _ready() -> void:
Global.project_switched.connect(queue_redraw)
@ -10,54 +13,60 @@ func _draw() -> void:
return
var target_rect: Rect2i
if Global.grid_draw_over_tile_mode:
target_rect = Global.current_project.tiles.get_bounding_rect()
else:
target_rect = Rect2i(Vector2i.ZERO, Global.current_project.size)
if not target_rect.has_area():
return
unique_rect_lines.clear()
unique_iso_lines.clear()
for grid_idx in range(Global.grids.size() - 1, -1, -1):
if Global.grids[grid_idx].grid_draw_over_tile_mode:
target_rect = Global.current_project.tiles.get_bounding_rect()
else:
target_rect = Rect2i(Vector2i.ZERO, Global.current_project.size)
if not target_rect.has_area():
return
var grid_type := Global.grid_type
if grid_type == Global.GridTypes.CARTESIAN || grid_type == Global.GridTypes.ALL:
_draw_cartesian_grid(target_rect)
var grid_type := Global.grids[grid_idx].grid_type
if grid_type == Global.GridTypes.CARTESIAN || grid_type == Global.GridTypes.ALL:
_draw_cartesian_grid(grid_idx, target_rect)
if grid_type == Global.GridTypes.ISOMETRIC || grid_type == Global.GridTypes.ALL:
_draw_isometric_grid(target_rect)
if grid_type == Global.GridTypes.ISOMETRIC || grid_type == Global.GridTypes.ALL:
_draw_isometric_grid(grid_idx, target_rect)
func _draw_cartesian_grid(target_rect: Rect2i) -> void:
func _draw_cartesian_grid(grid_index: int, target_rect: Rect2i) -> void:
var grid = Global.grids[grid_index]
var grid_multiline_points := PackedVector2Array()
var x: float = (
target_rect.position.x
+ fposmod(Global.grid_offset.x - target_rect.position.x, Global.grid_size.x)
+ fposmod(grid.grid_offset.x - target_rect.position.x, grid.grid_size.x)
)
while x <= target_rect.end.x:
grid_multiline_points.push_back(Vector2(x, target_rect.position.y))
grid_multiline_points.push_back(Vector2(x, target_rect.end.y))
x += Global.grid_size.x
if not Vector2(x, target_rect.position.y) in unique_rect_lines:
grid_multiline_points.push_back(Vector2(x, target_rect.position.y))
grid_multiline_points.push_back(Vector2(x, target_rect.end.y))
x += grid.grid_size.x
var y: float = (
target_rect.position.y
+ fposmod(Global.grid_offset.y - target_rect.position.y, Global.grid_size.y)
+ fposmod(grid.grid_offset.y - target_rect.position.y, grid.grid_size.y)
)
while y <= target_rect.end.y:
grid_multiline_points.push_back(Vector2(target_rect.position.x, y))
grid_multiline_points.push_back(Vector2(target_rect.end.x, y))
y += Global.grid_size.y
if not Vector2(target_rect.position.x, y) in unique_rect_lines:
grid_multiline_points.push_back(Vector2(target_rect.position.x, y))
grid_multiline_points.push_back(Vector2(target_rect.end.x, y))
y += grid.grid_size.y
unique_rect_lines.append_array(grid_multiline_points)
if not grid_multiline_points.is_empty():
draw_multiline(grid_multiline_points, Global.grid_color)
draw_multiline(grid_multiline_points, grid.grid_color)
func _draw_isometric_grid(target_rect: Rect2i) -> void:
func _draw_isometric_grid(grid_index: int, target_rect: Rect2i) -> void:
var grid = Global.grids[grid_index]
var grid_multiline_points := PackedVector2Array()
var cell_size: Vector2 = Global.isometric_grid_size
var cell_size: Vector2 = grid.isometric_grid_size
var max_cell_count: Vector2 = Vector2(target_rect.size) / cell_size
var origin_offset: Vector2 = Vector2(Global.grid_offset - target_rect.position).posmodv(
cell_size
)
var origin_offset: Vector2 = Vector2(grid.grid_offset - target_rect.position).posmodv(cell_size)
# lines ↗↗↗ (from bottom-left to top-right)
var per_cell_offset: Vector2 = cell_size * Vector2(1, -1)
@ -70,8 +79,9 @@ func _draw_isometric_grid(target_rect: Rect2i) -> void:
var start: Vector2 = Vector2(target_rect.position) + Vector2(0, y)
var cells_to_rect_bounds: float = minf(max_cell_count.x, y / cell_size.y)
var end := start + cells_to_rect_bounds * per_cell_offset
grid_multiline_points.push_back(start)
grid_multiline_points.push_back(end)
if not start in unique_iso_lines:
grid_multiline_points.push_back(start)
grid_multiline_points.push_back(end)
y += cell_size.y
# lines ↗↗↗ starting from the rect's bottom side (left to right):
@ -80,8 +90,9 @@ func _draw_isometric_grid(target_rect: Rect2i) -> void:
var start: Vector2 = Vector2(target_rect.position) + Vector2(x, target_rect.size.y)
var cells_to_rect_bounds: float = minf(max_cell_count.y, max_cell_count.x - x / cell_size.x)
var end: Vector2 = start + cells_to_rect_bounds * per_cell_offset
grid_multiline_points.push_back(start)
grid_multiline_points.push_back(end)
if not start in unique_iso_lines:
grid_multiline_points.push_back(start)
grid_multiline_points.push_back(end)
x += cell_size.x
# lines ↘↘↘ (from top-left to bottom-right)
@ -93,8 +104,9 @@ func _draw_isometric_grid(target_rect: Rect2i) -> void:
var start: Vector2 = Vector2(target_rect.position) + Vector2(0, y)
var cells_to_rect_bounds: float = minf(max_cell_count.x, max_cell_count.y - y / cell_size.y)
var end: Vector2 = start + cells_to_rect_bounds * per_cell_offset
grid_multiline_points.push_back(start)
grid_multiline_points.push_back(end)
if not start in unique_iso_lines:
grid_multiline_points.push_back(start)
grid_multiline_points.push_back(end)
y += cell_size.y
# lines ↘↘↘ starting from the rect's top side (left to right):
@ -103,9 +115,11 @@ func _draw_isometric_grid(target_rect: Rect2i) -> void:
var start: Vector2 = Vector2(target_rect.position) + Vector2(x, 0)
var cells_to_rect_bounds: float = minf(max_cell_count.y, max_cell_count.x - x / cell_size.x)
var end: Vector2 = start + cells_to_rect_bounds * per_cell_offset
grid_multiline_points.push_back(start)
grid_multiline_points.push_back(end)
if not start in unique_iso_lines:
grid_multiline_points.push_back(start)
grid_multiline_points.push_back(end)
x += cell_size.x
grid_multiline_points.append_array(grid_multiline_points)
if not grid_multiline_points.is_empty():
draw_multiline(grid_multiline_points, Global.grid_color)
draw_multiline(grid_multiline_points, grid.grid_color)

View file

@ -214,7 +214,7 @@ func _move_with_arrow_keys(event: InputEvent) -> void:
if _is_action_direction(event) and arrow_key_move:
var step := Vector2.ONE
if Input.is_key_pressed(KEY_CTRL):
step = Global.grid_size
step = Global.grids[0].grid_size
var input := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
var move := input.rotated(snappedf(Global.camera.rotation, PI / 2))
# These checks are needed to fix a bug where the selection got stuck