mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-30 23:19:49 +00:00
Added the Perspective editor (#806)
* Added Perspective Editor * removed unintended changes * Removed unintended changes * removed un-intended changes * Delete Axes.tscn * Delete Axis.gd * Removed MouseGuides from editor I will add them separately * Added MouseGuides * Some changes * Fixed some things * added mouse guide * make MouseGuides remember last setting * don't move if dialog is open * Dont move tracker guides if dialog is open * UI improvement to editor * Update VanishingPoint.gd * UI Improvement * Minor Color Improvements * fixed a bug This was causing a crash * Some UI Changes * Improve UI some more * fix typo * Added Undo/Redo and improved UI * Formatting * formatting * formatting * formatting * Fix Definition out of order * Fix Definition out of order * formatting * formatting * fix Duplicate error * Fix some things * Some UI Changes * Some code refinement * Removed un-needed lines * Some code refinement * Some more UI Changes * Changes, Changes and Changes * Delete LineButton.gd * Delete LineButton.tscn * Delete PerspectiveEditor.gd * Delete PerspectiveEditor.tscn * Delete PointCollapseContainer.gd * Delete PerspectiveLine.tscn * Delete PerspectiveLine.gd * Changed boundary separators to ColorRects * make the guide update more frequently * make default color have full alpha * Dim the boundaries based on luminance * typo * Formatting * Formatting * formatting i forgot to do * Delete VanishingPoint.gd * Delete VanishingPoint.tscn * Fixed rouge collapsible container --------- Co-authored-by: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com>
This commit is contained in:
parent
c6d6c6184c
commit
7307743f83
|
@ -159,6 +159,11 @@ _global_script_classes=[ {
|
|||
"language": "GDScript",
|
||||
"path": "res://src/UI/Buttons/PatternsPopup.gd"
|
||||
}, {
|
||||
"base": "Line2D",
|
||||
"class": "PerspectiveLine",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/UI/PerspectiveEditor/PerspectiveLine.gd"
|
||||
}, {
|
||||
"base": "BaseCel",
|
||||
"class": "PixelCel",
|
||||
"language": "GDScript",
|
||||
|
@ -250,6 +255,7 @@ _global_script_class_icons={
|
|||
"PalettePanel": "",
|
||||
"PaletteSwatch": "",
|
||||
"Patterns": "",
|
||||
"PerspectiveLine": "",
|
||||
"PixelCel": "",
|
||||
"PixelLayer": "",
|
||||
"Project": "",
|
||||
|
|
|
@ -20,6 +20,7 @@ enum ViewMenu {
|
|||
SHOW_PIXEL_GRID,
|
||||
SHOW_RULERS,
|
||||
SHOW_GUIDES,
|
||||
SHOW_MOUSE_GUIDES,
|
||||
SNAP_TO,
|
||||
}
|
||||
enum WindowMenu { WINDOW_OPACITY, PANELS, LAYOUTS, MOVABLE_PANELS, ZEN_MODE, FULLSCREEN_MODE }
|
||||
|
@ -138,6 +139,7 @@ var draw_grid := false
|
|||
var draw_pixel_grid := false
|
||||
var show_rulers := true
|
||||
var show_guides := true
|
||||
var show_mouse_guides := false
|
||||
var snapping_distance := 10.0
|
||||
var snap_to_rectangular_grid := false
|
||||
var snap_to_guides := false
|
||||
|
@ -181,6 +183,7 @@ onready var patterns_popup: Popup = control.find_node("PatternsPopup")
|
|||
onready var palette_panel: PalettePanel = control.find_node("Palettes")
|
||||
|
||||
onready var references_panel: ReferencesPanel = control.find_node("Reference Images")
|
||||
onready var perspective_editor := control.find_node("Perspective Editor")
|
||||
|
||||
onready var top_menu_container: Panel = control.find_node("TopMenuContainer")
|
||||
onready var rotation_level_button: Button = control.find_node("RotationLevel")
|
||||
|
|
|
@ -24,6 +24,7 @@ var animation_tags := [] setget _animation_tags_changed # Array of AnimationTag
|
|||
var guides := [] # Array of Guides
|
||||
var brushes := [] # Array of Images
|
||||
var reference_images := [] # Array of ReferenceImages
|
||||
var vanishing_points := [] # Array of Vanishing Points
|
||||
var fps := 6.0
|
||||
|
||||
var x_symmetry_point
|
||||
|
@ -91,6 +92,12 @@ func remove() -> void:
|
|||
undo_redo.free()
|
||||
for ri in reference_images:
|
||||
ri.queue_free()
|
||||
if self == Global.current_project:
|
||||
# If the project is not current_project then the points need not be removed
|
||||
for point_idx in vanishing_points.size():
|
||||
var editor = Global.perspective_editor
|
||||
for c in editor.vanishing_point_container.get_children():
|
||||
c.queue_free()
|
||||
for guide in guides:
|
||||
guide.queue_free()
|
||||
# Prevents memory leak (due to the layers' project reference stopping ref counting from freeing)
|
||||
|
@ -186,6 +193,7 @@ func change_project() -> void:
|
|||
Global.horizontal_ruler.update()
|
||||
Global.vertical_ruler.update()
|
||||
Global.references_panel.project_changed()
|
||||
Global.perspective_editor.update()
|
||||
Global.cursor_position_label.text = "[%s×%s]" % [size.x, size.y]
|
||||
|
||||
Global.window_title = "%s - Pixelorama %s" % [name, Global.current_version]
|
||||
|
@ -325,6 +333,7 @@ func serialize() -> Dictionary:
|
|||
"frames": frame_data,
|
||||
"brushes": brush_data,
|
||||
"reference_images": reference_image_data,
|
||||
"vanishing_points": vanishing_points,
|
||||
"export_directory_path": directory_path,
|
||||
"export_file_name": file_name,
|
||||
"export_file_format": file_format,
|
||||
|
@ -412,6 +421,9 @@ func deserialize(dict: Dictionary) -> void:
|
|||
ri.project = self
|
||||
ri.deserialize(g)
|
||||
Global.canvas.add_child(ri)
|
||||
if dict.has("vanishing_points"):
|
||||
vanishing_points = dict.vanishing_points
|
||||
Global.perspective_editor.update()
|
||||
if dict.has("symmetry_points"):
|
||||
x_symmetry_point = dict.symmetry_points[0]
|
||||
y_symmetry_point = dict.symmetry_points[1]
|
||||
|
|
|
@ -416,6 +416,7 @@ func _exit_tree() -> void:
|
|||
Global.config_cache.set_value("view_menu", "draw_pixel_grid", Global.draw_pixel_grid)
|
||||
Global.config_cache.set_value("view_menu", "show_rulers", Global.show_rulers)
|
||||
Global.config_cache.set_value("view_menu", "show_guides", Global.show_guides)
|
||||
Global.config_cache.set_value("view_menu", "show_mouse_guides", Global.show_mouse_guides)
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
|
||||
var i := 0
|
||||
|
|
|
@ -16,6 +16,7 @@ onready var grid = $Grid
|
|||
onready var selection = $Selection
|
||||
onready var indicators = $Indicators
|
||||
onready var previews = $Previews
|
||||
onready var mouse_guide_container = $MouseGuideContainer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=15 format=2]
|
||||
[gd_scene load_steps=16 format=2]
|
||||
|
||||
[ext_resource path="res://src/UI/Canvas/Canvas.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/UI/Canvas/Grid.gd" type="Script" id=2]
|
||||
|
@ -10,6 +10,7 @@
|
|||
[ext_resource path="res://src/UI/Canvas/Selection.gd" type="Script" id=8]
|
||||
[ext_resource path="res://src/Shaders/MarchingAntsOutline.shader" type="Shader" id=9]
|
||||
[ext_resource path="res://src/Shaders/AutoInvertColors.shader" type="Shader" id=10]
|
||||
[ext_resource path="res://src/UI/Canvas/MouseGuideContainer.tscn" type="PackedScene" id=11]
|
||||
[ext_resource path="res://src/UI/Canvas/OnionSkinning.gd" type="Script" id=12]
|
||||
|
||||
[sub_resource type="CanvasItemMaterial" id=1]
|
||||
|
@ -72,3 +73,5 @@ script = ExtResource( 12 )
|
|||
|
||||
[node name="OnionFuture" type="Node2D" parent="."]
|
||||
script = ExtResource( 12 )
|
||||
|
||||
[node name="MouseGuideContainer" parent="." instance=ExtResource( 11 )]
|
||||
|
|
77
src/UI/Canvas/MouseGuide.gd
Normal file
77
src/UI/Canvas/MouseGuide.gd
Normal file
|
@ -0,0 +1,77 @@
|
|||
extends Line2D
|
||||
|
||||
enum Types { VERTICAL, HORIZONTAL }
|
||||
const INPUT_WIDTH := 4
|
||||
export var type := 0
|
||||
var track_mouse := true
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# Add a subtle difference to the normal guide color by mixing in some green
|
||||
default_color = Global.guide_color.linear_interpolate(Color(0.2, 0.92, 0.2), .6)
|
||||
width = Global.camera.zoom.x * 2
|
||||
draw_guide_line()
|
||||
|
||||
|
||||
func draw_guide_line():
|
||||
if type == Types.HORIZONTAL:
|
||||
points[0] = Vector2(-19999, 0)
|
||||
points[1] = Vector2(19999, 0)
|
||||
else:
|
||||
points[0] = Vector2(0, 19999)
|
||||
points[1] = Vector2(0, -19999)
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if !Global.show_mouse_guides or !Global.can_draw or !Global.has_focus:
|
||||
visible = false
|
||||
return
|
||||
visible = true
|
||||
if event is InputEventMouseMotion:
|
||||
var tmp_transform = get_canvas_transform().affine_inverse()
|
||||
var tmp_position = Global.main_viewport.get_local_mouse_position()
|
||||
var mouse_point = (tmp_transform.basis_xform(tmp_position) + tmp_transform.origin).snapped(
|
||||
Vector2(0.5, 0.5)
|
||||
)
|
||||
|
||||
var project_size = Global.current_project.size
|
||||
if Rect2(Vector2.ZERO, project_size).has_point(mouse_point):
|
||||
visible = true
|
||||
else:
|
||||
visible = false
|
||||
return
|
||||
if type == Types.HORIZONTAL:
|
||||
points[0].y = mouse_point.y
|
||||
points[1].y = mouse_point.y
|
||||
else:
|
||||
points[0].x = mouse_point.x
|
||||
points[1].x = mouse_point.x
|
||||
update()
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
width = Global.camera.zoom.x * 2
|
||||
var viewport_size: Vector2 = Global.main_viewport.rect_size
|
||||
var zoom: Vector2 = Global.camera.zoom
|
||||
|
||||
# viewport_poly is an array of the points that make up the corners of the viewport
|
||||
var viewport_poly := [
|
||||
Vector2.ZERO, Vector2(viewport_size.x, 0), viewport_size, Vector2(0, viewport_size.y)
|
||||
]
|
||||
# Adjusting viewport_poly to take into account the camera offset, zoom, and rotation
|
||||
for p in range(viewport_poly.size()):
|
||||
viewport_poly[p] = (
|
||||
viewport_poly[p].rotated(Global.camera.rotation) * zoom
|
||||
+ Vector2(
|
||||
(
|
||||
Global.camera.offset.x
|
||||
- (viewport_size.rotated(Global.camera.rotation).x / 2) * zoom.x
|
||||
),
|
||||
(
|
||||
Global.camera.offset.y
|
||||
- (viewport_size.rotated(Global.camera.rotation).y / 2) * zoom.y
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
draw_set_transform(viewport_poly[0], Global.camera.rotation, zoom * 2)
|
31
src/UI/Canvas/MouseGuideContainer.tscn
Normal file
31
src/UI/Canvas/MouseGuideContainer.tscn
Normal file
|
@ -0,0 +1,31 @@
|
|||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://assets/graphics/dotted_line.png" type="Texture" id=1]
|
||||
[ext_resource path="res://src/UI/Canvas/MouseGuide.gd" type="Script" id=2]
|
||||
|
||||
[sub_resource type="AtlasTexture" id=1]
|
||||
flags = 2
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 0, 0, 8, 1 )
|
||||
|
||||
[node name="MouseGuideContainer" type="Node2D"]
|
||||
|
||||
[node name="Vertical" type="Line2D" parent="."]
|
||||
visible = false
|
||||
points = PoolVector2Array( 0, 19999, 0, -19999 )
|
||||
default_color = Color( 1, 1, 1, 1 )
|
||||
texture = SubResource( 1 )
|
||||
texture_mode = 1
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="Horizontal" type="Line2D" parent="."]
|
||||
visible = false
|
||||
points = PoolVector2Array( -19999, 0, 19999, 0 )
|
||||
default_color = Color( 1, 1, 1, 1 )
|
||||
texture = SubResource( 1 )
|
||||
texture_mode = 1
|
||||
script = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_editor_description_": ""
|
||||
}
|
||||
type = 1
|
9
src/UI/PerspectiveEditor/LineButton.gd
Normal file
9
src/UI/PerspectiveEditor/LineButton.gd
Normal file
|
@ -0,0 +1,9 @@
|
|||
extends Button
|
||||
|
||||
onready var length_slider = $"%LengthSlider"
|
||||
|
||||
|
||||
func _ready():
|
||||
var p_size = Global.current_project.size
|
||||
var suitable_length = sqrt(pow(p_size.x, 2) + pow(p_size.y, 2))
|
||||
length_slider.max_value = suitable_length
|
61
src/UI/PerspectiveEditor/LineButton.tscn
Normal file
61
src/UI/PerspectiveEditor/LineButton.tscn
Normal file
|
@ -0,0 +1,61 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/UI/Nodes/ValueSlider.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/UI/Nodes/CollapsibleContainer.gd" type="Script" id=3]
|
||||
|
||||
[node name="LineButton" type="VBoxContainer"]
|
||||
margin_right = 159.0
|
||||
margin_bottom = 20.0
|
||||
theme_type_variation = "CollapsibleContainer"
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||
visible = false
|
||||
margin_top = 24.0
|
||||
margin_right = 159.0
|
||||
margin_bottom = 76.0
|
||||
|
||||
[node name="Spacer" type="Control" parent="HBoxContainer"]
|
||||
margin_right = 20.0
|
||||
margin_bottom = 52.0
|
||||
rect_min_size = Vector2( 20, 0 )
|
||||
|
||||
[node name="VSeparator" type="VSeparator" parent="HBoxContainer"]
|
||||
margin_left = 24.0
|
||||
margin_right = 28.0
|
||||
margin_bottom = 52.0
|
||||
|
||||
[node name="Properties" type="VBoxContainer" parent="HBoxContainer"]
|
||||
margin_left = 32.0
|
||||
margin_right = 83.0
|
||||
margin_bottom = 52.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="AngleSlider" parent="HBoxContainer/Properties" instance=ExtResource( 1 )]
|
||||
margin_right = 51.0
|
||||
max_value = 359.999
|
||||
step = 0.001
|
||||
prefix = "Angle:"
|
||||
suffix = "°"
|
||||
|
||||
[node name="LengthSlider" parent="HBoxContainer/Properties" instance=ExtResource( 1 )]
|
||||
unique_name_in_owner = true
|
||||
margin_top = 28.0
|
||||
margin_right = 51.0
|
||||
margin_bottom = 52.0
|
||||
max_value = 19999.0
|
||||
value = 19999.0
|
||||
allow_greater = true
|
||||
prefix = "Length:"
|
||||
suffix = "px"
|
||||
|
||||
[node name="Delete" type="Button" parent="HBoxContainer"]
|
||||
margin_left = 87.0
|
||||
margin_right = 151.0
|
||||
margin_bottom = 52.0
|
||||
text = "Remove"
|
||||
|
||||
[node name="VSeparator2" type="VSeparator" parent="HBoxContainer"]
|
||||
margin_left = 155.0
|
||||
margin_right = 159.0
|
||||
margin_bottom = 52.0
|
67
src/UI/PerspectiveEditor/PerspectiveEditor.gd
Normal file
67
src/UI/PerspectiveEditor/PerspectiveEditor.gd
Normal file
|
@ -0,0 +1,67 @@
|
|||
extends Control
|
||||
|
||||
var axes: Node2D
|
||||
var do_pool = [] # A pool that stores data of points removed by undo
|
||||
var delete_pool = [] # A pool that containg deleted data and their index
|
||||
var vanishing_point_res := preload("res://src/UI/PerspectiveEditor/VanishingPoint.tscn")
|
||||
|
||||
onready var vanishing_point_container = $"%VanishingPointContainer"
|
||||
|
||||
|
||||
func _on_AddPoint_pressed() -> void:
|
||||
do_pool.clear() # Reset
|
||||
var project = Global.current_project
|
||||
project.undos += 1
|
||||
project.undo_redo.create_action("Add Vanishing Point")
|
||||
project.undo_redo.add_do_method(self, "add_vanishing_point", true)
|
||||
project.undo_redo.add_undo_method(self, "undo_add_vanishing_point")
|
||||
project.undo_redo.commit_action()
|
||||
|
||||
|
||||
func update():
|
||||
for c in vanishing_point_container.get_children():
|
||||
c.queue_free()
|
||||
for idx in Global.current_project.vanishing_points.size():
|
||||
var point_data = Global.current_project.vanishing_points[idx]
|
||||
var vanishing_point := vanishing_point_res.instance()
|
||||
vanishing_point_container.add_child(vanishing_point)
|
||||
vanishing_point.initiate(point_data, idx)
|
||||
|
||||
|
||||
func add_vanishing_point(is_redo := false):
|
||||
var vanishing_point := vanishing_point_res.instance()
|
||||
vanishing_point_container.add_child(vanishing_point)
|
||||
if is_redo and !do_pool.empty():
|
||||
vanishing_point.initiate(do_pool.pop_back())
|
||||
vanishing_point.update_data_to_project()
|
||||
else:
|
||||
vanishing_point.initiate()
|
||||
|
||||
|
||||
func undo_add_vanishing_point():
|
||||
var point = vanishing_point_container.get_child(vanishing_point_container.get_child_count() - 1)
|
||||
point.queue_free()
|
||||
do_pool.append(point.data.duplicate())
|
||||
point.update_data_to_project(true)
|
||||
|
||||
|
||||
func delete_point(idx):
|
||||
var project = Global.current_project
|
||||
project.undos += 1
|
||||
project.undo_redo.create_action("Delete Vanishing Point")
|
||||
project.undo_redo.add_do_method(self, "do_delete_point", idx)
|
||||
project.undo_redo.add_undo_method(self, "undo_delete_point", idx)
|
||||
project.undo_redo.commit_action()
|
||||
|
||||
|
||||
func do_delete_point(idx):
|
||||
var point = vanishing_point_container.get_child(idx)
|
||||
delete_pool.append(point.data)
|
||||
point.queue_free()
|
||||
point.update_data_to_project(true)
|
||||
|
||||
|
||||
func undo_delete_point(idx):
|
||||
var point = delete_pool.pop_back()
|
||||
Global.current_project.vanishing_points.insert(idx, point)
|
||||
update()
|
72
src/UI/PerspectiveEditor/PerspectiveEditor.tscn
Normal file
72
src/UI/PerspectiveEditor/PerspectiveEditor.tscn
Normal file
|
@ -0,0 +1,72 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://src/UI/PerspectiveEditor/PerspectiveEditor.gd" type="Script" id=1]
|
||||
|
||||
[node name="PerspectiveEditor" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_right = -1013.0
|
||||
margin_bottom = -510.0
|
||||
rect_min_size = Vector2( 270, 10 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
self_modulate = Color( 0.698039, 0.698039, 0.698039, 0.698039 )
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 4.0
|
||||
margin_right = -4.0
|
||||
rect_clip_content = true
|
||||
size_flags_vertical = 3
|
||||
__meta__ = {
|
||||
"_editor_description_": ""
|
||||
}
|
||||
|
||||
[node name="Header" type="HBoxContainer" parent="VBoxContainer"]
|
||||
margin_right = 262.0
|
||||
margin_bottom = 30.0
|
||||
custom_constants/separation = 0
|
||||
|
||||
[node name="Label" type="Label" parent="VBoxContainer/Header"]
|
||||
margin_top = 8.0
|
||||
margin_right = 232.0
|
||||
margin_bottom = 22.0
|
||||
size_flags_horizontal = 3
|
||||
theme_type_variation = "Header"
|
||||
text = "Perspective Editor"
|
||||
align = 1
|
||||
valign = 1
|
||||
|
||||
[node name="AddPoint" type="Button" parent="VBoxContainer/Header"]
|
||||
margin_left = 232.0
|
||||
margin_right = 262.0
|
||||
margin_bottom = 30.0
|
||||
rect_min_size = Vector2( 30, 30 )
|
||||
text = "+"
|
||||
clip_text = true
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="VBoxContainer"]
|
||||
margin_top = 34.0
|
||||
margin_right = 262.0
|
||||
margin_bottom = 38.0
|
||||
|
||||
[node name="HSeparator2" type="HSeparator" parent="VBoxContainer"]
|
||||
margin_top = 42.0
|
||||
margin_right = 262.0
|
||||
margin_bottom = 46.0
|
||||
|
||||
[node name="Content" type="ScrollContainer" parent="VBoxContainer"]
|
||||
margin_top = 50.0
|
||||
margin_right = 262.0
|
||||
margin_bottom = 210.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="VanishingPointContainer" type="VBoxContainer" parent="VBoxContainer/Content"]
|
||||
unique_name_in_owner = true
|
||||
margin_right = 262.0
|
||||
margin_bottom = 160.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
custom_constants/separation = 5
|
||||
|
||||
[connection signal="pressed" from="VBoxContainer/Header/AddPoint" to="." method="_on_AddPoint_pressed"]
|
101
src/UI/PerspectiveEditor/PerspectiveLine.gd
Normal file
101
src/UI/PerspectiveEditor/PerspectiveLine.gd
Normal file
|
@ -0,0 +1,101 @@
|
|||
class_name PerspectiveLine
|
||||
extends Line2D
|
||||
|
||||
const INPUT_WIDTH := 4
|
||||
var hidden = false
|
||||
var track_mouse := false
|
||||
var _data = {"start": Vector2.ZERO, "angle": 0, "length": 19999, "color": Color.black}
|
||||
|
||||
|
||||
func initiate(data: Dictionary):
|
||||
width = Global.camera.zoom.x * 2
|
||||
Global.canvas.add_child(self)
|
||||
refresh(data)
|
||||
|
||||
|
||||
func refresh(data: Dictionary):
|
||||
_data = data
|
||||
default_color = data.color
|
||||
draw_perspective_line()
|
||||
|
||||
|
||||
func draw_perspective_line():
|
||||
var angle = -_data.angle
|
||||
points[0] = _data.start
|
||||
if hidden:
|
||||
points[1] = _data.start
|
||||
else:
|
||||
points[1] = (
|
||||
_data.start
|
||||
+ Vector2(_data.length * cos(deg2rad(angle)), _data.length * sin(deg2rad(angle)))
|
||||
)
|
||||
|
||||
|
||||
func hide_perspective_line():
|
||||
points[1] = _data.start
|
||||
hidden = true
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventMouse:
|
||||
if track_mouse:
|
||||
if !Global.can_draw or !Global.has_focus:
|
||||
hide_perspective_line()
|
||||
return
|
||||
default_color.a = 0.5
|
||||
var tmp_transform = get_canvas_transform().affine_inverse()
|
||||
var tmp_position = Global.main_viewport.get_local_mouse_position()
|
||||
var mouse_point = tmp_transform.basis_xform(tmp_position) + tmp_transform.origin
|
||||
var project_size = Global.current_project.size
|
||||
if Rect2(Vector2.ZERO, project_size).has_point(mouse_point):
|
||||
hidden = false
|
||||
draw_perspective_line()
|
||||
var rel_vector = mouse_point - _data.start
|
||||
var test_vector = Vector2(_data.start.x, 0)
|
||||
if sign(test_vector.x) == 0:
|
||||
test_vector.x += 0.5
|
||||
|
||||
_data.angle = rad2deg(test_vector.angle_to(rel_vector))
|
||||
if sign(test_vector.x) == -1:
|
||||
_data.angle += 180
|
||||
|
||||
points[1] = (
|
||||
_data.start
|
||||
+ Vector2(
|
||||
_data.length * cos(deg2rad(_data.angle)),
|
||||
_data.length * sin(deg2rad(_data.angle))
|
||||
)
|
||||
)
|
||||
else:
|
||||
hide_perspective_line()
|
||||
update()
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
draw_circle(_data.start, Global.camera.zoom.x * 5, default_color)
|
||||
width = Global.camera.zoom.x * 2
|
||||
if hidden: # Hidden line
|
||||
return
|
||||
var viewport_size: Vector2 = Global.main_viewport.rect_size
|
||||
var zoom: Vector2 = Global.camera.zoom
|
||||
# viewport_poly is an array of the points that make up the corners of the viewport
|
||||
var viewport_poly := [
|
||||
Vector2.ZERO, Vector2(viewport_size.x, 0), viewport_size, Vector2(0, viewport_size.y)
|
||||
]
|
||||
# Adjusting viewport_poly to take into account the camera offset, zoom, and rotation
|
||||
for p in range(viewport_poly.size()):
|
||||
viewport_poly[p] = (
|
||||
viewport_poly[p].rotated(Global.camera.rotation) * zoom
|
||||
+ Vector2(
|
||||
(
|
||||
Global.camera.offset.x
|
||||
- (viewport_size.rotated(Global.camera.rotation).x / 2) * zoom.x
|
||||
),
|
||||
(
|
||||
Global.camera.offset.y
|
||||
- (viewport_size.rotated(Global.camera.rotation).y / 2) * zoom.y
|
||||
)
|
||||
)
|
||||
)
|
||||
# If there's no intersection with a viewport edge, show string in top left corner
|
||||
draw_set_transform(viewport_poly[0], Global.camera.rotation, zoom * 2)
|
7
src/UI/PerspectiveEditor/PerspectiveLine.tscn
Normal file
7
src/UI/PerspectiveEditor/PerspectiveLine.tscn
Normal file
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://src/UI/PerspectiveEditor/PerspectiveLine.gd" type="Script" id=1]
|
||||
|
||||
[node name="PerspectiveLine" type="Line2D"]
|
||||
points = PoolVector2Array( 0, 0, 64, 0 )
|
||||
script = ExtResource( 1 )
|
41
src/UI/PerspectiveEditor/PointCollapseContainer.gd
Normal file
41
src/UI/PerspectiveEditor/PointCollapseContainer.gd
Normal file
|
@ -0,0 +1,41 @@
|
|||
extends Button
|
||||
|
||||
# This is NOT related to the CollapsibleContainer class (though it behaves similarly)
|
||||
# i did it like this because the "Content" is part of a different node
|
||||
export var point_text := "" setget _set_text
|
||||
export var visible_content := false setget _set_visible_content
|
||||
onready var content = $"%Content"
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_set_visible(pressed)
|
||||
content.connect("visibility_changed", self, "_child_visibility_changed")
|
||||
|
||||
|
||||
func _set_text(value: String) -> void:
|
||||
$Label.text = value
|
||||
rect_min_size = $Label.rect_size
|
||||
|
||||
|
||||
func _set_visible_content(value: bool) -> void:
|
||||
visible_content = value
|
||||
pressed = value
|
||||
|
||||
|
||||
func _on_Button_toggled(button_pressed: bool) -> void:
|
||||
_set_visible(button_pressed)
|
||||
|
||||
|
||||
func _set_visible(pressed: bool) -> void:
|
||||
if pressed:
|
||||
$TextureRect.rect_rotation = 0
|
||||
else:
|
||||
$TextureRect.rect_rotation = -90
|
||||
content.visible = pressed
|
||||
|
||||
|
||||
# Checks if a child becomes visible from another source and ensures
|
||||
# it remains invisible if the button is not pressed
|
||||
func _child_visibility_changed() -> void:
|
||||
if not pressed:
|
||||
content.visible = false
|
228
src/UI/PerspectiveEditor/VanishingPoint.gd
Normal file
228
src/UI/PerspectiveEditor/VanishingPoint.gd
Normal file
|
@ -0,0 +1,228 @@
|
|||
extends VBoxContainer
|
||||
|
||||
var perspective_lines = []
|
||||
var tracker_line: PerspectiveLine
|
||||
var data = {
|
||||
"position_x": 0,
|
||||
"position_y": 0,
|
||||
"angles": [],
|
||||
"lengths": [],
|
||||
"color": Color(randf(), randf(), randf(), 1).to_html(),
|
||||
}
|
||||
|
||||
onready var color_picker_button = $"%ColorPickerButton"
|
||||
onready var title = $"%PointCollapseContainer"
|
||||
onready var pos_x = $"%X"
|
||||
onready var pos_y = $"%Y"
|
||||
onready var line_buttons_container = $"%LinesContainer"
|
||||
onready var boundary_l = $Content/BoundaryL
|
||||
onready var boundary_r = $Content/BoundaryR
|
||||
onready var boundary_b = $Content/VBoxContainer/BoundaryB
|
||||
|
||||
|
||||
func initiate(start_data = null, idx = -1) -> void:
|
||||
if start_data:
|
||||
data = start_data.duplicate()
|
||||
add_line(null, true)
|
||||
for i in data.angles.size():
|
||||
var loaded_line_data = {
|
||||
"start": Vector2(data.position_x, data.position_y),
|
||||
"angle": data.angles[i],
|
||||
"length": data.lengths[i],
|
||||
"color": Color(data.color)
|
||||
}
|
||||
add_line(loaded_line_data)
|
||||
if idx != -1:
|
||||
title.point_text = str("Point: ", idx + 1)
|
||||
else:
|
||||
title.point_text = str("Point: ", get_parent().get_child_count())
|
||||
pos_x.value = data.position_x
|
||||
pos_y.value = data.position_y
|
||||
color_picker_button.color = Color(data.color)
|
||||
update_boundary_color(color_picker_button.color)
|
||||
color_picker_button.connect("color_changed", self, "_on_color_changed")
|
||||
pos_x.connect("value_changed", self, "_on_X_value_changed")
|
||||
pos_y.connect("value_changed", self, "_on_Y_value_changed")
|
||||
if !start_data:
|
||||
update_data_to_project()
|
||||
|
||||
|
||||
func update_boundary_color(color: Color):
|
||||
var luminance = (0.2126 * color.r) + (0.7152 * color.g) + (0.0722 * color.b)
|
||||
color.a = 0.9 - luminance * 0.4 # Interpolates between 0.5 to 0.9
|
||||
boundary_l.color = color
|
||||
boundary_r.color = color
|
||||
boundary_b.color = color
|
||||
|
||||
|
||||
# Signals
|
||||
func _on_AddLine_pressed() -> void:
|
||||
add_line()
|
||||
update_data_to_project()
|
||||
|
||||
|
||||
func _on_Delete_pressed() -> void:
|
||||
Global.perspective_editor.delete_point(get_index())
|
||||
|
||||
|
||||
func _on_color_changed(_color: Color):
|
||||
update_boundary_color(_color)
|
||||
data.color = _color.to_html()
|
||||
refresh(-1)
|
||||
update_data_to_project()
|
||||
|
||||
|
||||
func _on_X_value_changed(value: float) -> void:
|
||||
data.position_x = value
|
||||
refresh(-1)
|
||||
update_data_to_project()
|
||||
|
||||
|
||||
func _on_Y_value_changed(value):
|
||||
data.position_y = value
|
||||
refresh(-1)
|
||||
update_data_to_project()
|
||||
|
||||
|
||||
func _angle_changed(value: float, line_button):
|
||||
var line_index = line_button.get_index()
|
||||
data.angles[line_index] = value
|
||||
refresh(line_index)
|
||||
update_data_to_project()
|
||||
|
||||
|
||||
func _length_changed(value: float, line_button):
|
||||
var line_index = line_button.get_index()
|
||||
data.lengths[line_index] = value
|
||||
refresh(line_index)
|
||||
update_data_to_project()
|
||||
|
||||
|
||||
func _remove_line_pressed(line_button):
|
||||
var index = line_button.get_index()
|
||||
remove_line(index)
|
||||
line_button.queue_free()
|
||||
update_data_to_project()
|
||||
|
||||
|
||||
# Methods
|
||||
func add_line(loaded_line_data = null, is_tracker := false):
|
||||
var p_size = Global.current_project.size
|
||||
var default_line_data = {
|
||||
"start": Vector2(data.position_x, data.position_y),
|
||||
"angle": 0,
|
||||
"length": 19999,
|
||||
"color": Color(data.color)
|
||||
}
|
||||
if default_line_data.start.x > p_size.x / 2:
|
||||
# If new line is created ahed of half project distance then
|
||||
# reverse it's angle (for beautification)
|
||||
default_line_data.angle = 180
|
||||
|
||||
# Check if we have loading data instead of creating line
|
||||
# Then THAT should be our data
|
||||
if loaded_line_data:
|
||||
default_line_data = loaded_line_data
|
||||
|
||||
if is_tracker: # if we are creating tracker line then length adjustment is not required
|
||||
if tracker_line != null: # Also if the tracker line already exists then cancel creation
|
||||
return
|
||||
else: # If we are not creating a perspective line then adjust it's length
|
||||
var suitable_length = sqrt(pow(p_size.x, 2) + pow(p_size.y, 2))
|
||||
default_line_data.length = suitable_length
|
||||
|
||||
# Create the visual line
|
||||
var line = preload("res://src/UI/PerspectiveEditor/PerspectiveLine.tscn").instance()
|
||||
line.initiate(default_line_data)
|
||||
|
||||
# Set it's mode accordingly
|
||||
if is_tracker: # Settings for Tracker mode
|
||||
line.track_mouse = true
|
||||
tracker_line = line
|
||||
tracker_line.hide_perspective_line()
|
||||
else: # Settings for Normal mode
|
||||
var line_button = preload("res://src/UI/PerspectiveEditor/LineButton.tscn").instance()
|
||||
line_buttons_container.add_child(line_button)
|
||||
var index = line_button.get_parent().get_child_count() - 2
|
||||
line_button.get_parent().move_child(line_button, index)
|
||||
|
||||
var line_name = str(
|
||||
"Line", line_button.get_index() + 1, " (", int(default_line_data.angle), "°)"
|
||||
)
|
||||
line_button.text = line_name
|
||||
|
||||
var remove_button = line_button.find_node("Delete")
|
||||
var angle_slider = line_button.find_node("AngleSlider")
|
||||
var length_slider = line_button.find_node("LengthSlider")
|
||||
|
||||
angle_slider.value = default_line_data.angle
|
||||
length_slider.value = default_line_data.length
|
||||
if !loaded_line_data:
|
||||
data.angles.append(angle_slider.value)
|
||||
data.lengths.append(length_slider.value)
|
||||
|
||||
angle_slider.connect("value_changed", self, "_angle_changed", [line_button])
|
||||
length_slider.connect("value_changed", self, "_length_changed", [line_button])
|
||||
remove_button.connect("pressed", self, "_remove_line_pressed", [line_button])
|
||||
perspective_lines.append(line)
|
||||
|
||||
|
||||
func remove_line(line_index):
|
||||
var line_to_remove = perspective_lines[line_index]
|
||||
perspective_lines.remove(line_index)
|
||||
data.angles.remove(line_index)
|
||||
data.lengths.remove(line_index)
|
||||
line_to_remove.queue_free()
|
||||
|
||||
|
||||
func update_data_to_project(removal := false):
|
||||
var project = Global.current_project
|
||||
var idx = get_index()
|
||||
if removal:
|
||||
project.vanishing_points.remove(idx)
|
||||
return
|
||||
if idx < project.vanishing_points.size():
|
||||
project.vanishing_points[idx] = data
|
||||
else:
|
||||
project.vanishing_points.append(data)
|
||||
Global.current_project.has_changed = true
|
||||
|
||||
|
||||
func refresh(index: int):
|
||||
if index == -1: # means all lines should be refreshed
|
||||
refresh_tracker()
|
||||
for i in data.angles.size():
|
||||
refresh_line(i)
|
||||
else:
|
||||
refresh_line(index)
|
||||
|
||||
|
||||
func refresh_line(index: int):
|
||||
var line_data = {
|
||||
"start": Vector2(data.position_x, data.position_y),
|
||||
"angle": data.angles[index],
|
||||
"length": data.lengths[index],
|
||||
"color": Color(data.color)
|
||||
}
|
||||
var line_button = line_buttons_container.get_child(index)
|
||||
var line_name = str("Line", line_button.get_index() + 1, " (", int(line_data.angle), "°)")
|
||||
line_button.text = line_name
|
||||
perspective_lines[index].refresh(line_data)
|
||||
|
||||
|
||||
func refresh_tracker():
|
||||
var line_data = {
|
||||
"start": Vector2(data.position_x, data.position_y),
|
||||
"angle": tracker_line._data.angle,
|
||||
"length": tracker_line._data.length,
|
||||
"color": Color(data.color)
|
||||
}
|
||||
tracker_line.refresh(line_data)
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if tracker_line:
|
||||
tracker_line.queue_free()
|
||||
tracker_line = null
|
||||
for idx in perspective_lines.size():
|
||||
perspective_lines[idx].queue_free()
|
171
src/UI/PerspectiveEditor/VanishingPoint.tscn
Normal file
171
src/UI/PerspectiveEditor/VanishingPoint.tscn
Normal file
|
@ -0,0 +1,171 @@
|
|||
[gd_scene load_steps=6 format=2]
|
||||
|
||||
[ext_resource path="res://src/UI/Nodes/ValueSlider.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/UI/PerspectiveEditor/VanishingPoint.gd" type="Script" id=2]
|
||||
[ext_resource path="res://src/UI/Nodes/CollapsibleContainer.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://assets/graphics/misc/value_arrow.svg" type="Texture" id=4]
|
||||
[ext_resource path="res://src/UI/PerspectiveEditor/PointCollapseContainer.gd" type="Script" id=5]
|
||||
|
||||
[node name="VanishingPoint" type="VBoxContainer" groups=["Entry"]]
|
||||
margin_right = 261.0
|
||||
margin_bottom = 145.0
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="TitleContainer" type="HBoxContainer" parent="."]
|
||||
margin_right = 261.0
|
||||
margin_bottom = 20.0
|
||||
|
||||
[node name="PointCollapseContainer" type="Button" parent="TitleContainer"]
|
||||
unique_name_in_owner = true
|
||||
margin_right = 207.0
|
||||
margin_bottom = 20.0
|
||||
mouse_default_cursor_shape = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_type_variation = "CollapsibleCheckBox"
|
||||
toggle_mode = true
|
||||
script = ExtResource( 5 )
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="TitleContainer/PointCollapseContainer" groups=["UIButtons"]]
|
||||
anchor_top = 0.5
|
||||
anchor_bottom = 0.5
|
||||
margin_left = 2.0
|
||||
margin_top = -6.0
|
||||
margin_right = 14.0
|
||||
margin_bottom = 6.0
|
||||
rect_rotation = -90.0
|
||||
rect_pivot_offset = Vector2( 6, 6 )
|
||||
texture = ExtResource( 4 )
|
||||
|
||||
[node name="Label" type="Label" parent="TitleContainer/PointCollapseContainer"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 14.0
|
||||
theme_type_variation = "Header"
|
||||
valign = 1
|
||||
|
||||
[node name="ColorPickerButton" type="ColorPickerButton" parent="TitleContainer"]
|
||||
unique_name_in_owner = true
|
||||
margin_left = 211.0
|
||||
margin_right = 261.0
|
||||
margin_bottom = 20.0
|
||||
rect_min_size = Vector2( 50, 0 )
|
||||
|
||||
[node name="Content" type="HBoxContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
margin_top = 24.0
|
||||
margin_right = 261.0
|
||||
margin_bottom = 130.0
|
||||
|
||||
[node name="Spacer" type="Control" parent="Content"]
|
||||
margin_right = 5.0
|
||||
margin_bottom = 106.0
|
||||
rect_min_size = Vector2( 5, 0 )
|
||||
|
||||
[node name="BoundaryL" type="ColorRect" parent="Content"]
|
||||
margin_left = 9.0
|
||||
margin_right = 11.0
|
||||
margin_bottom = 106.0
|
||||
rect_min_size = Vector2( 2, 0 )
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="Content"]
|
||||
margin_left = 15.0
|
||||
margin_right = 255.0
|
||||
margin_bottom = 106.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="PointInfo" type="HBoxContainer" parent="Content/VBoxContainer"]
|
||||
margin_right = 240.0
|
||||
margin_bottom = 52.0
|
||||
|
||||
[node name="Label" type="Label" parent="Content/VBoxContainer/PointInfo"]
|
||||
margin_right = 56.0
|
||||
margin_bottom = 52.0
|
||||
size_flags_vertical = 5
|
||||
text = "Position:"
|
||||
|
||||
[node name="Position" type="VBoxContainer" parent="Content/VBoxContainer/PointInfo"]
|
||||
margin_left = 60.0
|
||||
margin_right = 240.0
|
||||
margin_bottom = 52.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="X" parent="Content/VBoxContainer/PointInfo/Position" instance=ExtResource( 1 )]
|
||||
unique_name_in_owner = true
|
||||
margin_right = 180.0
|
||||
step = 0.5
|
||||
allow_greater = true
|
||||
allow_lesser = true
|
||||
prefix = "X :"
|
||||
|
||||
[node name="Y" parent="Content/VBoxContainer/PointInfo/Position" instance=ExtResource( 1 )]
|
||||
unique_name_in_owner = true
|
||||
margin_top = 28.0
|
||||
margin_right = 180.0
|
||||
margin_bottom = 52.0
|
||||
step = 0.5
|
||||
allow_greater = true
|
||||
allow_lesser = true
|
||||
prefix = "Y :"
|
||||
|
||||
[node name="CollapsibleContainer" parent="Content/VBoxContainer" instance=ExtResource( 3 )]
|
||||
margin_top = 56.0
|
||||
margin_right = 240.0
|
||||
margin_bottom = 76.0
|
||||
text = "Lines"
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="Content/VBoxContainer/CollapsibleContainer"]
|
||||
visible = false
|
||||
margin_top = 24.0
|
||||
margin_right = 261.0
|
||||
margin_bottom = 44.0
|
||||
|
||||
[node name="Spacer" type="Control" parent="Content/VBoxContainer/CollapsibleContainer/HBoxContainer"]
|
||||
margin_right = 20.0
|
||||
margin_bottom = 20.0
|
||||
rect_min_size = Vector2( 20, 0 )
|
||||
|
||||
[node name="VSeparator" type="VSeparator" parent="Content/VBoxContainer/CollapsibleContainer/HBoxContainer"]
|
||||
margin_right = 4.0
|
||||
margin_bottom = 40.0
|
||||
|
||||
[node name="LinesContainer" type="VBoxContainer" parent="Content/VBoxContainer/CollapsibleContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
margin_left = 24.0
|
||||
margin_right = 261.0
|
||||
margin_bottom = 20.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="AddLine" type="Button" parent="Content/VBoxContainer/CollapsibleContainer/HBoxContainer/LinesContainer"]
|
||||
margin_right = 237.0
|
||||
margin_bottom = 20.0
|
||||
text = "Add Line"
|
||||
|
||||
[node name="Delete" type="Button" parent="Content/VBoxContainer"]
|
||||
margin_top = 80.0
|
||||
margin_right = 240.0
|
||||
margin_bottom = 100.0
|
||||
rect_min_size = Vector2( 40, 0 )
|
||||
text = "Delete Point"
|
||||
|
||||
[node name="BoundaryB" type="ColorRect" parent="Content/VBoxContainer"]
|
||||
margin_top = 104.0
|
||||
margin_right = 240.0
|
||||
margin_bottom = 106.0
|
||||
rect_min_size = Vector2( 0, 2 )
|
||||
|
||||
[node name="BoundaryR" type="ColorRect" parent="Content"]
|
||||
margin_left = 259.0
|
||||
margin_right = 261.0
|
||||
margin_bottom = 106.0
|
||||
rect_min_size = Vector2( 2, 0 )
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="."]
|
||||
margin_top = 134.0
|
||||
margin_right = 261.0
|
||||
margin_bottom = 144.0
|
||||
custom_constants/separation = 10
|
||||
|
||||
[connection signal="toggled" from="TitleContainer/PointCollapseContainer" to="TitleContainer/PointCollapseContainer" method="_on_Button_toggled"]
|
||||
[connection signal="pressed" from="Content/VBoxContainer/CollapsibleContainer/HBoxContainer/LinesContainer/AddLine" to="." method="_on_AddLine_pressed"]
|
||||
[connection signal="pressed" from="Content/VBoxContainer/Delete" to="." method="_on_Delete_pressed"]
|
|
@ -123,6 +123,7 @@ func _setup_view_menu() -> void:
|
|||
"Show Pixel Grid",
|
||||
"Show Rulers",
|
||||
"Show Guides",
|
||||
"Show Mouse Guides",
|
||||
"Snap To",
|
||||
]
|
||||
view_menu = view_menu_button.get_popup()
|
||||
|
@ -160,8 +161,13 @@ func _setup_view_menu() -> void:
|
|||
var show_guides: bool = Global.config_cache.get_value(
|
||||
"view_menu", "show_guides", Global.show_guides
|
||||
)
|
||||
var show_mouse_guides: bool = Global.config_cache.get_value(
|
||||
"view_menu", "show_mouse_guides", Global.show_mouse_guides
|
||||
)
|
||||
if show_guides != Global.show_guides:
|
||||
_toggle_show_guides()
|
||||
if show_mouse_guides != Global.show_mouse_guides:
|
||||
_toggle_show_mouse_guides()
|
||||
|
||||
|
||||
func _setup_tile_mode_submenu(item: String) -> void:
|
||||
|
@ -460,6 +466,8 @@ func view_menu_id_pressed(id: int) -> void:
|
|||
_toggle_show_rulers()
|
||||
Global.ViewMenu.SHOW_GUIDES:
|
||||
_toggle_show_guides()
|
||||
Global.ViewMenu.SHOW_MOUSE_GUIDES:
|
||||
_toggle_show_mouse_guides()
|
||||
_:
|
||||
_handle_metadata(id, view_menu_button)
|
||||
|
||||
|
@ -574,8 +582,6 @@ func _toggle_show_grid() -> void:
|
|||
func _toggle_show_pixel_grid() -> void:
|
||||
Global.draw_pixel_grid = !Global.draw_pixel_grid
|
||||
view_menu.set_item_checked(Global.ViewMenu.SHOW_PIXEL_GRID, Global.draw_pixel_grid)
|
||||
if Global.canvas.pixel_grid:
|
||||
Global.canvas.pixel_grid.update()
|
||||
|
||||
|
||||
func _toggle_show_rulers() -> void:
|
||||
|
@ -598,6 +604,15 @@ func _toggle_show_guides() -> void:
|
|||
guide.visible = Global.show_y_symmetry_axis and Global.show_guides
|
||||
|
||||
|
||||
func _toggle_show_mouse_guides() -> void:
|
||||
Global.show_mouse_guides = !Global.show_mouse_guides
|
||||
view_menu.set_item_checked(Global.ViewMenu.SHOW_MOUSE_GUIDES, Global.show_mouse_guides)
|
||||
if Global.show_mouse_guides:
|
||||
if Global.canvas.mouse_guide_container:
|
||||
Global.canvas.mouse_guide_container.get_child(0).update()
|
||||
Global.canvas.mouse_guide_container.get_child(1).update()
|
||||
|
||||
|
||||
func _toggle_zen_mode() -> void:
|
||||
for i in ui_elements.size():
|
||||
if ui_elements[i].name == "Main Canvas":
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=48 format=2]
|
||||
[gd_scene load_steps=49 format=2]
|
||||
|
||||
[ext_resource path="res://src/UI/Tools/Tools.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/UI/Canvas/CanvasPreview.tscn" type="PackedScene" id=2]
|
||||
|
@ -11,6 +11,7 @@
|
|||
[ext_resource path="res://src/Shaders/TransparentChecker.shader" type="Shader" id=9]
|
||||
[ext_resource path="res://src/UI/GlobalToolOptions/GlobalToolOptions.tscn" type="PackedScene" id=10]
|
||||
[ext_resource path="res://src/UI/ReferenceImages/ReferencesPanel.tscn" type="PackedScene" id=11]
|
||||
[ext_resource path="res://src/UI/PerspectiveEditor/PerspectiveEditor.tscn" type="PackedScene" id=12]
|
||||
[ext_resource path="res://addons/dockable_container/layout.gd" type="Script" id=14]
|
||||
[ext_resource path="res://src/UI/CanvasPreviewContainer/CanvasPreviewContainer.tscn" type="PackedScene" id=16]
|
||||
[ext_resource path="res://src/UI/ColorPickers/ColorPickers.tscn" type="PackedScene" id=17]
|
||||
|
@ -34,7 +35,7 @@ shader_param/size = Vector2( 100, 100 )
|
|||
[sub_resource type="Resource" id=1]
|
||||
resource_name = "Tabs"
|
||||
script = ExtResource( 36 )
|
||||
names = PoolStringArray( "Tools" )
|
||||
names = PoolStringArray( "Tools", "Perspective Editor" )
|
||||
current_tab = 0
|
||||
|
||||
[sub_resource type="Resource" id=8]
|
||||
|
@ -404,6 +405,11 @@ margin_left = 1079.0
|
|||
margin_right = 1080.0
|
||||
margin_bottom = 1004.0
|
||||
|
||||
[node name="Perspective Editor" parent="DockableContainer" instance=ExtResource( 12 )]
|
||||
visible = false
|
||||
margin_right = -1010.0
|
||||
margin_bottom = -710.0
|
||||
|
||||
[connection signal="item_rect_changed" from="DockableContainer/Main Canvas" to="." method="_on_main_canvas_item_rect_changed"]
|
||||
[connection signal="visibility_changed" from="DockableContainer/Main Canvas" to="." method="_on_main_canvas_visibility_changed"]
|
||||
[connection signal="reposition_active_tab_request" from="DockableContainer/Main Canvas/TabsContainer/Tabs" to="DockableContainer/Main Canvas/TabsContainer/Tabs" method="_on_Tabs_reposition_active_tab_request"]
|
||||
|
|
Loading…
Reference in a new issue