Added scene palette addon

This commit is contained in:
Marco 2025-02-24 11:57:09 +01:00
commit 687d3f7803
43 changed files with 1471 additions and 0 deletions

View file

@ -0,0 +1,116 @@
@tool
extends Control
const pp = 'ScenePalettePlugin: ' # prepended to printed messages
const MOUSE_HOVER_SCALE_ADJUST = 0.05
@onready var picture_point = %PicturePoint
@onready var name_label = %NameLabel
@onready var texture_rect: TextureRect = %TextureRect
var _scene_path:String
var instantiate_scene_preview:
set(value):
instantiate_scene_preview = value
# refresh the preview
if _scene_path:
set_scene(_scene_path)
func adjust_scale(amt:float):
picture_point.scale = Vector2(amt, amt)
func show_file_label(show:bool):
# setting text here instead of in set_scene seems to work better
name_label.text = _create_display_label(_scene_path)
name_label.visible = show
func _create_display_label(path:String) -> String:
var display_label = path.split('.tscn')[0].split('/')[-1]
display_label = display_label.replace('_', ' ').replace('-', ' ')
return display_label
func set_scene(path:String):
tooltip_text = path
_scene_path = path
var file_extension = path.split('.')[-1]
for node in picture_point.get_children():
node.queue_free()
match file_extension:
'png':
texture_rect.texture = load(_scene_path)
'tscn':
if instantiate_scene_preview:
var node:Node = load(_scene_path).instantiate()
if _scene_is_safe(node):
picture_point.add_child(node)
return
# if scene is not safe to instantiate, just keep a preview
_make_preview()
'obj':
_make_preview()
func _make_preview():
var resource_previewer = EditorInterface.get_resource_previewer()
resource_previewer.queue_resource_preview(_scene_path, self, '_on_resource_preview', null)
func _on_resource_preview(path:String, preview:Texture2D, thumbnail_preview:Texture2D, _user_data):
var texture_rect = TextureRect.new()
add_child(texture_rect)
texture_rect.texture = preview
hide()
show()
## determine if scene is safe to instantiate as a preview
func _scene_is_safe(scene:Node) -> bool:
# if scene is a Node then it can't be positioned within the panel and
# clip_contents does not work.
if not scene is Node2D:
print("%Not instantiating preview for %s because it is not a Node2D" %
[pp, scene.scene_file_path]
)
return false
# if scene contains a camera, the entire editor is repositioned
if _scene_contains_camera(scene):
print("%Not instantiating preview for %s because it contains a camera." %
[pp, scene.scene_file_path]
)
return false
return true
func _scene_contains_camera(scene:Node) -> bool:
if scene is Camera2D:
return true
for node in scene.get_children():
var result:bool = _scene_contains_camera(node)
if result:
return result
return false
## Mimics the data that would be provided if a file were dragged from the
## FileSystem browser
func _make_file_data() -> Dictionary:
return {
'type': 'files',
'files': [_scene_path],
'from': ''
}
func _make_drag_preview() -> Control:
var control:Control = Control.new()
if instantiate_scene_preview:
var scene = load(_scene_path).instantiate()
control.add_child(scene)
# TODO add an alternate image here
return control
func _get_drag_data(at_position):
set_drag_preview(_make_drag_preview())
return _make_file_data()
func _on_mouse_entered():
scale = Vector2.ONE + Vector2(MOUSE_HOVER_SCALE_ADJUST, MOUSE_HOVER_SCALE_ADJUST)
func _on_mouse_exited():
scale = Vector2.ONE

View file

@ -0,0 +1 @@
uid://ddmp30k7qqcrm

View file

@ -0,0 +1,77 @@
[gd_scene load_steps=6 format=3 uid="uid://cypob1bi5kovv"]
[ext_resource type="Script" path="res://addons/scene_palette/components/scene_thumbnail/scene_drop_holder.gd" id="1_1tb3w"]
[ext_resource type="Script" path="res://addons/scene_palette/components/scene_thumbnail/scene_drop.gd" id="2_7tuog"]
[ext_resource type="Texture2D" uid="uid://cgrtskqrq8iqy" path="res://addons/scene_palette/icons/open_scene.png" id="3_iydoq"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0w221"]
bg_color = Color(0.2484, 0.2484, 0.2484, 1)
corner_radius_top_left = 5
corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5
[sub_resource type="LabelSettings" id="LabelSettings_txl6c"]
font_size = 12
font_color = Color(0.838897, 0.838897, 0.838897, 1)
[node name="SceneDropHolder" type="MarginContainer"]
clip_contents = true
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("1_1tb3w")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
[node name="SceneDrop" type="Panel" parent="VBoxContainer"]
unique_name_in_owner = true
clip_contents = true
custom_minimum_size = Vector2(65, 65)
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_0w221")
script = ExtResource("2_7tuog")
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/SceneDrop"]
clip_contents = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/margin_left = 5
theme_override_constants/margin_top = 5
theme_override_constants/margin_right = 5
theme_override_constants/margin_bottom = 20
[node name="PicturePoint" type="Control" parent="VBoxContainer/SceneDrop/MarginContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 8
[node name="TextureRect" type="TextureRect" parent="VBoxContainer/SceneDrop/MarginContainer"]
unique_name_in_owner = true
texture_filter = 1
clip_contents = true
layout_mode = 2
expand_mode = 5
[node name="NameLabel" type="Label" parent="VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "name"
label_settings = SubResource("LabelSettings_txl6c")
autowrap_mode = 3
[node name="OpenSceneButton" type="Button" parent="."]
layout_mode = 2
size_flags_horizontal = 8
size_flags_vertical = 0
tooltip_text = "Open Scene in Editor"
icon = ExtResource("3_iydoq")
[connection signal="mouse_entered" from="VBoxContainer/SceneDrop" to="VBoxContainer/SceneDrop" method="_on_mouse_entered"]
[connection signal="mouse_exited" from="VBoxContainer/SceneDrop" to="VBoxContainer/SceneDrop" method="_on_mouse_exited"]
[connection signal="pressed" from="OpenSceneButton" to="." method="_on_open_scene_button_pressed"]

View file

@ -0,0 +1,36 @@
@tool
extends MarginContainer
class_name PalettePluginSceneDrop
@onready var scene_drop = %SceneDrop
@onready var name_label = %NameLabel
@onready var open_scene_button: Button = $OpenSceneButton
# Note most of the code is in scene_drop.gd attached to SceneDrop, this is a wrapper.
# A wrapper is used because it made implementing the drag and drop code easier
var instantiate_scene_preview:
set(value):
scene_drop.instantiate_scene_preview = value
var _scene_path:String
func set_scene(path:String):
_scene_path = path
scene_drop.set_scene(path)
var scene_name = _scene_path.split('.')[0].split('/')[-1]
name_label.text = scene_name
name_label.tooltip_text = scene_name
var file_extension = path.split('.')[-1]
if file_extension != 'tscn':
open_scene_button.hide()
func _on_open_scene_button_pressed():
EditorInterface.open_scene_from_path(_scene_path)
func adjust_scale(amt:float):
scene_drop.adjust_scale(amt)
func show_file_label(show:bool):
scene_drop.show_file_label(show)

View file

@ -0,0 +1 @@
uid://ho726nh4p5h5