Brought over the addons from the 3d project.
@ -142,7 +142,7 @@ func _input(event):
|
||||
if event is InputEventKey and event.is_pressed() and not event.is_echo():
|
||||
_handle_shortcuts(event.scancode)
|
||||
|
||||
if is_mouse_in_canvas():
|
||||
if is_mouse_in_canvas() and paint_canvas.mouse_on_top:
|
||||
_handle_zoom(event)
|
||||
|
||||
if paint_canvas.is_active_layer_locked():
|
||||
@ -201,11 +201,13 @@ func _process(delta):
|
||||
mouse_position = get_global_mouse_position() #paint_canvas.get_local_mouse_position()
|
||||
canvas_position = paint_canvas.rect_global_position
|
||||
canvas_mouse_position = Vector2(mouse_position.x - canvas_position.x, mouse_position.y - canvas_position.y)
|
||||
if is_mouse_in_canvas():
|
||||
|
||||
if is_mouse_in_canvas() && paint_canvas.mouse_on_top:
|
||||
cell_mouse_position = Vector2(
|
||||
floor(canvas_mouse_position.x / grid_size),
|
||||
floor(canvas_mouse_position.y / grid_size))
|
||||
cell_color = paint_canvas.get_pixel(cell_mouse_position.x, cell_mouse_position.y)
|
||||
|
||||
update_text_info()
|
||||
|
||||
# if not is_mouse_in_canvas():
|
||||
@ -213,7 +215,7 @@ func _process(delta):
|
||||
# paint_canvas.update()
|
||||
# paint_canvas.tool_layer.update_texture()
|
||||
# else:
|
||||
if is_mouse_in_canvas():
|
||||
if is_mouse_in_canvas() && paint_canvas.mouse_on_top:
|
||||
if not paint_canvas.is_active_layer_locked():
|
||||
if is_position_in_canvas(get_global_mouse_position()) or \
|
||||
is_position_in_canvas(_last_mouse_pos_canvas_area):
|
||||
|
22
game/addons/Godoxel/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020 cobrapitz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
17
game/addons/Godoxel/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Godoxel (image Editor) v0.1
|
||||
###### (Godot-Pixel Image Editor)
|
||||
|
||||
|
||||
Godoxel is an image editor for Godot, that can be used inside the editor.
|
||||
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
* Has basic pixel editor functionality
|
||||
* Save/Load
|
||||
* Multiple layers (can be locked/hidden)
|
||||
* Tools: Pencil, lighten/darken, rectangle/line, fill, ...
|
||||
|
||||
---
|
||||
###### For feature proposals or occuring problems, please write an issue or message me on Discord cobrapitz#2872
|
@ -29,7 +29,7 @@ func make_visible(visible):
|
||||
|
||||
|
||||
func get_plugin_name():
|
||||
return "Godoxel"
|
||||
return "Paint"
|
||||
|
||||
|
||||
func get_plugin_icon():
|
||||
|
4
game/addons/addon_versions
Normal file
@ -0,0 +1,4 @@
|
||||
Godotxel 6e3b61c2887e51c767d0c2417e0b293a35f904ac from https://github.com/aaronfranke/GraphicsEditor
|
||||
godot-plugin-refresher e2b12f448b9fc112fd0f4acdc6de8df6180b464e from https://github.com/godot-extended-libraries/godot-plugin-refresher
|
||||
godot-color-palette 5fe5d6b2b7c1ee82868ed2c107ecc93809353a33 from https://github.com/EricEzaM/godot-color-palette
|
||||
|
127
game/addons/color-palette/ColorPaletteContainer.gd
Normal file
@ -0,0 +1,127 @@
|
||||
tool
|
||||
extends PanelContainer
|
||||
|
||||
signal palette_updated
|
||||
signal palette_color_selected(palette, color_index)
|
||||
signal palette_color_deleted(palette, color_index)
|
||||
signal container_selected(container_object)
|
||||
|
||||
onready var btn_load_to_picker = $MarginContainer/VBoxContainer/HBoxContainer/BtnLoadToPicker
|
||||
onready var btn_update_from_picker = $MarginContainer/VBoxContainer/HBoxContainer/BtnUpdateFromPicker
|
||||
onready var name_label = $MarginContainer/VBoxContainer/HBoxContainer/PaletteName
|
||||
onready var grid = $MarginContainer/VBoxContainer/PaletteTileContainer/TileContainer
|
||||
|
||||
var palette: Palette
|
||||
var undoredo: UndoRedo
|
||||
var selected: bool = false setget set_selected
|
||||
|
||||
|
||||
func _ready():
|
||||
btn_load_to_picker.connect("pressed", self, "load_to_picker")
|
||||
btn_update_from_picker.connect("pressed", self, "update_from_picker")
|
||||
grid.connect("grid_item_reordered", self, "_grid_item_reordered")
|
||||
|
||||
# Base settings for all color rects are set in the color tile class
|
||||
var cr = ColorTile.new()
|
||||
|
||||
if palette:
|
||||
name_label.text = palette.name
|
||||
name_label.hint_tooltip = palette.comments
|
||||
for c in palette.colors:
|
||||
# Color rect instance properties
|
||||
var cri = cr.duplicate()
|
||||
cri.color = c
|
||||
cri.connect("tile_selected", self, "_on_tile_selected")
|
||||
cri.connect("tile_deleted", self, "_on_tile_deleted")
|
||||
grid.add_child(cri)
|
||||
|
||||
func load_to_picker():
|
||||
var new_picker_presets: PoolColorArray
|
||||
|
||||
for c in palette.colors:
|
||||
new_picker_presets.append(c)
|
||||
|
||||
# Hack?
|
||||
var ep = EditorPlugin.new()
|
||||
ep.get_editor_interface() \
|
||||
.get_editor_settings() \
|
||||
.set_project_metadata("color_picker", "presets", new_picker_presets)
|
||||
ep.free()
|
||||
|
||||
|
||||
func update_from_picker():
|
||||
var ep = EditorPlugin.new()
|
||||
var colors: PoolColorArray = ep.get_editor_interface() \
|
||||
.get_editor_settings() \
|
||||
.get_project_metadata("color_picker", "presets")
|
||||
|
||||
palette.colors.clear()
|
||||
for c in colors:
|
||||
palette.add_color(c)
|
||||
|
||||
palette.save()
|
||||
|
||||
ep.free()
|
||||
|
||||
emit_signal("palette_updated")
|
||||
|
||||
|
||||
func _grid_item_reordered(p_index_from: int, p_index_to: int) -> void:
|
||||
undoredo.create_action("Reorder Palette %s" % palette.name)
|
||||
|
||||
# To do, move from "from" to "to"
|
||||
undoredo.add_do_method(palette, "reorder_color", p_index_from, p_index_to)
|
||||
undoredo.add_do_method(palette, "save")
|
||||
undoredo.add_do_method(self, "emit_signal", "palette_updated")
|
||||
undoredo.add_do_method(self, "emit_signal", "palette_color_selected", palette, p_index_to)
|
||||
|
||||
# To undo, just reverse the positions!
|
||||
undoredo.add_undo_method(palette, "reorder_color", p_index_to, p_index_from)
|
||||
undoredo.add_undo_method(palette, "save")
|
||||
undoredo.add_undo_method(self, "emit_signal", "palette_updated")
|
||||
undoredo.add_undo_method(self, "emit_signal", "palette_color_selected", palette, p_index_from)
|
||||
|
||||
undoredo.commit_action()
|
||||
|
||||
|
||||
# Bubble the event up the tree
|
||||
func _on_tile_selected(index):
|
||||
emit_signal("palette_color_selected", palette, index)
|
||||
|
||||
|
||||
func _on_tile_deleted(index):
|
||||
var original_color = palette.colors[index]
|
||||
|
||||
undoredo.create_action("Delete Color %s from Palette %s" % [original_color.to_html(), palette.name])
|
||||
|
||||
# To do, move from "from" to "to"
|
||||
undoredo.add_do_method(palette, "remove_color", index)
|
||||
undoredo.add_do_method(palette, "save")
|
||||
undoredo.add_do_method(self, "emit_signal", "palette_updated")
|
||||
|
||||
# To undo, just reverse the positions!
|
||||
undoredo.add_undo_method(palette, "add_color", original_color, index)
|
||||
undoredo.add_undo_method(palette, "save")
|
||||
undoredo.add_undo_method(self, "emit_signal", "palette_updated")
|
||||
|
||||
undoredo.commit_action()
|
||||
|
||||
|
||||
func set_selected(value: bool) -> void:
|
||||
selected = value
|
||||
if selected:
|
||||
var sb: StyleBoxFlat = get_stylebox("panel").duplicate()
|
||||
sb.bg_color = Color("#2c3141")
|
||||
add_stylebox_override("panel", sb)
|
||||
emit_signal("container_selected", self)
|
||||
else:
|
||||
var sb: StyleBoxFlat = get_stylebox("panel").duplicate()
|
||||
sb.bg_color = Color(0.15, 0.17, 0.23)
|
||||
add_stylebox_override("panel", sb)
|
||||
|
||||
|
||||
func _gui_input(event):
|
||||
if (event is InputEventMouseButton and
|
||||
event.get_button_index() == 1 and
|
||||
event.is_pressed()):
|
||||
self.selected = true
|
96
game/addons/color-palette/ColorPaletteContainer.tscn
Normal file
@ -0,0 +1,96 @@
|
||||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://addons/color-palette/TileContainer.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/color-palette/utilities/EditorTheme.tres" type="Theme" id=2]
|
||||
[ext_resource path="res://addons/color-palette/ColorPaletteContainer.gd" type="Script" id=4]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=1]
|
||||
bg_color = Color( 0.14902, 0.172549, 0.231373, 1 )
|
||||
border_width_left = 1
|
||||
border_width_top = 1
|
||||
border_width_right = 1
|
||||
border_width_bottom = 1
|
||||
border_color = Color( 0.0980392, 0.113725, 0.152941, 1 )
|
||||
|
||||
[node name="ColorPaletteContainer" type="PanelContainer"]
|
||||
margin_right = 494.0
|
||||
margin_bottom = 152.0
|
||||
theme = ExtResource( 2 )
|
||||
custom_styles/panel = SubResource( 1 )
|
||||
script = ExtResource( 4 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
margin_left = 1.0
|
||||
margin_top = 1.0
|
||||
margin_right = 493.0
|
||||
margin_bottom = 151.0
|
||||
mouse_filter = 1
|
||||
custom_constants/margin_right = 3
|
||||
custom_constants/margin_top = 3
|
||||
custom_constants/margin_left = 3
|
||||
custom_constants/margin_bottom = 3
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
|
||||
margin_left = 3.0
|
||||
margin_top = 3.0
|
||||
margin_right = 489.0
|
||||
margin_bottom = 147.0
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
|
||||
margin_right = 486.0
|
||||
margin_bottom = 22.0
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="PaletteName" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
margin_right = 95.0
|
||||
margin_bottom = 22.0
|
||||
custom_colors/font_color = Color( 0.576471, 0.576471, 0.576471, 1 )
|
||||
text = "Palette Name"
|
||||
|
||||
[node name="Spacer" type="Control" parent="MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
margin_left = 99.0
|
||||
margin_right = 226.0
|
||||
margin_bottom = 22.0
|
||||
mouse_filter = 1
|
||||
size_flags_horizontal = 3
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="BtnLoadToPicker" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
margin_left = 230.0
|
||||
margin_right = 344.0
|
||||
margin_bottom = 22.0
|
||||
hint_tooltip = "Loads the palette into the Color Picker presets (in your editor settings) so you can use these colors in all color selection dialogs."
|
||||
text = "Load into Picker"
|
||||
|
||||
[node name="BtnUpdateFromPicker" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
margin_left = 348.0
|
||||
margin_right = 486.0
|
||||
margin_bottom = 22.0
|
||||
hint_tooltip = "Replaces the palette colors with whatever you have in your color picker presets."
|
||||
custom_colors/font_color_disabled = Color( 0, 0, 0, 1 )
|
||||
text = "Update From Picker"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="MarginContainer/VBoxContainer"]
|
||||
margin_top = 26.0
|
||||
margin_right = 486.0
|
||||
margin_bottom = 26.0
|
||||
mouse_filter = 1
|
||||
custom_constants/separation = 0
|
||||
|
||||
[node name="PaletteTileContainer" type="MarginContainer" parent="MarginContainer/VBoxContainer"]
|
||||
margin_top = 30.0
|
||||
margin_right = 486.0
|
||||
margin_bottom = 30.0
|
||||
mouse_filter = 1
|
||||
|
||||
[node name="TileContainer" type="Container" parent="MarginContainer/VBoxContainer/PaletteTileContainer"]
|
||||
margin_right = 486.0
|
||||
mouse_filter = 1
|
||||
script = ExtResource( 1 )
|
127
game/addons/color-palette/ColorPaletteManager.gd
Normal file
@ -0,0 +1,127 @@
|
||||
tool
|
||||
extends MarginContainer
|
||||
|
||||
# Palette list
|
||||
onready var refresh_list_button = $HBoxContainer/ColorPaletteContainer/OptionsContainer/RefreshList
|
||||
onready var palette_list = $HBoxContainer/ColorPaletteContainer/PaletteListScroll/PaletteList
|
||||
# Options
|
||||
onready var palette_dir_le = $HBoxContainer/ColorPaletteContainer/OptionsContainer/PaletteDirectory
|
||||
onready var new_palette_name_le = $HBoxContainer/ColorPaletteContainer/OptionsContainer/NewPaletteName
|
||||
onready var new_palette_button = $HBoxContainer/ColorPaletteContainer/OptionsContainer/NewPalette
|
||||
onready var open_palette_dir_button = $HBoxContainer/ColorPaletteContainer/OptionsContainer/OpenPaletteDirectory
|
||||
# Color Editor
|
||||
onready var color_picker = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/ColorPicker
|
||||
onready var color_preview_rect = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer/SelectedColorRect
|
||||
onready var color_preview_label = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/SelectedColorLabel
|
||||
onready var apply_color_changed_button = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer/ApplyChanges
|
||||
onready var new_color_rect = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer/NewColorRect
|
||||
onready var new_color_button = $HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer/AddNewColor
|
||||
|
||||
var palette_container = preload("res://addons/color-palette/ColorPaletteContainer.tscn")
|
||||
|
||||
var palettes: Array # of Palette
|
||||
var undoredo: UndoRedo # passed from EditorPlugin
|
||||
|
||||
var selected_palette: Palette
|
||||
var selected_color_index: int
|
||||
|
||||
func _ready():
|
||||
refresh_palettes()
|
||||
refresh_list_button.connect("pressed", self, "refresh_palettes")
|
||||
apply_color_changed_button.connect("pressed", self, "_apply_new_color_to_selected_palette")
|
||||
new_palette_button.connect("pressed", self, "_create_new_palette")
|
||||
color_picker.connect("color_changed", new_color_rect, "set_frame_color")
|
||||
new_color_button.connect("pressed", self, "_add_color_to_selected_palette")
|
||||
open_palette_dir_button.connect("pressed", self, "_open_dir_in_file_manager")
|
||||
|
||||
# Clear the palette list, load the gpl files and populate the list again
|
||||
func refresh_palettes():
|
||||
palettes.clear()
|
||||
for plc in palette_list.get_children():
|
||||
palette_list.remove_child(plc)
|
||||
|
||||
# Ensure trailing slash
|
||||
if not palette_dir_le.text.ends_with("/"):
|
||||
palette_dir_le.text += "/"
|
||||
|
||||
var gpl_files = PaletteImporter.get_gpl_files(palette_dir_le.text)
|
||||
|
||||
for i in gpl_files:
|
||||
palettes.append(PaletteImporter.import_gpl(i))
|
||||
|
||||
for p in palettes:
|
||||
var pc = palette_container.instance()
|
||||
pc.palette = p
|
||||
pc.undoredo = undoredo
|
||||
if selected_palette:
|
||||
pc.selected = true if pc.palette.name == selected_palette.name else false
|
||||
pc.connect("palette_updated", self, "refresh_palettes")
|
||||
pc.connect("palette_color_selected", self, "_on_palette_color_selected")
|
||||
pc.connect("container_selected", self, "_on_palette_container_selected")
|
||||
palette_list.add_child(pc)
|
||||
|
||||
|
||||
func _on_palette_color_selected(palette: Palette, index: int):
|
||||
color_preview_label.text = ("%s (Color #%s)" % [palette.name, index+1])
|
||||
color_preview_rect.color = palette.colors[index]
|
||||
color_picker.color = palette.colors[index]
|
||||
new_color_rect.color = palette.colors[index]
|
||||
|
||||
selected_palette = palette
|
||||
selected_color_index = index
|
||||
|
||||
|
||||
func _apply_new_color_to_selected_palette() -> void:
|
||||
# Check that we can actually apply before doing so
|
||||
var size = selected_palette.colors.size()
|
||||
if size == 0 or selected_color_index >= size:
|
||||
return
|
||||
|
||||
var new_color = color_picker.color
|
||||
var original_color = selected_palette.colors[selected_color_index]
|
||||
|
||||
undoredo.create_action("Change Palette Color")
|
||||
undoredo.add_do_method(selected_palette, "change_color", selected_color_index, new_color)
|
||||
undoredo.add_do_method(selected_palette, "save")
|
||||
undoredo.add_do_method(self, "refresh_palettes")
|
||||
|
||||
undoredo.add_undo_method(selected_palette, "change_color", selected_color_index, original_color)
|
||||
undoredo.add_undo_method(selected_palette, "save")
|
||||
undoredo.add_undo_method(self, "refresh_palettes")
|
||||
undoredo.commit_action()
|
||||
|
||||
|
||||
func _create_new_palette() -> void:
|
||||
if new_palette_name_le.text.strip_edges().length() > 0:
|
||||
var palette = Palette.new()
|
||||
palette.path = palette_dir_le.text + new_palette_name_le.text + ".gpl"
|
||||
palette.save()
|
||||
refresh_palettes()
|
||||
else:
|
||||
push_error("Name cannot be blank")
|
||||
|
||||
|
||||
func _on_palette_container_selected(container: Control) -> void:
|
||||
for pc in palette_list.get_children():
|
||||
if pc != container:
|
||||
pc.selected = false
|
||||
|
||||
selected_palette = container.palette
|
||||
selected_color_index = 0
|
||||
color_preview_label.text = ("%s (No Color Selected)" % selected_palette.name)
|
||||
|
||||
|
||||
func _add_color_to_selected_palette() -> void:
|
||||
if selected_palette != null:
|
||||
selected_palette.add_color(color_picker.color)
|
||||
selected_palette.save()
|
||||
refresh_palettes()
|
||||
|
||||
|
||||
func _open_dir_in_file_manager():
|
||||
var dir := Directory.new()
|
||||
var path = ProjectSettings.globalize_path(palette_dir_le.text)
|
||||
if dir.dir_exists(path):
|
||||
OS.shell_open(path)
|
||||
else:
|
||||
push_error("Invalid directory.")
|
214
game/addons/color-palette/ColorPaletteManager.tscn
Normal file
@ -0,0 +1,214 @@
|
||||
[gd_scene load_steps=8 format=2]
|
||||
|
||||
[ext_resource path="res://addons/color-palette/utilities/EditorTheme.tres" type="Theme" id=1]
|
||||
[ext_resource path="res://addons/color-palette/ColorPaletteManager.gd" type="Script" id=2]
|
||||
[ext_resource path="res://addons/color-palette/icons/Add.svg" type="Texture" id=3]
|
||||
[ext_resource path="res://addons/color-palette/icons/Reload.svg" type="Texture" id=4]
|
||||
[ext_resource path="res://addons/color-palette/icons/Override.svg" type="Texture" id=5]
|
||||
[ext_resource path="res://addons/color-palette/icons/Filesystem.svg" type="Texture" id=6]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=1]
|
||||
bg_color = Color( 0.180392, 0.207843, 0.278431, 1 )
|
||||
border_width_left = 1
|
||||
border_width_top = 1
|
||||
border_width_right = 1
|
||||
border_width_bottom = 1
|
||||
border_color = Color( 0.137255, 0.160784, 0.215686, 1 )
|
||||
|
||||
[node name="ColorPaletteManager" type="MarginContainer"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
rect_min_size = Vector2( 0, 340 )
|
||||
theme = ExtResource( 1 )
|
||||
custom_constants/margin_right = 5
|
||||
custom_constants/margin_top = 5
|
||||
custom_constants/margin_left = 5
|
||||
custom_constants/margin_bottom = 5
|
||||
script = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||
margin_left = 5.0
|
||||
margin_top = 5.0
|
||||
margin_right = 1019.0
|
||||
margin_bottom = 595.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="ColorPaletteContainer" type="VBoxContainer" parent="HBoxContainer"]
|
||||
margin_right = 695.0
|
||||
margin_bottom = 590.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="OptionsContainer" type="HBoxContainer" parent="HBoxContainer/ColorPaletteContainer"]
|
||||
margin_right = 695.0
|
||||
margin_bottom = 24.0
|
||||
|
||||
[node name="Title" type="Label" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
|
||||
margin_top = 1.0
|
||||
margin_right = 116.0
|
||||
margin_bottom = 23.0
|
||||
text = "Palette Directory"
|
||||
|
||||
[node name="PaletteDirectory" type="LineEdit" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
|
||||
margin_left = 120.0
|
||||
margin_right = 420.0
|
||||
margin_bottom = 24.0
|
||||
rect_min_size = Vector2( 300, 0 )
|
||||
text = "res://addons/color-palette/_palettes/"
|
||||
placeholder_text = "Palette Directory"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="OpenPaletteDirectory" type="Button" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
|
||||
margin_left = 424.0
|
||||
margin_right = 452.0
|
||||
margin_bottom = 24.0
|
||||
hint_tooltip = "Open directory in the File Manager"
|
||||
custom_colors/font_color_disabled = Color( 0.180392, 0.207843, 0.278431, 1 )
|
||||
icon = ExtResource( 6 )
|
||||
|
||||
[node name="Spacer" type="Control" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
|
||||
margin_left = 456.0
|
||||
margin_right = 477.0
|
||||
margin_bottom = 24.0
|
||||
size_flags_horizontal = 3
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="NewPaletteName" type="LineEdit" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
|
||||
margin_left = 481.0
|
||||
margin_right = 631.0
|
||||
margin_bottom = 24.0
|
||||
rect_min_size = Vector2( 150, 0 )
|
||||
placeholder_text = "New Palette Name"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="NewPalette" type="Button" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
|
||||
margin_left = 635.0
|
||||
margin_right = 663.0
|
||||
margin_bottom = 24.0
|
||||
hint_tooltip = "Add new palette (creates new .gpl file on disk)"
|
||||
custom_colors/font_color_disabled = Color( 0.180392, 0.207843, 0.278431, 1 )
|
||||
icon = ExtResource( 3 )
|
||||
|
||||
[node name="RefreshList" type="Button" parent="HBoxContainer/ColorPaletteContainer/OptionsContainer"]
|
||||
margin_left = 667.0
|
||||
margin_right = 695.0
|
||||
margin_bottom = 24.0
|
||||
hint_tooltip = "Reload/Refresh list"
|
||||
custom_colors/font_color_disabled = Color( 0.180392, 0.207843, 0.278431, 1 )
|
||||
icon = ExtResource( 4 )
|
||||
|
||||
[node name="PaletteListScroll" type="ScrollContainer" parent="HBoxContainer/ColorPaletteContainer"]
|
||||
margin_top = 28.0
|
||||
margin_right = 695.0
|
||||
margin_bottom = 590.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
scroll_horizontal_enabled = false
|
||||
|
||||
[node name="PaletteList" type="VBoxContainer" parent="HBoxContainer/ColorPaletteContainer/PaletteListScroll"]
|
||||
margin_right = 695.0
|
||||
margin_bottom = 562.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="ColorEditorContainer" type="PanelContainer" parent="HBoxContainer"]
|
||||
margin_left = 699.0
|
||||
margin_right = 1014.0
|
||||
margin_bottom = 590.0
|
||||
rect_min_size = Vector2( 315, 0 )
|
||||
size_flags_vertical = 3
|
||||
custom_styles/panel = SubResource( 1 )
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="HBoxContainer/ColorEditorContainer"]
|
||||
margin_left = 1.0
|
||||
margin_top = 1.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 589.0
|
||||
custom_constants/margin_right = 5
|
||||
custom_constants/margin_top = 5
|
||||
custom_constants/margin_left = 5
|
||||
custom_constants/margin_bottom = 5
|
||||
|
||||
[node name="Scroll" type="ScrollContainer" parent="HBoxContainer/ColorEditorContainer/Margin"]
|
||||
margin_left = 5.0
|
||||
margin_top = 5.0
|
||||
margin_right = 308.0
|
||||
margin_bottom = 583.0
|
||||
|
||||
[node name="ColorPickerContainer" type="VBoxContainer" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll"]
|
||||
margin_right = 290.0
|
||||
margin_bottom = 492.0
|
||||
|
||||
[node name="SelectedColorLabel" type="Label" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer"]
|
||||
margin_right = 290.0
|
||||
margin_bottom = 22.0
|
||||
text = "Select a palette or color..."
|
||||
autowrap = true
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer"]
|
||||
margin_top = 26.0
|
||||
margin_right = 290.0
|
||||
margin_bottom = 50.0
|
||||
|
||||
[node name="SelectedColorRect" type="ColorRect" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer"]
|
||||
margin_right = 99.0
|
||||
margin_bottom = 24.0
|
||||
rect_min_size = Vector2( 50, 0 )
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Label" type="Label" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer"]
|
||||
margin_left = 103.0
|
||||
margin_top = 1.0
|
||||
margin_right = 119.0
|
||||
margin_bottom = 23.0
|
||||
rect_min_size = Vector2( 16, 0 )
|
||||
text = ">"
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="NewColorRect" type="ColorRect" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer"]
|
||||
margin_left = 123.0
|
||||
margin_right = 222.0
|
||||
margin_bottom = 24.0
|
||||
rect_min_size = Vector2( 50, 0 )
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="ApplyChanges" type="ToolButton" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer"]
|
||||
margin_left = 226.0
|
||||
margin_right = 256.0
|
||||
margin_bottom = 24.0
|
||||
rect_min_size = Vector2( 30, 0 )
|
||||
hint_tooltip = "Replace/Override the existing color with the selected color."
|
||||
theme = ExtResource( 1 )
|
||||
icon = ExtResource( 5 )
|
||||
|
||||
[node name="AddNewColor" type="ToolButton" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer/HBoxContainer"]
|
||||
margin_left = 260.0
|
||||
margin_right = 290.0
|
||||
margin_bottom = 24.0
|
||||
rect_min_size = Vector2( 30, 0 )
|
||||
hint_tooltip = "Add the selected color to the palette"
|
||||
theme = ExtResource( 1 )
|
||||
icon = ExtResource( 3 )
|
||||
|
||||
[node name="ColorPicker" type="ColorPicker" parent="HBoxContainer/ColorEditorContainer/Margin/Scroll/ColorPickerContainer"]
|
||||
margin_top = 54.0
|
||||
margin_right = 290.0
|
||||
margin_bottom = 492.0
|
||||
presets_enabled = false
|
||||
presets_visible = false
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
28
game/addons/color-palette/ColorTile.gd
Normal file
@ -0,0 +1,28 @@
|
||||
tool
|
||||
class_name ColorTile
|
||||
extends ColorRect
|
||||
|
||||
signal tile_deleted(index)
|
||||
signal tile_selected(index)
|
||||
|
||||
onready var parent = get_parent()
|
||||
|
||||
var dragging: bool = false
|
||||
|
||||
func _ready():
|
||||
rect_min_size = Vector2(30,30)
|
||||
mouse_filter = MOUSE_FILTER_PASS
|
||||
|
||||
func _gui_input(event):
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == BUTTON_LEFT and event.is_pressed():
|
||||
parent.dragging = self
|
||||
parent.drag_start_index = get_index()
|
||||
emit_signal("tile_selected", get_index())
|
||||
accept_event()
|
||||
return
|
||||
if event.button_index == BUTTON_RIGHT and event.is_pressed():
|
||||
emit_signal("tile_deleted", get_index())
|
||||
accept_event()
|
||||
return
|
||||
|
6
game/addons/color-palette/GridContainer.gd
Normal file
@ -0,0 +1,6 @@
|
||||
tool
|
||||
extends GridContainer
|
||||
|
||||
|
||||
func _get_minimum_size():
|
||||
return Vector2.ZERO
|
21
game/addons/color-palette/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Eric M
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
63
game/addons/color-palette/Palette.gd
Normal file
@ -0,0 +1,63 @@
|
||||
tool
|
||||
class_name Palette
|
||||
extends Reference
|
||||
|
||||
var name: String = "Palette"
|
||||
var colors: Array = [] # of Color
|
||||
var comments: String = ""
|
||||
var path: String = ""
|
||||
|
||||
func add_color(p_color : Color, p_index: int = -1) -> void:
|
||||
if p_index != -1:
|
||||
colors.insert(p_index, p_color)
|
||||
else:
|
||||
colors.append(p_color)
|
||||
|
||||
|
||||
func change_color(p_index: int, p_color: Color) -> void:
|
||||
colors[p_index] = p_color
|
||||
|
||||
|
||||
func reorder_color(p_index_from: int, p_index_to: int):
|
||||
if p_index_from == p_index_to:
|
||||
return
|
||||
|
||||
var moving_color = colors[p_index_from]
|
||||
if p_index_from < p_index_to:
|
||||
colors.remove(p_index_from)
|
||||
colors.insert(p_index_to, moving_color)
|
||||
|
||||
if p_index_from > p_index_to:
|
||||
colors.remove(p_index_from)
|
||||
colors.insert(p_index_to, moving_color)
|
||||
|
||||
|
||||
func remove_color(p_index: int):
|
||||
colors.remove(p_index)
|
||||
|
||||
|
||||
func save():
|
||||
if path.ends_with(".gpl") == false:
|
||||
push_error("To export gpl, file name must end in .gpl")
|
||||
return
|
||||
|
||||
var file = File.new()
|
||||
file.open(path, file.WRITE)
|
||||
file.store_line("GIMP Palette")
|
||||
|
||||
var comment_lines = comments.split("\n")
|
||||
for cl in comment_lines:
|
||||
file.store_line("# " + cl)
|
||||
|
||||
for c in colors:
|
||||
var color_data = [
|
||||
str(c.r8),
|
||||
str(c.g8),
|
||||
str(c.b8),
|
||||
"Untitled"
|
||||
]
|
||||
|
||||
var line = PoolStringArray(color_data).join(" ")
|
||||
file.store_line(line)
|
||||
|
||||
file.close()
|
26
game/addons/color-palette/PaletteColor.gd
Normal file
@ -0,0 +1,26 @@
|
||||
# NOT USED
|
||||
# Currently not used in order to simplify the addon
|
||||
# May be used at a later date
|
||||
|
||||
|
||||
#tool
|
||||
#class_name PaletteColor
|
||||
#extends Reference
|
||||
#
|
||||
#var color: Color = Color.black setget _set_color
|
||||
#var data: String = "" setget _set_data
|
||||
#var name: String = "Untitled"
|
||||
#
|
||||
#func _init(p_color: Color, p_name: String):
|
||||
# self.color = p_color
|
||||
# self.name = p_name
|
||||
#
|
||||
#
|
||||
#func _set_color(p_color):
|
||||
# color = p_color
|
||||
# data = color.to_html(true)
|
||||
#
|
||||
#
|
||||
#func _set_data(p_data):
|
||||
# data = p_data
|
||||
# color = Color(p_data)
|
73
game/addons/color-palette/PaletteImporter.gd
Normal file
@ -0,0 +1,73 @@
|
||||
tool
|
||||
class_name PaletteImporter
|
||||
extends Reference
|
||||
|
||||
# Adapted from Github -> Orama-Interactive/Pixelorama/src/Autoload/Import.gd
|
||||
static func import_gpl(path : String) -> Palette:
|
||||
var color_line_regex = RegEx.new()
|
||||
color_line_regex.compile("(?<red>[0-9]{1,3})[ \t]+(?<green>[0-9]{1,3})[ \t]+(?<blue>[0-9]{1,3})")
|
||||
|
||||
var result : Palette = null
|
||||
|
||||
var file = File.new()
|
||||
if file.file_exists(path):
|
||||
file.open(path, File.READ)
|
||||
var text = file.get_as_text()
|
||||
var lines = text.split('\n')
|
||||
var line_number := 0
|
||||
var comments := ""
|
||||
for line in lines:
|
||||
line = line.lstrip(" ")
|
||||
# Check if valid Gimp Palette Library file
|
||||
if line_number == 0:
|
||||
if line != "GIMP Palette":
|
||||
push_error("File \"%s\" is not a valid GIMP Palette." % path)
|
||||
break
|
||||
else:
|
||||
result = Palette.new()
|
||||
result.path = path
|
||||
var name_start = path.find_last('/') + 1
|
||||
var name_end = path.find_last('.')
|
||||
if name_end > name_start:
|
||||
result.name = path.substr(name_start, name_end - name_start)
|
||||
# Comments
|
||||
elif line.begins_with('#'):
|
||||
comments += line.trim_prefix('#') + '\n'
|
||||
elif not line.empty():
|
||||
var matches = color_line_regex.search(line)
|
||||
if matches:
|
||||
var red: float = matches.get_string("red").to_float() / 255.0
|
||||
var green: float = matches.get_string("green").to_float() / 255.0
|
||||
var blue: float = matches.get_string("blue").to_float() / 255.0
|
||||
var color = Color(red, green, blue)
|
||||
result.add_color(color)
|
||||
else:
|
||||
push_error("Unable to parse line %s with content: %s" % [line_number + 1, line])
|
||||
|
||||
line_number += 1
|
||||
|
||||
if result:
|
||||
result.comments = comments
|
||||
file.close()
|
||||
else:
|
||||
push_error("File \"%s\" does not exist." % path)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
# Get all gpl files in a path
|
||||
static func get_gpl_files(path) -> Array:
|
||||
var files = []
|
||||
|
||||
var dir = Directory.new()
|
||||
if dir.open(path) == OK:
|
||||
dir.list_dir_begin()
|
||||
var file_name = dir.get_next()
|
||||
while file_name != "":
|
||||
if !dir.current_is_dir() and file_name.ends_with(".gpl"):
|
||||
files.append(path + file_name)
|
||||
file_name = dir.get_next()
|
||||
else:
|
||||
print("An error occurred when trying to access the color palette path")
|
||||
|
||||
return files
|
28
game/addons/color-palette/TileContainer.gd
Normal file
@ -0,0 +1,28 @@
|
||||
tool
|
||||
extends FlexGridContainer
|
||||
|
||||
signal grid_item_reordered(index_from, index_to)
|
||||
|
||||
var dragging: ColorRect = null
|
||||
var drag_start_index = -1
|
||||
|
||||
func _gui_input(event):
|
||||
if event is InputEventMouseMotion and dragging != null:
|
||||
# Move the color rect as the user drags it for a live preview
|
||||
var mp = event.position
|
||||
for c in get_children():
|
||||
c = c as ColorRect
|
||||
if c.get_rect().has_point(mp):
|
||||
move_child(dragging, c.get_index())
|
||||
|
||||
|
||||
# When dragging finished
|
||||
if (event is InputEventMouseButton and
|
||||
dragging != null and
|
||||
event.get_button_index() == 1 and
|
||||
event.is_pressed() == false):
|
||||
emit_signal("grid_item_reordered",
|
||||
drag_start_index,
|
||||
dragging.get_index())
|
||||
|
||||
dragging = null
|
8
game/addons/color-palette/_palettes/MyNewPalette.gpl
Normal file
@ -0,0 +1,8 @@
|
||||
GIMP Palette
|
||||
#
|
||||
#
|
||||
255 255 255 Untitled
|
||||
0 41 255 Untitled
|
||||
255 0 0 Untitled
|
||||
255 143 0 Untitled
|
||||
0 183 255 Untitled
|
1
game/addons/color-palette/icons/Add.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v6h-6v2h6v6h2v-6h6v-2h-6v-6z" fill="#e0e0e0"/></svg>
|
After Width: | Height: | Size: 148 B |
34
game/addons/color-palette/icons/Add.svg.import
Normal file
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/Add.svg-428dcdfc55a08195b5467eb795512436.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/color-palette/icons/Add.svg"
|
||||
dest_files=[ "res://.import/Add.svg-428dcdfc55a08195b5467eb795512436.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
1
game/addons/color-palette/icons/Filesystem.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v5h2v8h1 5v1h6v-3h-6v1h-5v-4h5v1h6v-3h-6v1h-5v-2h3v-4h-2l-1-1z" fill="#e0e0e0"/></svg>
|
After Width: | Height: | Size: 182 B |
34
game/addons/color-palette/icons/Filesystem.svg.import
Normal file
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/Filesystem.svg-a134cae0dc3a9d19430b34d0c549fcba.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/color-palette/icons/Filesystem.svg"
|
||||
dest_files=[ "res://.import/Filesystem.svg-a134cae0dc3a9d19430b34d0c549fcba.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
1
game/addons/color-palette/icons/Override.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.108 0-2 .89199-2 2v1h4v-1h2v1h4v-1c0-1.108-.89199-2-2-2zm-2 5c-1.108 0-2 .89199-2 2v5c0 1.108.89199 2 2 2h10c1.108 0 2-.89199 2-2v-5c0-1.108-.89199-2-2-2h-4v3h2l-3 4-3-4h2v-3z" fill="#e0e0e0"/></svg>
|
After Width: | Height: | Size: 299 B |
34
game/addons/color-palette/icons/Override.svg.import
Normal file
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/Override.svg-90676568ad3b2265d0058068c0ba9a61.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/color-palette/icons/Override.svg"
|
||||
dest_files=[ "res://.import/Override.svg-90676568ad3b2265d0058068c0ba9a61.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
1
game/addons/color-palette/icons/Reload.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 -1036.4)"><path d="m9 2a6 6 0 0 0 -6 6h2a4 4 0 0 1 4-4 4 4 0 0 1 4 4 4 4 0 0 1 -4 4v2a6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" transform="translate(0 1036.4)"/><path d="m4.118 1048.3-1.6771-.9683-1.6771-.9682 1.6771-.9683 1.6771-.9682-.0000001 1.9365z" transform="matrix(0 -1.1926 1.5492 0 -1617 1049.3)"/></g></svg>
|
After Width: | Height: | Size: 452 B |
34
game/addons/color-palette/icons/Reload.svg.import
Normal file
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/Reload.svg-ef242b4c91f9b3786c396da13f6d0ca0.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/color-palette/icons/Reload.svg"
|
||||
dest_files=[ "res://.import/Reload.svg-ef242b4c91f9b3786c396da13f6d0ca0.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
7
game/addons/color-palette/plugin.cfg
Normal file
@ -0,0 +1,7 @@
|
||||
[plugin]
|
||||
|
||||
name="ColorPalette"
|
||||
description="Color palette manager for Godot"
|
||||
author="EricEzaM"
|
||||
version="1.0"
|
||||
script="plugin.gd"
|
14
game/addons/color-palette/plugin.gd
Normal file
@ -0,0 +1,14 @@
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
var cpm
|
||||
|
||||
func _enter_tree():
|
||||
cpm = preload("res://addons/color-palette/ColorPaletteManager.tscn").instance()
|
||||
cpm.undoredo = get_undo_redo()
|
||||
add_control_to_bottom_panel(cpm, "Color Palette")
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
remove_control_from_bottom_panel(cpm)
|
||||
cpm.free()
|
11989
game/addons/color-palette/utilities/EditorTheme.tres
Normal file
178
game/addons/color-palette/utilities/FlexGridContainer.gd
Normal file
@ -0,0 +1,178 @@
|
||||
tool
|
||||
class_name FlexGridContainer, "res://addons/color-palette/utilities/FlexGridContainerIcon.png"
|
||||
extends Container
|
||||
|
||||
|
||||
var columns: int = 1 setget set_columns
|
||||
|
||||
|
||||
func _notification(p_what):
|
||||
match p_what:
|
||||
NOTIFICATION_SORT_CHILDREN:
|
||||
var col_minw: Dictionary # Max of min_width of all controls in each col (indexed by col).
|
||||
var row_minh: Dictionary # Max of min_height of all controls in each row (indexed by row).
|
||||
var col_expanded: Array # Columns which have the SIZE_EXPAND flag set.
|
||||
var row_expanded: Array # Rows which have the SIZE_EXPAND flag set.
|
||||
|
||||
var hsep = get_constant("hseparation", "GridContainer")
|
||||
var vsep = get_constant("vseparation", "GridContainer")
|
||||
|
||||
var min_columns = 1
|
||||
|
||||
if get_child_count() > 0:
|
||||
min_columns = int(floor(rect_size.x / (get_child(0).get_combined_minimum_size().x + hsep)))
|
||||
|
||||
self.columns = min_columns
|
||||
|
||||
var max_col = min(get_child_count(), columns)
|
||||
var max_row = ceil(float(get_child_count()) / float(columns))
|
||||
|
||||
# Compute the per-column/per-row data.
|
||||
var valid_controls_index = 0
|
||||
for i in range(get_child_count()):
|
||||
var c: Control = get_child(i)
|
||||
if !c or !c.is_visible_in_tree():
|
||||
continue
|
||||
|
||||
var row = valid_controls_index / columns
|
||||
var col = valid_controls_index % columns
|
||||
valid_controls_index += 1
|
||||
|
||||
var ms: Vector2 = c.get_combined_minimum_size()
|
||||
if col_minw.has(col):
|
||||
col_minw[col] = max(col_minw[col], ms.x)
|
||||
else:
|
||||
col_minw[col] = ms.x
|
||||
if row_minh.has(row):
|
||||
row_minh[row] = max(row_minh[row], ms.y)
|
||||
else:
|
||||
row_minh[row] = ms.y
|
||||
|
||||
if c.get_h_size_flags() & SIZE_EXPAND:
|
||||
col_expanded.push_front(col)
|
||||
|
||||
if c.get_v_size_flags() & SIZE_EXPAND:
|
||||
row_expanded.push_front(row)
|
||||
|
||||
# Consider all empty columns expanded.
|
||||
for i in range(valid_controls_index, columns):
|
||||
col_expanded.push_front(i)
|
||||
|
||||
# Evaluate the remaining space for expanded columns/rows.
|
||||
var remaining_space: Vector2 = get_size()
|
||||
|
||||
for e in col_minw.keys():
|
||||
if !col_expanded.has(e):
|
||||
remaining_space.x -= col_minw.get(e)
|
||||
|
||||
for e in row_minh.keys():
|
||||
if !row_expanded.has(e):
|
||||
remaining_space.y -= row_minh.get(e)
|
||||
|
||||
remaining_space.y -= vsep * max(max_row - 1, 0)
|
||||
remaining_space.x -= hsep * max(max_col - 1, 0)
|
||||
|
||||
var can_fit = false
|
||||
while !can_fit && col_expanded.size() > 0:
|
||||
# Check if all minwidth constraints are OK if we use the remaining space.
|
||||
can_fit = true
|
||||
var max_index = col_expanded.front()
|
||||
|
||||
for e in col_expanded:
|
||||
if col_minw.has(e):
|
||||
if col_minw[e] > col_minw[max_index]:
|
||||
max_index = e
|
||||
if can_fit && (remaining_space.x / col_expanded.size()) < col_minw[e]:
|
||||
can_fit = false
|
||||
|
||||
# If not, the column with maximum minwidth is not expanded.
|
||||
if (!can_fit):
|
||||
col_expanded.erase(max_index)
|
||||
remaining_space.x -= col_minw[max_index]
|
||||
|
||||
can_fit = false
|
||||
while !can_fit && row_expanded.size() > 0:
|
||||
# Check if all minheight constraints are OK if we use the remaining space.
|
||||
can_fit = true
|
||||
var max_index = row_expanded.front()
|
||||
|
||||
for e in row_expanded:
|
||||
if row_minh[e] > row_minh[max_index]:
|
||||
max_index = e
|
||||
if can_fit && (remaining_space.y / row_expanded.size()) < row_minh[e]:
|
||||
can_fit = false
|
||||
|
||||
# If not, the row with maximum minheight is not expanded.
|
||||
if (!can_fit):
|
||||
row_expanded.erase(max_index)
|
||||
remaining_space.y -= row_minh[max_index]
|
||||
|
||||
# Finally, fit the nodes.
|
||||
var col_expand = remaining_space.x / col_expanded.size() if col_expanded.size() > 0 else 0
|
||||
var row_expand = remaining_space.y / row_expanded.size() if row_expanded.size() > 0 else 0
|
||||
|
||||
var col_ofs = 0
|
||||
var row_ofs = 0
|
||||
|
||||
valid_controls_index = 0
|
||||
for i in range(get_child_count()):
|
||||
var c: Control = get_child(i)
|
||||
if (!c || !c.is_visible_in_tree()):
|
||||
continue
|
||||
var row = valid_controls_index / columns
|
||||
var col = valid_controls_index % columns
|
||||
valid_controls_index += 1
|
||||
|
||||
if (col == 0):
|
||||
col_ofs = 0
|
||||
if (row > 0):
|
||||
row_ofs += (row_expand if row_expanded.has(row - 1) else row_minh[row - 1]) + vsep
|
||||
|
||||
var p = Vector2(col_ofs, row_ofs)
|
||||
var s = Vector2(col_expand if col_expanded.has(col) else col_minw[col], row_expand if row_expanded.has(row) else row_minh[row])
|
||||
|
||||
fit_child_in_rect(c, Rect2(p, s))
|
||||
|
||||
col_ofs += s.x + hsep
|
||||
|
||||
NOTIFICATION_THEME_CHANGED:
|
||||
minimum_size_changed()
|
||||
|
||||
func _get_minimum_size():
|
||||
# Only worry about max height, not width (since it does width automatically)
|
||||
var row_minh: Dictionary
|
||||
|
||||
var vsep = get_constant("vseparation", "GridContainer")
|
||||
|
||||
var max_row = 0
|
||||
|
||||
var valid_controls_index = 0
|
||||
for i in range(get_child_count()):
|
||||
|
||||
var c: Control = get_child(i)
|
||||
if !c or !c.is_visible():
|
||||
continue
|
||||
var row = valid_controls_index / columns
|
||||
valid_controls_index += 1
|
||||
|
||||
var ms = c.get_combined_minimum_size()
|
||||
|
||||
if row_minh.has(row):
|
||||
row_minh[row] = max(row_minh[row], ms.y)
|
||||
else:
|
||||
row_minh[row] = ms.y
|
||||
max_row = max(row, max_row)
|
||||
|
||||
var ms: Vector2
|
||||
|
||||
for e in row_minh.keys():
|
||||
ms.y += row_minh.get(e)
|
||||
|
||||
ms.y += vsep * max_row
|
||||
|
||||
return ms
|
||||
|
||||
|
||||
func set_columns(p_columns: int):
|
||||
columns = p_columns
|
||||
minimum_size_changed()
|
BIN
game/addons/color-palette/utilities/FlexGridContainerIcon.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/FlexGridContainerIcon.png-6e168e671762d83e231247cac0689323.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/color-palette/utilities/FlexGridContainerIcon.png"
|
||||
dest_files=[ "res://.import/FlexGridContainerIcon.png-6e168e671762d83e231247cac0689323.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
107
game/addons/data_manager/_data/settings.tres
Normal file
@ -0,0 +1,107 @@
|
||||
[gd_resource type="Resource" load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/data_manager/resources/data_manager_addon_settings.gd" type="Script" id=1]
|
||||
|
||||
[resource]
|
||||
script = ExtResource( 1 )
|
||||
folder_count = 25
|
||||
folders/0/folder = "."
|
||||
folders/0/header = ""
|
||||
folders/0/name = "Root"
|
||||
folders/0/type = "Resource"
|
||||
folders/1/folder = "entity_skills"
|
||||
folders/1/header = ""
|
||||
folders/1/name = "Skills"
|
||||
folders/1/type = "EntitySkillData"
|
||||
folders/2/folder = "entities"
|
||||
folders/2/header = ""
|
||||
folders/2/name = "Entities"
|
||||
folders/2/type = "EntityData"
|
||||
folders/3/folder = "player_character_data"
|
||||
folders/3/header = ""
|
||||
folders/3/name = "Player Characters"
|
||||
folders/3/type = "EntityData"
|
||||
folders/4/folder = "entity_classes"
|
||||
folders/4/header = ""
|
||||
folders/4/name = "Classes"
|
||||
folders/4/type = "EntityClassData"
|
||||
folders/5/folder = "ai"
|
||||
folders/5/header = ""
|
||||
folders/5/name = "AI"
|
||||
folders/5/type = "AIAction"
|
||||
folders/6/folder = "character_models"
|
||||
folders/6/header = "Models"
|
||||
folders/6/name = "Models"
|
||||
folders/6/type = "MeshDataResource"
|
||||
folders/7/folder = "character_textures"
|
||||
folders/7/header = ""
|
||||
folders/7/name = "Textures"
|
||||
folders/7/type = "Texture"
|
||||
folders/8/folder = "spells"
|
||||
folders/8/header = "Spells"
|
||||
folders/8/name = "Spells"
|
||||
folders/8/type = "Spell"
|
||||
folders/9/folder = "aura_groups"
|
||||
folders/9/header = ""
|
||||
folders/9/name = "Aura Groups"
|
||||
folders/9/type = "AuraGroup"
|
||||
folders/10/folder = "character_specs"
|
||||
folders/10/header = ""
|
||||
folders/10/name = "Specs"
|
||||
folders/10/type = "CharacterSpec"
|
||||
folders/11/folder = "effect_data"
|
||||
folders/11/header = ""
|
||||
folders/11/name = "Effect Datas"
|
||||
folders/11/type = "SpellEffectVisual"
|
||||
folders/12/folder = "world_spells"
|
||||
folders/12/header = ""
|
||||
folders/12/name = "World Spells"
|
||||
folders/12/type = "WorldSpellData"
|
||||
folders/13/folder = "item_templates"
|
||||
folders/13/header = "Items"
|
||||
folders/13/name = "Items"
|
||||
folders/13/type = "ItemTemplate"
|
||||
folders/14/folder = "crafting"
|
||||
folders/14/header = ""
|
||||
folders/14/name = "Craft Recipes"
|
||||
folders/14/type = "CraftRecipe"
|
||||
folders/15/folder = "item_visuals"
|
||||
folders/15/header = ""
|
||||
folders/15/name = "Item Visuals"
|
||||
folders/15/type = "ItemVisual"
|
||||
folders/16/folder = "planets"
|
||||
folders/16/header = "World"
|
||||
folders/16/name = "World"
|
||||
folders/16/type = "World"
|
||||
folders/17/folder = "continents"
|
||||
folders/17/header = ""
|
||||
folders/17/name = "Continents"
|
||||
folders/17/type = "Continent"
|
||||
folders/18/folder = "zones"
|
||||
folders/18/header = ""
|
||||
folders/18/name = "Zones"
|
||||
folders/18/type = "Zone"
|
||||
folders/19/folder = "sub_zones"
|
||||
folders/19/header = ""
|
||||
folders/19/name = "SubZones"
|
||||
folders/19/type = "SubZone"
|
||||
folders/20/folder = "dungeons"
|
||||
folders/20/header = ""
|
||||
folders/20/name = "Dungeons"
|
||||
folders/20/type = "DungeonData"
|
||||
folders/21/folder = "dungeon_rooms"
|
||||
folders/21/header = ""
|
||||
folders/21/name = "Dungeon Rooms"
|
||||
folders/21/type = "DungeonRoomData"
|
||||
folders/22/folder = "basic_models"
|
||||
folders/22/header = ""
|
||||
folders/22/name = "Basic Models"
|
||||
folders/22/type = "MeshDataResource"
|
||||
folders/23/folder = "prop_models"
|
||||
folders/23/header = ""
|
||||
folders/23/name = "Prop Models"
|
||||
folders/23/type = "PackedScene"
|
||||
folders/24/folder = "entity_resources"
|
||||
folders/24/header = "Entities"
|
||||
folders/24/name = "Entity Resources"
|
||||
folders/24/type = "EntityResourceData"
|
Before Width: | Height: | Size: 939 B After Width: | Height: | Size: 939 B |
@ -2,15 +2,15 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/empty.png-d52a27cebe3b559ee5afeb72c926ad8c.stex"
|
||||
path="res://.import/empty.png-7c3c16235e874062c86c346ae86f27bd.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/empty.png"
|
||||
dest_files=[ "res://.import/empty.png-d52a27cebe3b559ee5afeb72c926ad8c.stex" ]
|
||||
source_file="res://addons/data_manager/icons/empty.png"
|
||||
dest_files=[ "res://.import/empty.png-7c3c16235e874062c86c346ae86f27bd.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@ -2,15 +2,15 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/gom.png-7469f830e410a943b31bbb19c8debf4e.stex"
|
||||
path="res://.import/gom.png-7336a5cc19ade9f52daca73cd870ca75.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/gom.png"
|
||||
dest_files=[ "res://.import/gom.png-7469f830e410a943b31bbb19c8debf4e.stex" ]
|
||||
source_file="res://addons/data_manager/icons/gom.png"
|
||||
dest_files=[ "res://.import/gom.png-7336a5cc19ade9f52daca73cd870ca75.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 111 B After Width: | Height: | Size: 111 B |
@ -2,15 +2,15 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_add.png-b78af00c3ee58b2d523f0a86c227a437.stex"
|
||||
path="res://.import/icon_add.png-4936253aec6c83c328ecfe2f83f4abdb.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/icon_add.png"
|
||||
dest_files=[ "res://.import/icon_add.png-b78af00c3ee58b2d523f0a86c227a437.stex" ]
|
||||
source_file="res://addons/data_manager/icons/icon_add.png"
|
||||
dest_files=[ "res://.import/icon_add.png-4936253aec6c83c328ecfe2f83f4abdb.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 248 B After Width: | Height: | Size: 248 B |
@ -2,15 +2,15 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_copy.png-2686b5282d44e971e22e560caf7cb772.stex"
|
||||
path="res://.import/icon_copy.png-b8adcf38019b53173acfa7e965fd19ce.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/icon_copy.png"
|
||||
dest_files=[ "res://.import/icon_copy.png-2686b5282d44e971e22e560caf7cb772.stex" ]
|
||||
source_file="res://addons/data_manager/icons/icon_copy.png"
|
||||
dest_files=[ "res://.import/icon_copy.png-b8adcf38019b53173acfa7e965fd19ce.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 200 B |
@ -2,15 +2,15 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_multi_line.png-5f84bb8f6a38a4a71b359efb46a0f143.stex"
|
||||
path="res://.import/icon_display-name.png-eed428a00d84c6a84e6b1b924bf6b5a5.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/icon_multi_line.png"
|
||||
dest_files=[ "res://.import/icon_multi_line.png-5f84bb8f6a38a4a71b359efb46a0f143.stex" ]
|
||||
source_file="res://addons/data_manager/icons/icon_display-name.png"
|
||||
dest_files=[ "res://.import/icon_display-name.png-eed428a00d84c6a84e6b1b924bf6b5a5.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 167 B After Width: | Height: | Size: 167 B |
@ -2,15 +2,15 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_move_up.png-d4081170c845eac210690228db6a49a8.stex"
|
||||
path="res://.import/icon_duplicate.png-bc9124161be2304f34e2e5292fc9bb72.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/icon_move_up.png"
|
||||
dest_files=[ "res://.import/icon_move_up.png-d4081170c845eac210690228db6a49a8.stex" ]
|
||||
source_file="res://addons/data_manager/icons/icon_duplicate.png"
|
||||
dest_files=[ "res://.import/icon_duplicate.png-bc9124161be2304f34e2e5292fc9bb72.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 346 B |
@ -2,15 +2,15 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_edit.png-2a909a80ec69c874db271f3116b05a4d.stex"
|
||||
path="res://.import/icon_edit.png-8dda7283a7e3e9d8bcd70055bb4af86b.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/icon_edit.png"
|
||||
dest_files=[ "res://.import/icon_edit.png-2a909a80ec69c874db271f3116b05a4d.stex" ]
|
||||
source_file="res://addons/data_manager/icons/icon_edit.png"
|
||||
dest_files=[ "res://.import/icon_edit.png-8dda7283a7e3e9d8bcd70055bb4af86b.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 267 B After Width: | Height: | Size: 267 B |
35
game/addons/data_manager/icons/icon_empty.png.import
Normal file
@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_empty.png-41310ee5e2b51754d7fdd9ccd55dd8bb.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/data_manager/icons/icon_empty.png"
|
||||
dest_files=[ "res://.import/icon_empty.png-41310ee5e2b51754d7fdd9ccd55dd8bb.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
Before Width: | Height: | Size: 170 B After Width: | Height: | Size: 170 B |
@ -2,15 +2,15 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_load.png-2950b376847c4a33baf8e4601a28c79c.stex"
|
||||
path="res://.import/icon_load.png-27103febef60080a6acff2120a3b5382.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/icon_load.png"
|
||||
dest_files=[ "res://.import/icon_load.png-2950b376847c4a33baf8e4601a28c79c.stex" ]
|
||||
source_file="res://addons/data_manager/icons/icon_load.png"
|
||||
dest_files=[ "res://.import/icon_load.png-27103febef60080a6acff2120a3b5382.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 268 B After Width: | Height: | Size: 268 B |
@ -2,15 +2,15 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_options.png-1a80bcf95186ea96b32c86803be399a6.stex"
|
||||
path="res://.import/icon_move_down.png-0a5c510c5cd06b571858d1b2cf7a95cf.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/icon_options.png"
|
||||
dest_files=[ "res://.import/icon_options.png-1a80bcf95186ea96b32c86803be399a6.stex" ]
|
||||
source_file="res://addons/data_manager/icons/icon_move_down.png"
|
||||
dest_files=[ "res://.import/icon_move_down.png-0a5c510c5cd06b571858d1b2cf7a95cf.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 269 B |
35
game/addons/data_manager/icons/icon_move_up.png.import
Normal file
@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_move_up.png-8bbd78f84e89d3ab25e3b699f6e3ba8d.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/data_manager/icons/icon_move_up.png"
|
||||
dest_files=[ "res://.import/icon_move_up.png-8bbd78f84e89d3ab25e3b699f6e3ba8d.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
Before Width: | Height: | Size: 140 B After Width: | Height: | Size: 140 B |
35
game/addons/data_manager/icons/icon_multi_line.png.import
Normal file
@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_multi_line.png-f2116803bfa2e69309bda042fe09ca22.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/data_manager/icons/icon_multi_line.png"
|
||||
dest_files=[ "res://.import/icon_multi_line.png-f2116803bfa2e69309bda042fe09ca22.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
Before Width: | Height: | Size: 392 B After Width: | Height: | Size: 392 B |
35
game/addons/data_manager/icons/icon_options.png.import
Normal file
@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_options.png-8a05079b2f7e729dae53ff1568b6536e.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/data_manager/icons/icon_options.png"
|
||||
dest_files=[ "res://.import/icon_options.png-8a05079b2f7e729dae53ff1568b6536e.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
Before Width: | Height: | Size: 409 B After Width: | Height: | Size: 409 B |
35
game/addons/data_manager/icons/icon_reload_small.png.import
Normal file
@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_reload_small.png-5cfe0f7b7e56d4c9649ddbe472105e0a.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/data_manager/icons/icon_reload_small.png"
|
||||
dest_files=[ "res://.import/icon_reload_small.png-5cfe0f7b7e56d4c9649ddbe472105e0a.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 166 B |
35
game/addons/data_manager/icons/icon_remove.png.import
Normal file
@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_remove.png-cd07d5c1378356af560353bd7a42f342.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/data_manager/icons/icon_remove.png"
|
||||
dest_files=[ "res://.import/icon_remove.png-cd07d5c1378356af560353bd7a42f342.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
Before Width: | Height: | Size: 160 B After Width: | Height: | Size: 160 B |
35
game/addons/data_manager/icons/icon_rename.png.import
Normal file
@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_rename.png-057eb6051ce4bfd5326de785a2ce0780.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/data_manager/icons/icon_rename.png"
|
||||
dest_files=[ "res://.import/icon_rename.png-057eb6051ce4bfd5326de785a2ce0780.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
Before Width: | Height: | Size: 252 B After Width: | Height: | Size: 252 B |
@ -2,15 +2,15 @@
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_save.png-6f4eb3356472677111c577b4fc5fa9fd.stex"
|
||||
path="res://.import/icon_save.png-65939defe113bdfb6174e9451d3fb596.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/icon_save.png"
|
||||
dest_files=[ "res://.import/icon_save.png-6f4eb3356472677111c577b4fc5fa9fd.stex" ]
|
||||
source_file="res://addons/data_manager/icons/icon_save.png"
|
||||
dest_files=[ "res://.import/icon_save.png-65939defe113bdfb6174e9451d3fb596.stex" ]
|
||||
|
||||
[params]
|
||||
|
Before Width: | Height: | Size: 262 B After Width: | Height: | Size: 262 B |
35
game/addons/data_manager/icons/icon_script.png.import
Normal file
@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_script.png-02675c4ec5dd1554ae0ce28638df6a48.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/data_manager/icons/icon_script.png"
|
||||
dest_files=[ "res://.import/icon_script.png-02675c4ec5dd1554ae0ce28638df6a48.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
74
game/addons/data_manager/panels/AddFolderDialog.gd
Normal file
@ -0,0 +1,74 @@
|
||||
tool
|
||||
extends ConfirmationDialog
|
||||
|
||||
const DataManagerAddonSettings = preload("res://addons/data_manager/resources/data_manager_addon_settings.gd")
|
||||
|
||||
var _settings : DataManagerAddonSettings = null
|
||||
var _module = null
|
||||
|
||||
signal folders_created
|
||||
|
||||
func _enter_tree():
|
||||
if !is_connected("confirmed", self, "on_confirmed"):
|
||||
connect("confirmed", self, "on_confirmed")
|
||||
|
||||
func setup() -> void:
|
||||
var entry_container : Control = $ScrollContainer/VBoxContainer
|
||||
|
||||
for ch in entry_container.get_children():
|
||||
ch.queue_free()
|
||||
|
||||
var dir : Directory = Directory.new()
|
||||
|
||||
var label_str : String = "= " + get_module_label_text(_module) + " ="
|
||||
window_title = "Add folder(s) for " + label_str
|
||||
|
||||
var module_dir_base : String = _module.resource_path.get_base_dir()
|
||||
|
||||
for f in _settings.folders:
|
||||
if dir.dir_exists(module_dir_base + "/" + f.folder):
|
||||
continue
|
||||
|
||||
var ecb : CheckBox = CheckBox.new()
|
||||
ecb.text = f.folder + " (" + f.type + ")"
|
||||
ecb.set_meta("folder", f.folder)
|
||||
entry_container.add_child(ecb)
|
||||
|
||||
func on_confirmed() -> void:
|
||||
var entry_container : Control = $ScrollContainer/VBoxContainer
|
||||
|
||||
var dir : Directory = Directory.new()
|
||||
var module_dir_base : String = _module.resource_path.get_base_dir()
|
||||
|
||||
for c in entry_container.get_children():
|
||||
if !(c is CheckBox):
|
||||
continue
|
||||
|
||||
if !c.pressed:
|
||||
continue
|
||||
|
||||
var folder : String = c.get_meta("folder")
|
||||
var d : String = module_dir_base + "/" + folder
|
||||
if !dir.dir_exists(d):
|
||||
dir.make_dir(d)
|
||||
|
||||
emit_signal("folders_created")
|
||||
|
||||
func set_module(module, settings : DataManagerAddonSettings) -> void:
|
||||
_module = module
|
||||
_settings = settings
|
||||
setup()
|
||||
#popup_centered()
|
||||
|
||||
popup_centered()
|
||||
|
||||
func get_module_label_text(module) -> String:
|
||||
var label_str : String = module.resource_name
|
||||
|
||||
if label_str == "":
|
||||
label_str = module.resource_path
|
||||
label_str = label_str.replace("res://", "")
|
||||
label_str = label_str.replace("/game_module.tres", "")
|
||||
label_str = label_str.replace("game_module.tres", "")
|
||||
|
||||
return label_str
|
@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/module_manager/panels/CreateNamePopup.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/data_manager/panels/CreateNamePopup.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[node name="CreateNamePopup" type="ConfirmationDialog"]
|
@ -18,7 +18,9 @@ func set_data(pdata: Resource) -> void:
|
||||
|
||||
if data.has_method("get_text_name"):
|
||||
s += str(data.get_text_name())
|
||||
|
||||
elif data.has_method("get_name"):
|
||||
s += str(data.get_name())
|
||||
|
||||
if data.has_method("get_rank"):
|
||||
s += " (R " + str(data.get_rank()) + ")"
|
||||
|
@ -1,7 +1,6 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/module_manager/panels/HistoryEntry.gd" type="Script" id=1]
|
||||
|
||||
[ext_resource path="res://addons/data_manager/panels/HistoryEntry.gd" type="Script" id=1]
|
||||
|
||||
[node name="HistoryEntry" type="Button"]
|
||||
margin_right = 236.0
|
216
game/addons/data_manager/panels/MainPanel.gd
Normal file
@ -0,0 +1,216 @@
|
||||
tool
|
||||
extends Control
|
||||
|
||||
const DataManagerAddonSettings = preload("res://addons/data_manager/resources/data_manager_addon_settings.gd")
|
||||
const add_icon = preload("res://addons/data_manager/icons/icon_add.png")
|
||||
|
||||
signal inspect_data
|
||||
|
||||
export(PackedScene) var resource_scene : PackedScene
|
||||
export(String) var base_folder : String = "res://"
|
||||
export(NodePath) var main_container : NodePath
|
||||
export(NodePath) var module_entry_container_path : NodePath
|
||||
export(NodePath) var folder_entry_container_path : NodePath
|
||||
|
||||
var _main_container : Node
|
||||
var _resource_scene : Node
|
||||
var _module_entry_container : Node
|
||||
var _folder_entry_container : Node
|
||||
|
||||
var _modules : Array = Array()
|
||||
var _active_modules : Array = Array()
|
||||
var _settings : DataManagerAddonSettings = null
|
||||
|
||||
var _initialized : bool = false
|
||||
var _plugin : EditorPlugin = null
|
||||
|
||||
func _enter_tree():
|
||||
if !is_connected("visibility_changed", self, "on_visibility_changed"):
|
||||
connect("visibility_changed", self, "on_visibility_changed")
|
||||
|
||||
if !$Popups/AddFolderDialog.is_connected("folders_created", self, "on_folders_created"):
|
||||
$Popups/AddFolderDialog.connect("folders_created", self, "on_folders_created")
|
||||
|
||||
func on_visibility_changed():
|
||||
if _plugin && is_visible_in_tree() && !_initialized:
|
||||
_initialized = true
|
||||
load_data()
|
||||
|
||||
func load_data():
|
||||
var dir : Directory = Directory.new()
|
||||
|
||||
_settings = _plugin.settings
|
||||
|
||||
_main_container = get_node(main_container)
|
||||
|
||||
_resource_scene = resource_scene.instance()
|
||||
_main_container.add_child(_resource_scene)
|
||||
_resource_scene.owner = _main_container
|
||||
_resource_scene.connect("inspect_data", self, "inspect_data")
|
||||
|
||||
_module_entry_container = get_node(module_entry_container_path)
|
||||
_folder_entry_container = get_node(folder_entry_container_path)
|
||||
|
||||
generate_module_entry_list()
|
||||
|
||||
func generate_module_entry_list() -> void:
|
||||
for ch in _folder_entry_container.get_children():
|
||||
ch.queue_free()
|
||||
|
||||
load_modules()
|
||||
|
||||
for m in _modules:
|
||||
var label_str : String = get_module_label_text(m)
|
||||
|
||||
var b : Button = Button.new()
|
||||
b.toggle_mode = true
|
||||
b.text = label_str
|
||||
b.set_h_size_flags(SIZE_EXPAND_FILL)
|
||||
b.connect("toggled", self, "on_module_entry_button_toggled", [ m ])
|
||||
_module_entry_container.add_child(b)
|
||||
|
||||
func generate_folder_entry_list() -> void:
|
||||
for ch in _folder_entry_container.get_children():
|
||||
ch.queue_free()
|
||||
|
||||
var dir : Directory = Directory.new()
|
||||
|
||||
for i in range(_active_modules.size()):
|
||||
var module = _active_modules[i]
|
||||
|
||||
if i > 0:
|
||||
_folder_entry_container.add_child(HSeparator.new())
|
||||
|
||||
var label_str : String = "= " + get_module_label_text(module) + " ="
|
||||
var mlabel : Label = Label.new()
|
||||
mlabel.text = label_str
|
||||
mlabel.align = HALIGN_CENTER
|
||||
mlabel.valign = VALIGN_CENTER
|
||||
_folder_entry_container.add_child(mlabel)
|
||||
var module_dir_base : String = module.resource_path.get_base_dir()
|
||||
|
||||
var index = 0
|
||||
for j in range(_settings.get_folder_count()):
|
||||
var f = _settings.folder_get(j)
|
||||
var full_folder_path : String = module_dir_base + "/" + f.folder
|
||||
|
||||
if !dir.dir_exists(full_folder_path):
|
||||
continue
|
||||
|
||||
if f.header != "":
|
||||
var h : Label = Label.new()
|
||||
|
||||
_folder_entry_container.add_child(h)
|
||||
h.text = f.header
|
||||
|
||||
var fe : Button = Button.new()
|
||||
fe.text = f.name
|
||||
fe.connect("pressed", self, "on_folder_entry_button_pressed", [ module, full_folder_path, j ])
|
||||
_folder_entry_container.add_child(fe)
|
||||
|
||||
index += 1
|
||||
|
||||
var bsep : Label = Label.new()
|
||||
bsep.text = "Actions"
|
||||
_folder_entry_container.add_child(bsep)
|
||||
|
||||
var add_folder_button : Button = Button.new()
|
||||
add_folder_button.text = "Add Folder"
|
||||
add_folder_button.icon = add_icon
|
||||
_folder_entry_container.add_child(add_folder_button)
|
||||
add_folder_button.connect("pressed", self, "on_add_folder_button_pressed", [ module ])
|
||||
|
||||
#set_tab(0)
|
||||
|
||||
func on_folder_entry_button_pressed(module, full_folder_path : String, folder_index : int) -> void:
|
||||
#_resource_scene.show()
|
||||
_resource_scene.set_resource_type(full_folder_path, _settings.folder_get_type(folder_index))
|
||||
|
||||
func on_module_entry_button_toggled(on : bool, module) -> void:
|
||||
if on:
|
||||
for m in _active_modules:
|
||||
if m == module:
|
||||
return
|
||||
|
||||
_active_modules.push_back(module)
|
||||
generate_folder_entry_list()
|
||||
else:
|
||||
for i in range(_active_modules.size()):
|
||||
if _active_modules[i] == module:
|
||||
_active_modules.remove(i)
|
||||
generate_folder_entry_list()
|
||||
return
|
||||
|
||||
func on_add_folder_button_pressed(module) -> void:
|
||||
$Popups/AddFolderDialog.set_module(module, _settings)
|
||||
|
||||
func load_modules() -> void:
|
||||
_modules.clear()
|
||||
load_modules_at("res://")
|
||||
_modules.sort_custom(ModulePathSorter, "sort_ascending")
|
||||
|
||||
func load_modules_at(path : String) -> void:
|
||||
var dir = Directory.new()
|
||||
if dir.open(path) == OK:
|
||||
dir.list_dir_begin()
|
||||
var file_name = dir.get_next()
|
||||
while file_name != "":
|
||||
if file_name == "." or file_name == "..":
|
||||
file_name = dir.get_next()
|
||||
continue
|
||||
|
||||
if dir.current_is_dir():
|
||||
if path == "res://":
|
||||
load_modules_at(path + file_name)
|
||||
else:
|
||||
load_modules_at(path + "/" + file_name)
|
||||
else:
|
||||
if file_name == "game_module.tres":
|
||||
var res : Resource = null
|
||||
|
||||
if path == "res://":
|
||||
res = ResourceLoader.load(path + file_name)
|
||||
else:
|
||||
res = ResourceLoader.load(path + "/" + file_name)
|
||||
|
||||
if res.enabled:
|
||||
_modules.append(res)
|
||||
|
||||
file_name = dir.get_next()
|
||||
else:
|
||||
print("An error occurred when trying to access the path: " + path)
|
||||
|
||||
class ModulePathSorter:
|
||||
static func sort_ascending(a, b):
|
||||
if a.resource_path < b.resource_path:
|
||||
return true
|
||||
return false
|
||||
|
||||
func set_tab(tab_index : int) -> void:
|
||||
hide_all()
|
||||
|
||||
_resource_scene.show()
|
||||
_resource_scene.set_resource_type(_settings.folder_get_folder(tab_index), _settings.folder_get_type(tab_index))
|
||||
|
||||
func hide_all() -> void:
|
||||
_resource_scene.hide()
|
||||
|
||||
func inspect_data(var data : Resource) -> void:
|
||||
emit_signal("inspect_data", data)
|
||||
|
||||
func set_plugin(plugin : EditorPlugin) -> void:
|
||||
_plugin = plugin
|
||||
|
||||
func get_module_label_text(module) -> String:
|
||||
var label_str : String = module.resource_name
|
||||
|
||||
if label_str == "":
|
||||
label_str = module.resource_path
|
||||
label_str = label_str.replace("res://", "")
|
||||
label_str = label_str.replace("/game_module.tres", "")
|
||||
label_str = label_str.replace("game_module.tres", "")
|
||||
|
||||
return label_str
|
||||
|
||||
func on_folders_created() -> void:
|
||||
generate_folder_entry_list()
|
101
game/addons/data_manager/panels/MainPanel.tscn
Normal file
@ -0,0 +1,101 @@
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://addons/data_manager/panels/MainPanel.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/data_manager/panels/ResourcePanel.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://addons/data_manager/panels/AddFolderDialog.gd" type="Script" id=4]
|
||||
|
||||
[node name="Panel" type="MarginContainer"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
resource_scene = ExtResource( 3 )
|
||||
base_folder = "res://data/"
|
||||
main_container = NodePath("HSplitContainer/MarginContainer")
|
||||
module_entry_container_path = NodePath("HSplitContainer/TabContainer/Modules/VBoxContainer")
|
||||
folder_entry_container_path = NodePath("HSplitContainer/TabContainer/Folders/VBoxContainer")
|
||||
|
||||
[node name="HSplitContainer" type="HSplitContainer" parent="."]
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 600.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
split_offset = 210
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="TabContainer" type="TabContainer" parent="HSplitContainer"]
|
||||
margin_right = 218.0
|
||||
margin_bottom = 600.0
|
||||
|
||||
[node name="Modules" type="ScrollContainer" parent="HSplitContainer/TabContainer"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 4.0
|
||||
margin_top = 32.0
|
||||
margin_right = -4.0
|
||||
margin_bottom = -4.0
|
||||
size_flags_vertical = 3
|
||||
scroll_horizontal_enabled = false
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/TabContainer/Modules"]
|
||||
margin_right = 210.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Folders" type="ScrollContainer" parent="HSplitContainer/TabContainer"]
|
||||
visible = false
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 4.0
|
||||
margin_top = 32.0
|
||||
margin_right = -4.0
|
||||
margin_bottom = -4.0
|
||||
size_flags_vertical = 3
|
||||
scroll_horizontal_enabled = false
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/TabContainer/Folders"]
|
||||
margin_right = 210.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="HSplitContainer"]
|
||||
margin_left = 230.0
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 600.0
|
||||
|
||||
[node name="Popups" type="Control" parent="."]
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 600.0
|
||||
mouse_filter = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
__meta__ = {
|
||||
"_edit_lock_": true
|
||||
}
|
||||
|
||||
[node name="AddFolderDialog" type="ConfirmationDialog" parent="Popups"]
|
||||
margin_left = 287.0
|
||||
margin_top = 100.0
|
||||
margin_right = 751.0
|
||||
margin_bottom = 447.0
|
||||
window_title = "Add folder(s)"
|
||||
resizable = true
|
||||
script = ExtResource( 4 )
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="Popups/AddFolderDialog"]
|
||||
margin_left = 8.0
|
||||
margin_top = 8.0
|
||||
margin_right = 456.0
|
||||
margin_bottom = 311.0
|
||||
scroll_horizontal_enabled = false
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="Popups/AddFolderDialog/ScrollContainer"]
|
||||
margin_right = 448.0
|
||||
size_flags_horizontal = 3
|
@ -42,6 +42,9 @@ func _ready():
|
||||
_delete_popup = get_node(delete_popup_path)
|
||||
|
||||
func set_resource_type(folder : String, resource_type : String) -> void:
|
||||
if !folder.ends_with("/"):
|
||||
folder += "/"
|
||||
|
||||
if folder == _folder and _resource_type == resource_type:
|
||||
return
|
||||
|
@ -1,13 +1,12 @@
|
||||
[gd_scene load_steps=8 format=2]
|
||||
|
||||
[ext_resource path="res://addons/module_manager/panels/CreateNamePopup.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://addons/module_manager/panels/ResourceRow.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://addons/module_manager/panels/HistoryEntry.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://addons/module_manager/icons/icon_add.png" type="Texture" id=4]
|
||||
[ext_resource path="res://addons/module_manager/panels/ResourcePanel.gd" type="Script" id=5]
|
||||
[ext_resource path="res://addons/module_manager/icons/icon_empty.png" type="Texture" id=6]
|
||||
[ext_resource path="res://addons/module_manager/icons/icon_reload_small.png" type="Texture" id=7]
|
||||
|
||||
[ext_resource path="res://addons/data_manager/panels/CreateNamePopup.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://addons/data_manager/panels/ResourceRow.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://addons/data_manager/panels/HistoryEntry.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://addons/data_manager/icons/icon_add.png" type="Texture" id=4]
|
||||
[ext_resource path="res://addons/data_manager/panels/ResourcePanel.gd" type="Script" id=5]
|
||||
[ext_resource path="res://addons/data_manager/icons/icon_empty.png" type="Texture" id=6]
|
||||
[ext_resource path="res://addons/data_manager/icons/icon_reload_small.png" type="Texture" id=7]
|
||||
|
||||
[node name="Panel" type="Control"]
|
||||
anchor_right = 1.0
|
||||
@ -33,71 +32,71 @@ __meta__ = {
|
||||
}
|
||||
|
||||
[node name="VBoxContainer2" type="VBoxContainer" parent="ResourcePanel"]
|
||||
margin_right = 664.0
|
||||
margin_right = 600.0
|
||||
margin_bottom = 600.0
|
||||
|
||||
[node name="LineEdit" type="LineEdit" parent="ResourcePanel/VBoxContainer2"]
|
||||
margin_right = 664.0
|
||||
margin_bottom = 45.0
|
||||
margin_right = 600.0
|
||||
margin_bottom = 26.0
|
||||
right_icon = ExtResource( 6 )
|
||||
placeholder_text = "Filter"
|
||||
caret_blink = true
|
||||
|
||||
[node name="CreateButton" type="Button" parent="ResourcePanel/VBoxContainer2"]
|
||||
margin_top = 53.0
|
||||
margin_right = 664.0
|
||||
margin_bottom = 90.0
|
||||
margin_top = 30.0
|
||||
margin_right = 600.0
|
||||
margin_bottom = 50.0
|
||||
rect_min_size = Vector2( 100, 0 )
|
||||
text = "Create"
|
||||
icon = ExtResource( 4 )
|
||||
expand_icon = true
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="ResourcePanel/VBoxContainer2"]
|
||||
margin_top = 98.0
|
||||
margin_right = 664.0
|
||||
margin_bottom = 106.0
|
||||
margin_top = 54.0
|
||||
margin_right = 600.0
|
||||
margin_bottom = 58.0
|
||||
size_flags_horizontal = 3
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="ScrollContainer2" type="ScrollContainer" parent="ResourcePanel/VBoxContainer2"]
|
||||
margin_top = 114.0
|
||||
margin_right = 664.0
|
||||
margin_top = 62.0
|
||||
margin_right = 600.0
|
||||
margin_bottom = 600.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="ResourcePanel/VBoxContainer2/ScrollContainer2"]
|
||||
margin_right = 664.0
|
||||
margin_right = 600.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="ResourcePanel"]
|
||||
margin_left = 688.0
|
||||
margin_left = 612.0
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 600.0
|
||||
|
||||
[node name="Button" type="Button" parent="ResourcePanel/VBoxContainer"]
|
||||
margin_right = 336.0
|
||||
margin_bottom = 37.0
|
||||
margin_right = 412.0
|
||||
margin_bottom = 20.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Clear History"
|
||||
icon = ExtResource( 7 )
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="ResourcePanel/VBoxContainer"]
|
||||
margin_top = 45.0
|
||||
margin_right = 336.0
|
||||
margin_bottom = 53.0
|
||||
margin_top = 24.0
|
||||
margin_right = 412.0
|
||||
margin_bottom = 28.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="ResourcePanel/VBoxContainer"]
|
||||
margin_top = 61.0
|
||||
margin_right = 336.0
|
||||
margin_top = 32.0
|
||||
margin_right = 412.0
|
||||
margin_bottom = 600.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="ResourcePanel/VBoxContainer/ScrollContainer"]
|
||||
margin_right = 336.0
|
||||
margin_right = 412.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="CreateNamePopup" parent="." instance=ExtResource( 1 )]
|
||||
@ -112,6 +111,7 @@ margin_top = -55.0
|
||||
margin_right = 139.0
|
||||
margin_bottom = 55.0
|
||||
dialog_text = "Delete?"
|
||||
|
||||
[connection signal="text_entered" from="ResourcePanel/VBoxContainer2/LineEdit" to="." method="search"]
|
||||
[connection signal="pressed" from="ResourcePanel/VBoxContainer2/CreateButton" to="CreateNamePopup" method="popup"]
|
||||
[connection signal="pressed" from="ResourcePanel/VBoxContainer/Button" to="." method="clear_history"]
|
@ -1,13 +1,13 @@
|
||||
[gd_scene load_steps=9 format=2]
|
||||
|
||||
[ext_resource path="res://addons/module_manager/previews/TexturePreview.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://addons/module_manager/previews/ControlPreview.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://addons/module_manager/previews/Node2DPreview.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://addons/module_manager/previews/SpatialPreview.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://addons/module_manager/panels/ResourceRowMainButton.gd" type="Script" id=5]
|
||||
[ext_resource path="res://addons/module_manager/panels/EntryButton.gd" type="Script" id=6]
|
||||
[ext_resource path="res://addons/module_manager/icons/icon_duplicate.png" type="Texture" id=7]
|
||||
[ext_resource path="res://addons/module_manager/icons/icon_remove.png" type="Texture" id=8]
|
||||
[ext_resource path="res://addons/data_manager/previews/TexturePreview.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://addons/data_manager/previews/ControlPreview.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://addons/data_manager/previews/Node2DPreview.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://addons/data_manager/previews/SpatialPreview.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://addons/data_manager/panels/ResourceRowMainButton.gd" type="Script" id=5]
|
||||
[ext_resource path="res://addons/data_manager/panels/EntryButton.gd" type="Script" id=6]
|
||||
[ext_resource path="res://addons/data_manager/icons/icon_duplicate.png" type="Texture" id=7]
|
||||
[ext_resource path="res://addons/data_manager/icons/icon_remove.png" type="Texture" id=8]
|
||||
|
||||
|
||||
[node name="ResourceRow" type="HBoxContainer"]
|
@ -1,6 +1,6 @@
|
||||
[plugin]
|
||||
|
||||
name="Entity Spell System Data Manager"
|
||||
name="Data Manager"
|
||||
description=""
|
||||
author="Relintai"
|
||||
version="1.0"
|
61
game/addons/data_manager/plugin.gd
Normal file
@ -0,0 +1,61 @@
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
const DataManagerAddonSettings = preload("res://addons/data_manager/resources/data_manager_addon_settings.gd")
|
||||
|
||||
const _main_panel : PackedScene = preload("res://addons/data_manager/panels/MainPanel.tscn")
|
||||
const _script_icon : Texture = preload("res://addons/data_manager/icons/icon_multi_line.png")
|
||||
|
||||
var settings : DataManagerAddonSettings = null
|
||||
|
||||
var _main_panel_instance : Control
|
||||
|
||||
func _enter_tree():
|
||||
load_settings()
|
||||
|
||||
_main_panel_instance = _main_panel.instance() as Control
|
||||
_main_panel_instance.set_plugin(self)
|
||||
_main_panel_instance.connect("inspect_data", self, "inspect_data")
|
||||
|
||||
get_editor_interface().get_editor_viewport().add_child(_main_panel_instance)
|
||||
|
||||
make_visible(false)
|
||||
|
||||
func _exit_tree():
|
||||
_main_panel_instance.queue_free()
|
||||
|
||||
func has_main_screen():
|
||||
return true
|
||||
|
||||
func make_visible(visible):
|
||||
if visible:
|
||||
_main_panel_instance.show()
|
||||
else:
|
||||
_main_panel_instance.hide()
|
||||
|
||||
func get_plugin_icon():
|
||||
return _script_icon
|
||||
|
||||
func get_plugin_name():
|
||||
return "Data"
|
||||
|
||||
func inspect_data(var data : Resource) -> void:
|
||||
get_editor_interface().inspect_object(data)
|
||||
|
||||
func ensure_data_dir_exists() -> void:
|
||||
var dir : Directory = Directory.new()
|
||||
|
||||
if !dir.dir_exists("res://addons/data_manager/_data/"):
|
||||
dir.make_dir("res://addons/data_manager/_data/")
|
||||
|
||||
func load_settings() -> void:
|
||||
ensure_data_dir_exists()
|
||||
|
||||
var dir : Directory = Directory.new()
|
||||
|
||||
if !dir.file_exists("res://addons/data_manager/_data/settings.tres"):
|
||||
settings = DataManagerAddonSettings.new()
|
||||
|
||||
ResourceSaver.save("res://addons/data_manager/_data/settings.tres", settings)
|
||||
else:
|
||||
settings = ResourceLoader.load("res://addons/data_manager/_data/settings.tres")
|
@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/module_manager/previews/ControlPreview.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/data_manager/previews/ControlPreview.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[node name="ControlPreview" type="ViewportContainer"]
|
@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/module_manager/previews/Node2DPreview.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/data_manager/previews/Node2DPreview.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[node name="Node2DPreview" type="ViewportContainer"]
|
@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/module_manager/previews/SpatialPreview.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/data_manager/previews/SpatialPreview.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[node name="SpatialPreview" type="ViewportContainer"]
|
@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/module_manager/previews/TexturePreview.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/data_manager/previews/TexturePreview.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[node name="TexturePreview" type="TextureRect"]
|
@ -0,0 +1,135 @@
|
||||
tool
|
||||
extends Resource
|
||||
|
||||
class SettingEntry:
|
||||
var folder : String = ""
|
||||
var header : String = ""
|
||||
var name : String = ""
|
||||
var type : String = ""
|
||||
|
||||
var folders : Array = Array()
|
||||
|
||||
func get_folder_count() -> int:
|
||||
return folders.size()
|
||||
|
||||
func folder_get(index : int) -> SettingEntry:
|
||||
return folders[index]
|
||||
|
||||
func folder_get_folder(index : int) -> String:
|
||||
return folders[index].folder
|
||||
|
||||
func folder_get_header(index : int) -> String:
|
||||
return folders[index].header
|
||||
|
||||
func folder_get_name(index : int) -> String:
|
||||
return folders[index].name
|
||||
|
||||
func folder_get_type(index : int) -> String:
|
||||
return folders[index].type
|
||||
|
||||
func _get(property):
|
||||
if property == "folder_count":
|
||||
return folders.size()
|
||||
|
||||
if property.begins_with("folders/"):
|
||||
var sindex : String = property.get_slice("/", 1)
|
||||
|
||||
if sindex == "":
|
||||
return null
|
||||
|
||||
var index : int = sindex.to_int()
|
||||
|
||||
if index < 0 || index >= folders.size():
|
||||
return null
|
||||
|
||||
var p : String = property.get_slice("/", 2)
|
||||
|
||||
if p == "folder":
|
||||
return folders[index].folder
|
||||
elif p == "header":
|
||||
return folders[index].header
|
||||
elif p == "name":
|
||||
return folders[index].name
|
||||
elif p == "type":
|
||||
return folders[index].type
|
||||
else:
|
||||
return null
|
||||
|
||||
return null
|
||||
|
||||
func _set(property, val):
|
||||
if property == "folder_count":
|
||||
set_folder_count(val)
|
||||
return true
|
||||
|
||||
if property.begins_with("folders/"):
|
||||
var sindex : String = property.get_slice("/", 1)
|
||||
|
||||
if sindex == "":
|
||||
return null
|
||||
|
||||
var index : int = sindex.to_int()
|
||||
|
||||
if index < 0:
|
||||
return false
|
||||
|
||||
if index >= folders.size():
|
||||
return false
|
||||
|
||||
var p : String = property.get_slice("/", 2)
|
||||
|
||||
if p == "folder":
|
||||
folders[index].folder = val
|
||||
return true
|
||||
elif p == "header":
|
||||
folders[index].header = val
|
||||
return true
|
||||
elif p == "name":
|
||||
folders[index].name = val
|
||||
return true
|
||||
elif p == "type":
|
||||
folders[index].type = val
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
func _get_property_list() -> Array:
|
||||
var props : Array = Array()
|
||||
|
||||
props.append({
|
||||
"name": "folder_count",
|
||||
"type": TYPE_INT,
|
||||
})
|
||||
|
||||
for i in range(folders.size()):
|
||||
props.append({
|
||||
"name": "folders/" + str(i) + "/folder",
|
||||
"type": TYPE_STRING,
|
||||
})
|
||||
props.append({
|
||||
"name": "folders/" + str(i) + "/header",
|
||||
"type": TYPE_STRING,
|
||||
})
|
||||
props.append({
|
||||
"name": "folders/" + str(i) + "/name",
|
||||
"type": TYPE_STRING,
|
||||
})
|
||||
props.append({
|
||||
"name": "folders/" + str(i) + "/type",
|
||||
"type": TYPE_STRING,
|
||||
})
|
||||
|
||||
return props
|
||||
|
||||
func apply_folder_size(val : int) -> void:
|
||||
folders.resize(val)
|
||||
|
||||
for i in range(folders.size()):
|
||||
if !folders[i]:
|
||||
folders[i] = SettingEntry.new()
|
||||
|
||||
func set_folder_count(val : int) -> void:
|
||||
apply_folder_size(val)
|
||||
|
||||
emit_changed()
|
||||
property_list_changed_notify()
|
@ -11,10 +11,22 @@ export(NodePath) var add_popup_path : NodePath = "Popups/AddPopup"
|
||||
var _graph_edit : GraphEdit = null
|
||||
|
||||
var _material : MMMateial
|
||||
var _ignore_material_change_event : int = 0
|
||||
var _recreation_in_progress : bool = false
|
||||
|
||||
var _plugin : EditorPlugin = null
|
||||
var _undo_redo : UndoRedo = null
|
||||
|
||||
func _enter_tree():
|
||||
ensure_objs()
|
||||
|
||||
func set_plugin(plugin : EditorPlugin) -> void:
|
||||
_plugin = plugin
|
||||
_undo_redo = plugin.get_undo_redo()
|
||||
|
||||
func get_undo_redo() -> UndoRedo:
|
||||
return _undo_redo
|
||||
|
||||
func ensure_objs() -> void:
|
||||
if !_graph_edit:
|
||||
_graph_edit = get_node(graph_edit_path)
|
||||
@ -46,6 +58,13 @@ func ensure_objs() -> void:
|
||||
_graph_edit.connect("disconnection_request", self, "on_graph_edit_disconnection_request")
|
||||
|
||||
func recreate() -> void:
|
||||
ignore_changes(true)
|
||||
|
||||
if _recreation_in_progress:
|
||||
return
|
||||
|
||||
_recreation_in_progress = true
|
||||
|
||||
ensure_objs()
|
||||
|
||||
_graph_edit.clear_connections()
|
||||
@ -63,6 +82,7 @@ func recreate() -> void:
|
||||
for n in _material.nodes:
|
||||
var gn : GraphNode = MMGraphNode.new()
|
||||
gn.slot_colors = slot_colors
|
||||
gn.set_editor(self)
|
||||
gn.set_node(_material, n)
|
||||
_graph_edit.add_child(gn)
|
||||
|
||||
@ -80,6 +100,10 @@ func recreate() -> void:
|
||||
_graph_edit.connect_node(output_node.name, from_slot, input_node.name, to_slot)
|
||||
|
||||
_material.render()
|
||||
|
||||
_recreation_in_progress = false
|
||||
|
||||
ignore_changes(false)
|
||||
|
||||
func find_graph_node_for(nnode) -> Node:
|
||||
for c in _graph_edit.get_children():
|
||||
@ -93,33 +117,73 @@ func find_graph_node_for(nnode) -> Node:
|
||||
return null
|
||||
|
||||
func set_mmmaterial(object : MMMateial):
|
||||
if _material:
|
||||
_material.disconnect("changed", self, "on_material_changed")
|
||||
|
||||
_material = object
|
||||
|
||||
|
||||
recreate()
|
||||
|
||||
if _material:
|
||||
_material.connect("changed", self, "on_material_changed")
|
||||
|
||||
func on_material_changed() -> void:
|
||||
if _ignore_material_change_event > 0:
|
||||
return
|
||||
|
||||
if _recreation_in_progress:
|
||||
return
|
||||
|
||||
call_deferred("recreate")
|
||||
|
||||
func ignore_changes(val : bool) -> void:
|
||||
if val:
|
||||
_ignore_material_change_event += 1
|
||||
else:
|
||||
_ignore_material_change_event -= 1
|
||||
|
||||
func on_graph_edit_connection_request(from: String, from_slot: int, to: String, to_slot: int):
|
||||
var from_node : GraphNode = _graph_edit.get_node(from)
|
||||
var to_node : GraphNode = _graph_edit.get_node(to)
|
||||
|
||||
ignore_changes(true)
|
||||
|
||||
_material.cancel_render_and_wait()
|
||||
|
||||
|
||||
if from_node.connect_slot(from_slot, to_node, to_slot):
|
||||
_graph_edit.connect_node(from, from_slot, to, to_slot)
|
||||
|
||||
ignore_changes(false)
|
||||
|
||||
func on_graph_edit_disconnection_request(from: String, from_slot: int, to: String, to_slot: int):
|
||||
var from_node : GraphNode = _graph_edit.get_node(from)
|
||||
var to_node : GraphNode = _graph_edit.get_node(to)
|
||||
|
||||
ignore_changes(true)
|
||||
|
||||
_material.cancel_render_and_wait()
|
||||
|
||||
if from_node.disconnect_slot(from_slot, to_node, to_slot):
|
||||
_graph_edit.disconnect_node(from, from_slot, to, to_slot)
|
||||
|
||||
ignore_changes(false)
|
||||
|
||||
func on_graph_node_close_request(node : GraphNode) -> void:
|
||||
if _material:
|
||||
ignore_changes(true)
|
||||
|
||||
_material.cancel_render_and_wait()
|
||||
_material.remove_node(node._node)
|
||||
|
||||
#_material.remove_node(node._node)
|
||||
|
||||
_undo_redo.create_action("MMGD: Remove Node")
|
||||
_undo_redo.add_do_method(_material, "remove_node", node._node)
|
||||
_undo_redo.add_undo_method(_material, "add_node", node._node)
|
||||
_undo_redo.commit_action()
|
||||
|
||||
recreate()
|
||||
|
||||
ignore_changes(false)
|
||||
|
||||
func _on_AddButton_pressed():
|
||||
get_node(add_popup_path).popup_centered()
|
||||
@ -139,10 +203,20 @@ func _on_AddPopup_ok_pressed(script_path : String):
|
||||
print("_on_AddPopup_ok_pressed: Error !nnode! script: " + script_path)
|
||||
return
|
||||
|
||||
_material.add_node(nnode)
|
||||
ignore_changes(true)
|
||||
|
||||
#_material.add_node(nnode)
|
||||
|
||||
_undo_redo.create_action("MMGD: Add Node")
|
||||
_undo_redo.add_do_method(_material, "add_node", nnode)
|
||||
_undo_redo.add_undo_method(_material, "remove_node", nnode)
|
||||
_undo_redo.commit_action()
|
||||
|
||||
var gn : GraphNode = MMGraphNode.new()
|
||||
gn.slot_colors = slot_colors
|
||||
gn.set_editor(self)
|
||||
gn.set_node(_material, nnode)
|
||||
_graph_edit.add_child(gn)
|
||||
|
||||
ignore_changes(false)
|
||||
|
||||
|
@ -11,11 +11,24 @@ var _material : MMMateial = null
|
||||
var _node : MMNode = null
|
||||
var properties : Array = Array()
|
||||
|
||||
var _editor_node
|
||||
var _undo_redo : UndoRedo = null
|
||||
var _ignore_change_event : bool = false
|
||||
|
||||
func _init():
|
||||
show_close = true
|
||||
connect("offset_changed", self, "on_offset_changed")
|
||||
connect("dragged", self, "on_dragged")
|
||||
connect("close_request", self, "on_close_request")
|
||||
|
||||
func set_editor(editor_node) -> void:
|
||||
_editor_node = editor_node
|
||||
|
||||
_undo_redo = _editor_node.get_undo_redo()
|
||||
|
||||
func ignore_changes(val : bool) -> void:
|
||||
_ignore_change_event = val
|
||||
_editor_node.ignore_changes(val)
|
||||
|
||||
func add_slot_texture(getter : String, setter : String) -> int:
|
||||
var t : TextureRect = TextureRect.new()
|
||||
t.rect_min_size = Vector2(128, 128)
|
||||
@ -448,7 +461,12 @@ func connect_slot(slot_idx : int, to_node : Node, to_slot_idx : int) -> bool:
|
||||
to_property_index = i
|
||||
break
|
||||
|
||||
to_node.properties[to_property_index][6].set_input_property(properties[from_property_index][6])
|
||||
#to_node.properties[to_property_index][6].set_input_property(properties[from_property_index][6])
|
||||
|
||||
_undo_redo.create_action("MMGD: connect_slot")
|
||||
_undo_redo.add_do_method(to_node.properties[to_property_index][6], "set_input_property", properties[from_property_index][6])
|
||||
_undo_redo.add_undo_method(to_node.properties[to_property_index][6], "set_input_property", to_node.properties[to_property_index][6].input_property)
|
||||
_undo_redo.commit_action()
|
||||
|
||||
return true
|
||||
|
||||
@ -472,7 +490,12 @@ func disconnect_slot(slot_idx : int, to_node : Node, to_slot_idx : int) -> bool:
|
||||
to_property_index = i
|
||||
break
|
||||
|
||||
to_node.properties[to_property_index][6].set_input_property(null)
|
||||
#to_node.properties[to_property_index][6].set_input_property(null)
|
||||
|
||||
_undo_redo.create_action("MMGD: disconnect_slot")
|
||||
_undo_redo.add_do_method(to_node.properties[to_property_index][6], "unset_input_property")
|
||||
_undo_redo.add_undo_method(to_node.properties[to_property_index][6], "set_input_property", to_node.properties[to_property_index][6].input_property)
|
||||
_undo_redo.commit_action()
|
||||
|
||||
return true
|
||||
|
||||
@ -519,52 +542,120 @@ func set_node(material : MMMateial, node : MMNode) -> void:
|
||||
|
||||
offset = _node.get_graph_position()
|
||||
|
||||
_node.connect("changed", self, "on_node_changed")
|
||||
#_node.connect("changed", self, "on_node_changed")
|
||||
|
||||
func propagate_node_change() -> void:
|
||||
pass
|
||||
|
||||
func on_offset_changed():
|
||||
func on_dragged(from : Vector2, to : Vector2):
|
||||
if _node:
|
||||
_node.set_graph_position(offset)
|
||||
ignore_changes(true)
|
||||
#_node.set_graph_position(offset)
|
||||
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(_node, "set_graph_position", to)
|
||||
_undo_redo.add_undo_method(_node, "set_graph_position", from)
|
||||
_undo_redo.commit_action()
|
||||
|
||||
ignore_changes(false)
|
||||
|
||||
func on_node_changed():
|
||||
#get all properties again
|
||||
#_node.recalculate_image(_material)
|
||||
|
||||
propagate_node_change()
|
||||
#func on_node_changed():
|
||||
# if _ignore_change_event:
|
||||
# return
|
||||
#
|
||||
# _ignore_change_event = true
|
||||
# propagate_node_change()
|
||||
# _ignore_change_event = false
|
||||
|
||||
func on_int_spinbox_value_changed(val : float, slot_idx) -> void:
|
||||
_node.call(properties[slot_idx][4], int(val))
|
||||
#_node.call(properties[slot_idx][4], int(val))
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(_node, properties[slot_idx][4], int(val))
|
||||
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func on_float_spinbox_value_changed(val : float, slot_idx) -> void:
|
||||
_node.call(properties[slot_idx][4], val)
|
||||
#_node.call(properties[slot_idx][4], val)
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(_node, properties[slot_idx][4], val)
|
||||
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func on_vector2_spinbox_value_changed(val : float, slot_idx, spinbox_x, spinbox_y) -> void:
|
||||
var vv : Vector2 = Vector2(spinbox_x.value, spinbox_y.value)
|
||||
|
||||
_node.call(properties[slot_idx][4], vv)
|
||||
#_node.call(properties[slot_idx][4], vv)
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(_node, properties[slot_idx][4], vv)
|
||||
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func on_vector3_spinbox_value_changed(val : float, slot_idx, spinbox_x, spinbox_y, spinbox_z) -> void:
|
||||
var vv : Vector3 = Vector3(spinbox_x.value, spinbox_y.value, spinbox_z.value)
|
||||
|
||||
_node.call(properties[slot_idx][4], vv)
|
||||
#_node.call(properties[slot_idx][4], vv)
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(_node, properties[slot_idx][4], vv)
|
||||
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func on_int_universal_spinbox_value_changed(val : float, slot_idx) -> void:
|
||||
properties[slot_idx][6].set_default_value(int(val))
|
||||
#properties[slot_idx][6].set_default_value(int(val))
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(properties[slot_idx][6], "set_default_value", int(val))
|
||||
_undo_redo.add_undo_method(properties[slot_idx][6], "set_default_value", properties[slot_idx][6].get_default_value())
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func on_float_universal_spinbox_value_changed(val : float, slot_idx) -> void:
|
||||
properties[slot_idx][6].set_default_value(val)
|
||||
#properties[slot_idx][6].set_default_value(val)
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(properties[slot_idx][6], "set_default_value", val)
|
||||
_undo_redo.add_undo_method(properties[slot_idx][6], "set_default_value", properties[slot_idx][6].get_default_value())
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func on_vector2_universal_spinbox_value_changed(val : float, slot_idx, spinbox_x, spinbox_y) -> void:
|
||||
var vv : Vector2 = Vector2(spinbox_x.value, spinbox_y.value)
|
||||
|
||||
properties[slot_idx][6].set_default_value(vv)
|
||||
#properties[slot_idx][6].set_default_value(vv)
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(properties[slot_idx][6], "set_default_value", vv)
|
||||
_undo_redo.add_undo_method(properties[slot_idx][6], "set_default_value", properties[slot_idx][6].get_default_value())
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func on_slot_enum_item_selected(val : int, slot_idx : int) -> void:
|
||||
_node.call(properties[slot_idx][4], val)
|
||||
#_node.call(properties[slot_idx][4], val)
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(_node, properties[slot_idx][4], val)
|
||||
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func on_universal_texture_changed(slot_idx : int) -> void:
|
||||
ignore_changes(true)
|
||||
|
||||
var img : Image = properties[slot_idx][6].get_active_image()
|
||||
|
||||
var tex : ImageTexture = properties[slot_idx][5].texture
|
||||
@ -573,8 +664,12 @@ func on_universal_texture_changed(slot_idx : int) -> void:
|
||||
properties[slot_idx][5].texture.create_from_image(img, 0)
|
||||
else:
|
||||
properties[slot_idx][5].texture = ImageTexture.new()
|
||||
|
||||
ignore_changes(false)
|
||||
|
||||
func on_universal_texture_changed_image_picker(slot_idx : int) -> void:
|
||||
ignore_changes(true)
|
||||
|
||||
var img : Image = properties[slot_idx][6].get_active_image()
|
||||
|
||||
var tex : ImageTexture = properties[slot_idx][5].texture_normal
|
||||
@ -583,15 +678,38 @@ func on_universal_texture_changed_image_picker(slot_idx : int) -> void:
|
||||
properties[slot_idx][5].texture_normal.create_from_image(img, 0)
|
||||
else:
|
||||
properties[slot_idx][5].texture_normal = ImageTexture.new()
|
||||
|
||||
ignore_changes(false)
|
||||
|
||||
func on_slot_line_edit_text_entered(text : String, slot_idx : int) -> void:
|
||||
_node.call(properties[slot_idx][4], text)
|
||||
#_node.call(properties[slot_idx][4], text)
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(_node, properties[slot_idx][4], text)
|
||||
_undo_redo.add_undo_method(_node, properties[slot_idx][4], _node.call(properties[slot_idx][3]))
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func on_universal_color_changed(c : Color, slot_idx : int) -> void:
|
||||
properties[slot_idx][6].set_default_value(c)
|
||||
#properties[slot_idx][6].set_default_value(c)
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(properties[slot_idx][6], "set_default_value", c)
|
||||
_undo_redo.add_undo_method(properties[slot_idx][6], "set_default_value", properties[slot_idx][6].get_default_value())
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func on_universal_image_path_changed(f : String, slot_idx : int) -> void:
|
||||
_node.call(properties[slot_idx][8], f)
|
||||
|
||||
ignore_changes(true)
|
||||
_undo_redo.create_action("MMGD: value changed")
|
||||
_undo_redo.add_do_method(properties[slot_idx][6], "set_default_value", f)
|
||||
_undo_redo.add_undo_method(properties[slot_idx][6], "set_default_value", properties[slot_idx][6].get_default_value())
|
||||
_undo_redo.commit_action()
|
||||
ignore_changes(false)
|
||||
|
||||
func get_material_node() -> MMNode:
|
||||
return _node
|
||||
|
@ -22,6 +22,7 @@ func initialize():
|
||||
job.setup(self, "_thread_func")
|
||||
|
||||
for n in nodes:
|
||||
n.init_properties()
|
||||
n.connect("changed", self, "on_node_changed")
|
||||
|
||||
func add_node(node : MMNode) -> void:
|
||||
@ -49,15 +50,18 @@ func remove_node(node : MMNode) -> void:
|
||||
emit_changed()
|
||||
|
||||
func render() -> void:
|
||||
initialize()
|
||||
|
||||
if rendering:
|
||||
queued_render = true
|
||||
return
|
||||
|
||||
if USE_THREADS:
|
||||
render_threaded()
|
||||
else:
|
||||
render_non_threaded()
|
||||
|
||||
func render_non_threaded() -> void:
|
||||
if !initialized:
|
||||
initialize()
|
||||
|
||||
var did_render : bool = true
|
||||
|
||||
while did_render:
|
||||
@ -70,13 +74,6 @@ func render_non_threaded() -> void:
|
||||
func render_threaded() -> void:
|
||||
job.cancelled = false
|
||||
|
||||
if rendering:
|
||||
queued_render = true
|
||||
return
|
||||
|
||||
if !initialized:
|
||||
initialize()
|
||||
|
||||
if !ThreadPool.has_job(job):
|
||||
ThreadPool.add_job(job)
|
||||
|
||||
@ -109,11 +106,12 @@ func _thread_func() -> void:
|
||||
|
||||
func cancel_render_and_wait() -> void:
|
||||
if rendering:
|
||||
ThreadPool.cancel_task_wait(job)
|
||||
ThreadPool.cancel_job_wait(job)
|
||||
|
||||
job.cancelled = false
|
||||
|
||||
pass
|
||||
|
||||
func on_node_changed() -> void:
|
||||
emit_changed()
|
||||
call_deferred("render")
|
||||
|
@ -311,6 +311,11 @@ func set_input_property(val : MMNodeUniversalProperty) -> void:
|
||||
input_property.connect("changed", self, "on_input_property_changed")
|
||||
|
||||
emit_changed()
|
||||
|
||||
|
||||
# Because in UndiRedo if you pass null as the only argument it will look
|
||||
# for a method with no arguments
|
||||
func unset_input_property() -> void:
|
||||
set_input_property(null)
|
||||
|
||||
func on_input_property_changed() -> void:
|
||||
emit_changed()
|
||||
|
@ -16,6 +16,7 @@ func _enter_tree():
|
||||
add_custom_type("MMNodeUniversalProperty", "Resource", MMNodeUniversalProperty, null)
|
||||
|
||||
editor_scene = editor_packed_scene.instance()
|
||||
editor_scene.set_plugin(self)
|
||||
|
||||
tool_button = add_control_to_bottom_panel(editor_scene, "MMGD")
|
||||
tool_button.hide()
|
||||
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon_display-name.png-b574a7070246a84b4ec56d12c5fe3d19.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/module_manager/icons/icon_display-name.png"
|
||||
dest_files=[ "res://.import/icon_display-name.png-b574a7070246a84b4ec56d12c5fe3d19.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|