Cleaned up hierarchy

This commit is contained in:
Matthias Stöckli 2017-08-06 00:16:07 +02:00
parent 7d21397587
commit 86aeaf5a20
159 changed files with 27988 additions and 0 deletions

View File

Before

Width:  |  Height:  |  Size: 939 B

After

Width:  |  Height:  |  Size: 939 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 111 B

After

Width:  |  Height:  |  Size: 111 B

View File

Before

Width:  |  Height:  |  Size: 248 B

After

Width:  |  Height:  |  Size: 248 B

View File

Before

Width:  |  Height:  |  Size: 200 B

After

Width:  |  Height:  |  Size: 200 B

View File

Before

Width:  |  Height:  |  Size: 167 B

After

Width:  |  Height:  |  Size: 167 B

View File

Before

Width:  |  Height:  |  Size: 346 B

After

Width:  |  Height:  |  Size: 346 B

View File

Before

Width:  |  Height:  |  Size: 267 B

After

Width:  |  Height:  |  Size: 267 B

View File

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 170 B

View File

Before

Width:  |  Height:  |  Size: 268 B

After

Width:  |  Height:  |  Size: 268 B

View File

Before

Width:  |  Height:  |  Size: 269 B

After

Width:  |  Height:  |  Size: 269 B

View File

Before

Width:  |  Height:  |  Size: 140 B

After

Width:  |  Height:  |  Size: 140 B

View File

Before

Width:  |  Height:  |  Size: 392 B

After

Width:  |  Height:  |  Size: 392 B

View File

Before

Width:  |  Height:  |  Size: 409 B

After

Width:  |  Height:  |  Size: 409 B

View File

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 166 B

View File

Before

Width:  |  Height:  |  Size: 160 B

After

Width:  |  Height:  |  Size: 160 B

View File

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 252 B

View File

Before

Width:  |  Height:  |  Size: 262 B

After

Width:  |  Height:  |  Size: 262 B

View File

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

View File

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

46
demo/Shop.tscn Normal file
View File

@ -0,0 +1,46 @@
[gd_scene load_steps=3 format=1]
[ext_resource path="res://World.gd" type="Script" id=1]
[ext_resource path="res://ShopDialog.tscn" type="PackedScene" id=2]
[node name="World" type="Node2D"]
script/script = ExtResource( 1 )
[node name="ShopButtons" type="VButtonArray" parent="."]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 465.0
margin/top = 43.0
margin/right = 600.0
margin/bottom = 191.0
flat = false
button/count = 0
button/min_button_size = -1.0
button/align = 437
[node name="ShopDialog" parent="." instance=ExtResource( 2 )]
visibility/visible = false
[node name="Label" type="Label" parent="."]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 189.0
margin/bottom = 14.0
text = "Open this scene to test items and shops."
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[connection signal="button_selected" from="ShopButtons" to="." method="_on_ShopButtons_button_selected"]

23
demo/ShopDialog.gd Normal file
View File

@ -0,0 +1,23 @@
extends WindowDialog
onready var item_list = get_node("VBoxContainer/ItemList")
func create_shop(merchant):
var items_of_this_merchant = []
var all_shop_items = data.get_items("shop_item")
for shop_item in all_shop_items.values():
if shop_item.seller == merchant.name:
items_of_this_merchant.append(shop_item)
var i = 0
item_list.clear()
for shop_item in items_of_this_merchant:
item_list.add_item(shop_item.name)
item_list.set_item_metadata(i, shop_item)
i = i + 1
get_node("VBoxContainer/MerchantLabel").set_bbcode(merchant.name)
get_node("VBoxContainer/GreetingLabel").set_text(merchant.greeting)

75
demo/ShopDialog.tscn Normal file
View File

@ -0,0 +1,75 @@
[gd_scene load_steps=2 format=1]
[ext_resource path="res://ShopDialog.gd" type="Script" id=1]
[node name="WindowDialog" type="WindowDialog"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 316.0
margin/bottom = 288.0
popup/exclusive = false
window/title = ""
script/script = ExtResource( 1 )
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 0.0
margin/bottom = 0.0
alignment = 0
[node name="MerchantLabel" type="RichTextLabel" parent="VBoxContainer"]
rect/min_size = Vector2( 0, 30 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 316.0
margin/bottom = 30.0
custom_colors/default_color = Color( 1, 0, 0, 1 )
bbcode/enabled = false
bbcode/bbcode = "<<MERCHANT>>"
visible_characters = -1
[node name="GreetingLabel" type="Label" parent="VBoxContainer"]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 34.0
margin/right = 316.0
margin/bottom = 48.0
text = "<<GREETING>>"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="ItemList" type="ItemList" parent="VBoxContainer"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 3
margin/left = 0.0
margin/top = 52.0
margin/right = 316.0
margin/bottom = 288.0

19
demo/ShopTest.gd Normal file
View File

@ -0,0 +1,19 @@
extends Node2D
onready var buttons_array = get_node("ShopButtons")
onready var shop_dialog = get_node("ShopDialog")
func _ready():
var shop_types = ["Armor Shop", "Weapon Shop", "Inn", "Travelling Salesman"]
for shop_type in shop_types:
buttons_array.add_button(shop_type)
func _on_ShopButtons_button_selected( button_idx ):
var text = buttons_array.get_button_text(button_idx)
var all_merchants = data.get_items("merchant")
for merchant in all_merchants.values():
if merchant.name == text:
shop_dialog.create_shop(merchant)
shop_dialog.popup_centered()

46
demo/ShopTest.tscn Normal file
View File

@ -0,0 +1,46 @@
[gd_scene load_steps=3 format=1]
[ext_resource path="res://ShopTest.gd" type="Script" id=1]
[ext_resource path="res://ShopDialog.tscn" type="PackedScene" id=2]
[node name="World" type="Node2D"]
script/script = ExtResource( 1 )
[node name="ShopButtons" type="VButtonArray" parent="."]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 465.0
margin/top = 43.0
margin/right = 600.0
margin/bottom = 191.0
flat = false
button/count = 0
button/min_button_size = -1.0
button/align = 437
[node name="ShopDialog" parent="." instance=ExtResource( 2 )]
visibility/visible = false
[node name="Label" type="Label" parent="."]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 189.0
margin/bottom = 14.0
text = "Open this scene to test items and shops."
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[connection signal="button_selected" from="ShopButtons" to="." method="_on_ShopButtons_button_selected"]

30
demo/Spellbook.gd Normal file
View File

@ -0,0 +1,30 @@
extends Panel
onready var spell_list = get_node("LeftVBox/ScrollContainer/SpellList")
var icon_spell_unknown = preload("res://graphics/icon_spell_unknown.png")
func _ready():
var all_spells = data.get_items("spell")
var i = 0
for spell in all_spells.values():
var icon = null
if spell.icon:
icon = load(spell.icon)
else:
icon = icon_spell_unknown
spell_list.add_item(spell.name, icon)
spell_list.set_item_tooltip(i, spell.name)
spell_list.set_item_metadata(i, spell)
i = i + 1
spell_list.select(0)
_on_SpellList_item_selected(0)
func _on_SpellList_item_selected( index ):
var spell = spell_list.get_item_metadata(index)
get_node("RightVBox/SkillName").set_text(spell.name)
get_node("RightVBox/Description").set_text(spell.description)
var element = data.get_item("element", spell.element)
get_node("RightVBox/Type").set_bbcode("[color=#" + element.color.to_html() + "]" + element.name + "[/color]")
get_node("RightVBox/BaseDamage").set_text("Base Damage: " + str(spell.base_damage))

162
demo/Spellbook.tscn Normal file
View File

@ -0,0 +1,162 @@
[gd_scene load_steps=3 format=1]
[ext_resource path="res://Spellbook.gd" type="Script" id=1]
[ext_resource path="res://title_font.fnt" type="BitmapFont" id=2]
[node name="Panel" type="Panel"]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 0.0
margin/bottom = 0.0
script/script = ExtResource( 1 )
[node name="LeftVBox" type="VBoxContainer" parent="."]
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 200.0
margin/bottom = 600.0
alignment = 0
[node name="Label" type="Label" parent="LeftVBox"]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 200.0
margin/bottom = 21.0
custom_fonts/font = ExtResource( 2 )
text = "Spellbook"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="ScrollContainer" type="ScrollContainer" parent="LeftVBox"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 25.0
margin/right = 200.0
margin/bottom = 600.0
scroll/horizontal = true
scroll/vertical = true
[node name="SpellList" type="ItemList" parent="LeftVBox/ScrollContainer"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 0.0
margin/right = 200.0
margin/bottom = 575.0
[node name="RightVBox" type="VBoxContainer" parent="."]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 270.0
margin/top = 20.0
margin/right = 0.0
margin/bottom = 0.0
alignment = 0
[node name="SkillName" type="Label" parent="RightVBox"]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 754.0
margin/bottom = 21.0
custom_fonts/font = ExtResource( 2 )
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Description" type="Label" parent="RightVBox"]
rect/min_size = Vector2( 0, 100 )
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 25.0
margin/right = 754.0
margin/bottom = 125.0
autowrap = true
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Type" type="RichTextLabel" parent="RightVBox"]
rect/min_size = Vector2( 0, 20 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 129.0
margin/right = 754.0
margin/bottom = 149.0
bbcode/enabled = true
bbcode/bbcode = ""
visible_characters = -1
[node name="BaseDamage" type="Label" parent="RightVBox"]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 153.0
margin/right = 754.0
margin/bottom = 167.0
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Label" type="Label" parent="."]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 247.0
margin/bottom = 14.0
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[connection signal="item_selected" from="LeftVBox/ScrollContainer/SpellList" to="." method="_on_SpellList_item_selected"]

View File

@ -0,0 +1,17 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

View File

@ -0,0 +1,114 @@
# Godot Data Editor
This repository hosts a plugin for the [Godot Engine]. It allows users to enter data items based on Godot classes which are then serialized in either as json or binaries. Serialized items may be encrypted if desired.
# Features
* Support for binary or json serialization
* Create data classes with the click of a button
* Use gdscript to add properties and logic to your data classes, all instances will be Nodes
* Make use of the built-in [export property hints]
* Add instance-specific custom properties
* Access data with a simple API using the _data_ singleton
* ALPHA: Use the notification/observer system to react to changes in data items
* ALPHA: Encrypt your data files
# Screenshots
![editor_screenshot]
![class_screenshot]
# Installation
* Open your project folder, e.g. "../MyGame/"
* Create a folder named "addons" (if not already present)
* In addons, create a folder named "godot_data_editor"
* Copy the content of this repository into it. You may remove the "sceenshots" ;)
* Open your project in the editor and navigate to the plugin (Scene -> Project Settings -> Plugins)
* The plugin "godot_data_editor" should now appear, change the status from "Inactive" to "Active"
* Restart the editor to make sure that the _data_ singleton is loaded properly
I intend to upload the plugin to the AssetLib, once I feel it is stable enough.
# System Requirements
The plugin was written for version *2.1.3* of the Godot Engine. Upcoming minor versions should be supported as well.
It is very likely that a number of changes will be necessary, once Godot 3 is released.
# API / Tutorial
I created a little video which shows how to use the plugin to create a simple shop system: [[Link to video which does not exist yet :) ]]
Working with data is rather simple, use the provided _data_ class to access the items. The following code snippets demonstrates item retrieval as well as the observation feature:
```gdscript
extends Node
func _ready():
# Get a single item
var herb = data.get_item("shop_item", "herb")
var price = herb.price
# Get all items as dictionary (key: id, value: item)
var shop_items = data.get_items("shop_item")
for shop_item in shop_items.values():
print(shop_item.price)
pass
#######################################
# Observe Properties:
# Please note that you currently have to update properties using the "update_property" to make use of this feature
#######################################
# Be notified when something about this herb changes
data.observe_item(self, herb, "herb_changed")
herb.update_property("name", "better_herb")
# Be notified when the price of this herb changes,
data.observe_item_property(self, herb, "price", "herb_price_changed")
herb.update_property("price", 500)
# Be notified when any item changes
var doge_axe = data.get_item("shop_item", "doge_axe")
data.observe_class(self, "shop_item", "shop_item_changed")
doge_axe.update_property("price", 500)
# Overkill: be notified about everything
data.observe_all_changes(self, "something_changed")
#######################################
# Stop Observing:
# When you are no longer interested in updates, simply unsubscribe/stop observing
#######################################
data.stop_observing_item_property(self, herb, "price")
data.stop_observing_item(self, herb)
data.stop_observing_class(self, "shop_item")
data.stop_observing_changes(self)
func herb_changed(item, property, value):
print("Something about this herb changed!")
func herb_price_changed(item, property, value):
print("Herb price changed!")
func shop_item_changed(item, property, value):
print(item.name + " changed! " + property + " : " + str(value))
func something_changed(item, property, value):
print("I guess something changed.")
```
# Please Contribute!
Please feel free to contribute. Unfortunately, the code base still is not documented that well and there are a number of bugs which will need to be ironed out. I am sure that there are many things I have been doing wrong, especially in regard to memory management.
# Known Issues
* The "Rename Class" feature may not properly rename the class file if it still in use
* In some cases, the controls are not correctly resized - pressing "Reload" should usually do the trick though
* There is no support for undo/redo
* Pressing Ctrl+S will not save the data items but the current scene
* The _data_ singleton is only visible in the editor when the project is being restarted. This seems to be a limitation of the engine which does not allow reload the engine.cfg file
* The "class overview" screen is lacking any kind of useful content
# HALP! Something went wrong!
Stay calm, most issues can be resolved by either pressing the "Reload" button or activating and deactivating the plugin. If the problem persists, there is likely an issue with your data. Check if the name of the class (which are stored in the "classes" folder by default) is the same as the folder name of your instances (by default called "data"). If this is the case, there might be a conflict with duplicate IDs or the like. Please post an issue here if this happened without any external influence (e.g. you edited the files manually in another editor).
[Godot Engine]: <https://github.com/godotengine/godot>
[export property hints]: <http://docs.godotengine.org/en/latest/learning/scripting/gdscript/gdscript_basics.html#exports>
[editor_screenshot]: https://github.com/Stoeoeoe/godot_data_editor/blob/master/screenshots/editor.png "The Godot Data Editor"
[class_screenshot]: https://github.com/Stoeoeoe/godot_data_editor/blob/master/screenshots/class.png "Example Class"

View File

@ -0,0 +1,10 @@
tool
extends PanelContainer
func _ready():
pass
func set_label(text):
get_node("Panel/Body/Label").set_text(text)

View File

@ -0,0 +1,163 @@
[gd_scene load_steps=4 format=1]
[ext_resource path="res://addons/godot_data_editor/class_overview.gd" type="Script" id=1]
[ext_resource path="res://addons/godot_data_editor/style/light_gray_panel.tres" type="StyleBox" id=2]
[ext_resource path="res://addons/godot_data_editor/fonts/droid_serif_bold.tres" type="DynamicFont" id=3]
[node name="ClassOverview" type="PanelContainer"]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 0.0
margin/right = 0.0
margin/bottom = 0.0
script/script = ExtResource( 1 )
[node name="Panel" type="Panel" parent="."]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 7.0
margin/top = 7.0
margin/right = 1273.0
margin/bottom = 593.0
custom_styles/panel = ExtResource( 2 )
[node name="Body" type="VBoxContainer" parent="Panel"]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 10.0
margin/top = 10.0
margin/right = 10.0
margin/bottom = 10.0
alignment = 0
[node name="ClassPropertiesLabel" type="Label" parent="Panel/Body"]
visibility/visible = false
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 1246.0
margin/bottom = 19.0
custom_fonts/font = ExtResource( 3 )
text = "Static Class Properties"
uppercase = true
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="HSeparator" type="HSeparator" parent="Panel/Body"]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 1246.0
margin/bottom = 3.0
[node name="Control" type="Control" parent="Panel/Body"]
rect/min_size = Vector2( 0, 15 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 1246.0
margin/bottom = 15.0
[node name="Scroll" type="ScrollContainer" parent="Panel/Body"]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 19.0
margin/right = 1246.0
margin/bottom = 566.0
scroll/horizontal = true
scroll/vertical = true
[node name="Statics" type="VBoxContainer" parent="Panel/Body/Scroll"]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 3
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 1246.0
margin/bottom = 0.0
alignment = 0
[node name="NoStaticsPropertiesLabel" type="Label" parent="Panel/Body/Scroll/Statics"]
visibility/visible = false
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 1246.0
margin/bottom = 14.0
text = "There are no static properties for this class. Click below to add one."
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="AddStaticPropertyButton" type="Button" parent="Panel/Body/Scroll/Statics"]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 18.0
margin/right = 1246.0
margin/bottom = 38.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Add static property"
flat = false
[node name="Label" type="Label" parent="Panel/Body"]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 19.0
margin/right = 1246.0
margin/bottom = 33.0
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1

View File

@ -0,0 +1,50 @@
tool
extends Panel
var property_item_class = preload("property_item.tscn")
onready var class_properties_box = get_node("Body/Scroll/ClassProperties")
onready var no_class_properties_label = get_node("Body/Scroll/ClassProperties/NoClassPropertiesLabel")
var item = null
signal on_item_changed(item)
func build_properties(item):
self.item = item
for node in class_properties_box.get_children():
if node.has_meta("property"):
class_properties_box.remove_child(node)
var number_of_properties = 0
for property in item.get_property_list():
if property["usage"] == (PROPERTY_USAGE_SCRIPT_VARIABLE + PROPERTY_USAGE_STORAGE + PROPERTY_USAGE_EDITOR + PROPERTY_USAGE_NETWORK):
no_class_properties_label.hide()
number_of_properties += 1
var property_item = property_item_class.instance()
var property_name = property["name"]
var value = item.get(property_name)
property_item.initialize(property_name, property["type"], value, property["hint"], property["hint_string"])
property_item.connect("property_item_load_button_down", self, "_property_item_requests_file_dialog", [])
var changed_values = []
property_item.connect("on_property_value_changed", self, "item_changed", changed_values)
property_item.set_meta("property", true)
class_properties_box.add_child(property_item)
pass
if number_of_properties == 0:
no_class_properties_label.show()
func item_changed(property, value):
if item:
item.set(property, value)
emit_signal("on_item_changed", item)

View File

@ -0,0 +1,116 @@
[gd_scene load_steps=4 format=1]
[ext_resource path="res://addons/godot_data_editor/style/light_gray_panel.tres" type="StyleBox" id=1]
[ext_resource path="res://addons/godot_data_editor/class_properties.gd" type="Script" id=2]
[ext_resource path="res://addons/godot_data_editor/fonts/droid_serif_bold.tres" type="DynamicFont" id=3]
[node name="ClassProperties" type="Panel"]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 0.0
margin/right = 0.0
margin/bottom = 0.0
custom_styles/panel = ExtResource( 1 )
script/script = ExtResource( 2 )
[node name="Body" type="VBoxContainer" parent="."]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 10.0
margin/top = 10.0
margin/right = 10.0
margin/bottom = 10.0
alignment = 0
[node name="TitleLabel" type="Label" parent="Body"]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 1260.0
margin/bottom = 2.0
custom_fonts/font = ExtResource( 3 )
text = "Class Properties"
uppercase = true
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="HSeparator" type="HSeparator" parent="Body"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 6.0
margin/right = 1260.0
margin/bottom = 9.0
[node name="Spacer" type="Control" parent="Body"]
rect/min_size = Vector2( 0, 15 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 13.0
margin/right = 1260.0
margin/bottom = 28.0
[node name="Scroll" type="ScrollContainer" parent="Body"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 32.0
margin/right = 1260.0
margin/bottom = 580.0
scroll/horizontal = true
scroll/vertical = true
[node name="ClassProperties" type="VBoxContainer" parent="Body/Scroll"]
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 454.0
margin/bottom = 14.0
alignment = 0
[node name="NoClassPropertiesLabel" type="Label" parent="Body/Scroll/ClassProperties"]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 454.0
margin/bottom = 14.0
text = "There are currently no class properties. Edit the Class to add new ones."
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1

View File

@ -0,0 +1,77 @@
tool
extends Panel
var item = null
var property_item_class = preload("property_item.tscn")
var remove_icon = preload("icons/icon_remove.png")
onready var custom_properties_box = get_node("Body/Scroll/CustomProperties")
onready var no_custom_properties_label = get_node("Body/Scroll/CustomProperties/NoCustomPropertiesLabel")
onready var item_manager = null # Item Manager, used to load, modify and save items
signal on_item_changed(item)
signal new_custom_property_created
signal custom_property_add_requested
signal custom_property_delete_requested(custom_property_id)
#TODO: Somehow the properties are initialized twice
func _ready():
pass
self.item_manager = Globals.get("item_manager")
func build_properties(item):
self.item = item
var properties = item._custom_properties
for node in custom_properties_box.get_children():
if node.has_meta("property"):
custom_properties_box.remove_child(node)
var number_of_properties = 0
var property_names = properties.keys()
property_names.sort()
for property_name in property_names:
no_custom_properties_label.hide()
number_of_properties += 1
var container = MarginContainer.new()
var property_item = property_item_class.instance()
var type = properties[property_name][0]
# If there already is a value, read it, otherwise set it to null
var value = null
if properties[property_name].size() == 2:
value = properties[property_name][1]
property_item.initialize(property_name, type, value, 0, "", true)
property_item.connect("custom_property_delete_requested", self, "emit_signal", ["custom_property_delete_requested", property_name, ])
property_item.connect("property_item_load_button_down", self, "_property_item_requests_file_dialog", [])
var changed_values = []
property_item.connect("on_property_value_changed", self, "item_changed", changed_values)
container.set_meta("property", true)
container.add_child(property_item)
custom_properties_box.add_child(container)
pass
if number_of_properties == 0:
no_custom_properties_label.show()
# Fires signal when the item's custom properties is to be updated, delegates to data_editor_gui.
func item_changed(property, value):
if item:
item._custom_properties[property][1] = value
emit_signal("on_item_changed", item)
# Delegates the deletion
func delete_custom_property(property_name):
emit_signal("custom_property_delete_requested", property_name)
# Fires signal when the item's custom properties is to be updated, delegates to data_editor_gui.func _on_NewCustomPropertyButton_button_down():
func _on_NewCustomPropertyButton_button_down():
emit_signal("custom_property_add_requested")

View File

@ -0,0 +1,134 @@
[gd_scene load_steps=4 format=1]
[ext_resource path="res://addons/godot_data_editor/style/light_gray_panel.tres" type="StyleBox" id=1]
[ext_resource path="res://addons/godot_data_editor/custom_properties.gd" type="Script" id=2]
[ext_resource path="res://addons/godot_data_editor/fonts/droid_serif_bold.tres" type="DynamicFont" id=3]
[node name="Panel" type="Panel"]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 0.0
margin/bottom = 0.0
custom_styles/panel = ExtResource( 1 )
script/script = ExtResource( 2 )
[node name="Body" type="VBoxContainer" parent="."]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 10.0
margin/top = 10.0
margin/right = 10.0
margin/bottom = 10.0
alignment = 0
[node name="TitleLabel" type="Label" parent="Body"]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 1260.0
margin/bottom = 2.0
custom_fonts/font = ExtResource( 3 )
text = "Custom Properties"
uppercase = true
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="HSeparator" type="HSeparator" parent="Body"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 6.0
margin/right = 1260.0
margin/bottom = 9.0
[node name="Spacer" type="Control" parent="Body"]
rect/min_size = Vector2( 0, 15 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 13.0
margin/right = 1260.0
margin/bottom = 28.0
[node name="Scroll" type="ScrollContainer" parent="Body"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 32.0
margin/right = 1260.0
margin/bottom = 556.0
scroll/horizontal = true
scroll/vertical = true
[node name="CustomProperties" type="VBoxContainer" parent="Body/Scroll"]
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 2
size_flags/vertical = 3
margin/left = 0.0
margin/top = 0.0
margin/right = 441.0
margin/bottom = 524.0
alignment = 0
[node name="NoCustomPropertiesLabel" type="Label" parent="Body/Scroll/CustomProperties"]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 441.0
margin/bottom = 14.0
text = "There are no custom properties for this item. Click below to add one."
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="NewCustomPropertyButton" type="Button" parent="Body"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 560.0
margin/right = 1260.0
margin/bottom = 580.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Add new custom property"
flat = false
[connection signal="button_down" from="Body/NewCustomPropertyButton" to="." method="_on_NewCustomPropertyButton_button_down"]

View File

@ -0,0 +1,138 @@
extends Node
var item_manager = null
var items = {}
var values = {}
func _init():
# Caution: This item manager may not be in sync with the one used by the editor
self.item_manager = preload("item_manager.gd").new()
self.items = item_manager.items
func get_item(item_class, id):
return item_manager.get_item(item_class, id)
func get_items(item_class):
return item_manager.get_items(item_class)
func _load_item(item_class, id):
items[item_class][id] = item_manager.load_item(item_class, id)
func load_item_value(item, property):
return get_progress(item._class, item._id, property)
func get_progress(item_class, id, property):
if items[item_class].has(id) and items[item_class][id].has(property):
return items[item_class][id][property]
func set_progress(item_class, id, property, value):
var item = item_manager.get_item(item_class, id)
var has_value = item.get(property)
if item and has_value:
item.set(property, value)
if has_user_signal("@any_value_changed"):
emit_signal("@any_value_changed", item, property, value)
var signal_name = ""
signal_name = "@" + item_class
# Class signal
if has_user_signal(signal_name):
emit_signal(signal_name, item, property, value)
# Item signal
signal_name = "@" + item_class + "|" + id
if has_user_signal(signal_name):
emit_signal(signal_name, item, property, value)
# Property signal
signal_name = "@" + item_class + "|" + id + "|" + property
if has_user_signal(signal_name):
emit_signal(signal_name, item, property, value)
return true
else:
return false
func observe_all_changes(observer, method, binds=[], flags = 0):
var signal_name = "@any_value_changed"
self.add_user_signal(signal_name) # TODO: Args
self.connect(signal_name, observer, method, binds, flags)
func observe_class(observer, item_class, method, binds=[], flags = 0):
var signal_name = "@" + item_class
self.add_user_signal(signal_name) # TODO: Args
self.connect(signal_name, observer, method, binds, flags)
func observe_item(observer, item, method, binds=[], flags = 0):
var signal_name = "@" + item._class + "|" + item._id
if not has_user_signal(signal_name):
self.add_user_signal(signal_name) # TODO: Args
self.connect(signal_name, observer, method, binds, flags)
func observe_item_property(observer, item, property, method, binds=[], flags = 0):
var signal_name = "@" + item._class + "|" + item._id + "|" + property
if not has_user_signal(signal_name):
self.add_user_signal(signal_name) # TODO: Args
self.connect(signal_name, observer, method, binds, flags)
func _get_relevant_connections():
var relevant_connections = []
var signals = get_signal_list()
for s in signals:
var name = s["name"]
if name.begins_with("@"):
for c in get_signal_connection_list(name):
relevant_connections.append(c)
return relevant_connections
func stop_observing_class(observer, item_class):
var connection_list = _get_relevant_connections()
for connection in connection_list:
var target = connection["target"]
var signal_info = connection["signal"].replace("@", "").split("|")
if signal_info.size() == 1 and signal_info[0] == item_class and target == observer:
self.disconnect(connection["signal"], target, connection["method"])
func stop_observing_item(observer, item):
var connection_list = _get_relevant_connections()
for connection in connection_list:
var target = connection["target"]
var signal_info = connection["signal"].replace("@", "").split("|")
if signal_info.size() == 2 and signal_info[0] == item._class and signal_info[1] == item._id and target == observer:
self.disconnect(connection["signal"], target, connection["method"])
func stop_observing_item_property(observer, item, property):
var connection_list = _get_relevant_connections()
for connection in connection_list:
var target = connection["target"]
var signal_info = connection["signal"].replace("@", "").split("|")
if signal_info.size() == 3 and signal_info[0] == item._class and signal_info[1] == item._id and signal_info[2] == property and target == observer:
self.disconnect(connection["signal"], target, connection["method"])
func stop_observing_changes(observer):
var connection_list = _get_relevant_connections()
for connection in connection_list:
var target = connection["target"]
if target == observer:
self.disconnect(connection["signal"], target, connection["method"])
# observer.disconnect(
func set_item_progress(item, property, value):
set_progress(item._class, item._id, property, value)
func get_progress_by_item(item):

View File

@ -0,0 +1,97 @@
tool
extends EditorPlugin
var data_editor_class = preload("data_editor_gui.tscn")
var data_class = preload("data.gd")
var gui = null
var all_items = {}
signal data_item_class_opened(item_class)
func _enter_tree():
OS.set_low_processor_usage_mode(true)
check_for_data_singleton()
check_plugin_settings()
gui = data_editor_class.instance()
get_editor_viewport().add_child(gui)
gui.set_area_as_parent_rect()
gui.hide()
# Remove control and data singleton
func _exit_tree():
OS.set_low_processor_usage_mode(false)
get_editor_viewport().remove_child(gui)
gui.free()
var config = ConfigFile.new()
var status = config.load("res://engine.cfg")
if status == OK:
if config.has_section_key("autoload", "data"):
config.set_value("autoload", "data", null)
config.save("res://engine.cfg")
# Check if the Classes and Data folders exist
Globals.clear("item_manager")
func _ready():
gui.connect("class_edit_requested", self, "edit_class", [])
Globals.set("debug_is_editor", true)
# Opens the selected class in the Script Editor
func edit_class(item_class):
edit_resource(item_class)
func check_for_data_singleton():
var config = ConfigFile.new()
var status = config.load("res://engine.cfg")
if status == OK:
if not config.has_section_key("autoload", "data"):
config.set_value("autoload", "data", "*res://addons/godot_data_editor/data.gd")
config.save("res://engine.cfg")
#var directory = Directory.new()
#directory.copy("res://engine.cfg", "res://engine.cfg_BACKUP")
# Load the plugin settings and adds default if they do not exist.
# TODO: Obtain defaults from dialog
func check_plugin_settings():
var config = ConfigFile.new()
var status = config.load("res://addons/godot_data_editor/plugin.cfg")
if status == OK:
if not config.has_section_key("custom", "class_directory"):
config.set_value("custom", "class_directory", "res://classes")
# TODO: Create folders
if not config.has_section_key("custom", "extension"):
config.set_value("custom", "extension", "json")
if not config.has_section_key("custom", "output_directory"):
config.set_value("custom", "output_directory", "res://data")
# TODO: Create folders
if not config.has_section_key("custom", "password"):
config.set_value("custom", "password", "")
if not config.has_section_key("custom", "sanitize_ids"):
config.set_value("custom", "sanitize_ids", true)
if not config.has_section_key("custom", "serializer"):
config.set_value("custom", "serializer", "json")
config.save("res://addons/godot_data_editor/plugin.cfg")
# Virtual: Name of the tool button on top
func get_name():
return "Data"
# Virtual: Makes sure that the control owns the main screen
func has_main_screen():
return true
# Virtual:
func make_visible(visible):
if(visible):
gui.reload()
gui.show()
else:
gui.hide()

View File

@ -0,0 +1,405 @@
tool
extends Control
var selected_item = null
var selected_id = null
var selected_class = null
onready var item_tree = get_node("VBox/Body/ItemTree")
onready var id_label = get_node("VBox/Body/Content/VBox/Container/ItemIdLabel")
onready var instance_details = get_node("VBox/Body/Content/VBox/InstanceDetails/")
onready var class_properties = get_node("VBox/Body/Content/VBox/InstanceDetails/HBox/ClassProperties")
onready var custom_properties = get_node("VBox/Body/Content/VBox/InstanceDetails/HBox/CustomProperties")
onready var class_overview = get_node("VBox/Body/Content/VBox/ClassOverview")
onready var no_classes = get_node("VBox/Body/Content/VBox/NoClasses")
#onready var last_modified_date = get_node("VBox/Body/Content/VBox/Container/GridContainer/LastModifiedDate")
#onready var created_date = get_node("VBox/Body/Content/VBox/Container/GridContainer/CreatedDate")
onready var new_custom_property_dialog = get_node("NewCustomPropertyDialog")
onready var new_custom_property_name = get_node("NewCustomPropertyDialog/LineEdit")
onready var new_custom_property_type_options = get_node("NewCustomPropertyDialog/TypeOptions")
onready var add_button = get_node("VBox/Head/Add")
onready var delete_button = get_node("VBox/Head/Delete")
onready var duplicate_button = get_node("VBox/Head/Duplicate")
onready var change_display_name_button = get_node("VBox/Body/Content/VBox/Container/HBox/DisplayName")
onready var rename_button = get_node("VBox/Head/Rename")
onready var save_button = get_node("VBox/Head/Save")
onready var save_all_button = get_node("VBox/Head/SaveAll")
onready var copy_id_button = get_node("VBox/Body/Content/VBox/Container/HBox/CopyId")
onready var edit_class_button = get_node("VBox/Body/Content/VBox/Container/HBox/EditClass")
# Dialogs
onready var input_dialog = get_node("InputDialog")
onready var new_item_class_dialog = get_node("NewClassDialog")
onready var new_item_class_name = get_node("NewClassDialog/ClassName")
onready var new_item_class_icon = get_node("NewClassDialog/ClassIconPath")
onready var new_item_class_icon_dialog = get_node("NewClassDialog/ClassIconFileDialog")
onready var warn_dialog = get_node("WarnDialog")
onready var options_screen = get_node("OptionsDialog")
var item_tree_class = preload("item_tree.tscn")
#var active_element = null
var item_manager = null
signal class_edit_requested(script)
signal input_dialog_confirmed(text1, text2)
# First initialize the item manager which is used for loading, saving and configs
func _init():
item_manager = preload("item_manager.gd").new() # This item_manager will add itself to the globals
func _ready():
Globals.set("debug_is_editor", false)
# Tree signals
item_tree.connect("on_new_item_pressed", self, "handle_actions", ["add"])
item_tree.connect("on_rename_pressed", self, "handle_actions", ["rename"])
item_tree.connect("on_delete_pressed", self, "handle_actions", ["delete"])
item_tree.connect("on_duplicate_pressed", self, "handle_actions", ["duplicate"])
item_tree.connect("on_item_selected", self, "change_item_context", [])
item_tree.connect("on_open", self, "open_item", [])
custom_properties.connect("custom_property_add_requested", self, "handle_actions", ["add_custom_property"])
custom_properties.connect("new_custom_property_created", self, "handle_actions", ["add_custom_property"])
custom_properties.connect("custom_property_delete_requested", self, "delete_custom_property", [])
class_properties.connect("on_item_changed", self, "toggle_item_dirty_state", [])
options_screen.connect("extension_changed", item_manager, "rename_extension_of_all_items", [])
options_screen.connect("encryption_changed", item_manager, "delete_and_resave", [])
item_manager.connect("class_insertion_failed", self, "show_warning", [])
item_manager.connect("item_insertion_failed", self, "show_warning", [])
item_manager.connect("custom_property_insertion_failed", self, "show_warning", [])
item_manager.connect("item_duplication_failed", self, "show_warning", [])
# item_manager.connect("class_is_invalid", self, "show_warning", [])
# Add types to the custom property type dropdown
var type_names = item_manager.type_names.keys()
type_names.sort()
new_custom_property_type_options.clear()
var index = 0
for type in type_names:
new_custom_property_type_options.add_item(type)
new_custom_property_type_options.set_item_metadata(index, item_manager.type_names[type])
index += 1
# No classes available
var has_no_classes = item_manager.classes.size() == 0
if has_no_classes:
change_display_name_button.set_disabled(has_no_classes)
duplicate_button.set_disabled(true)
save_button.set_disabled(true)
save_all_button.set_disabled(true)
save_all_button.set_disabled(true)
rename_button.set_disabled(true)
add_button.set_disabled(true)
delete_button.set_disabled(true)
copy_id_button.set_disabled(true)
edit_class_button.set_disabled(true)
no_classes.show()
id_label.set_text("No Classes")
instance_details.hide()
class_overview.hide()
else:
# Select the first item in the tree when loading the GUI
var all_classes = item_manager.classes.keys()
all_classes.sort()
selected_class = all_classes[0]
change_item_context(selected_item, selected_class)
# TODO: Implement
func open_item():
var item_path = item_manager.get_full_path(selected_item)
var program = ""
var os_name = OS.get_name()
if os_name == "Windows":
program = "explorer"
item_path = item_path.replace("/", "\\") # ~_~...
# TODO: Not sure if these work... Probably add the possibility to add a custom editor
elif os_name == "OSX":
program = "open"
else:
program = "nautilus"
OS.execute(program, [item_path], false)
func change_item_context(selected_item, selected_class):
if selected_class:
self.selected_class = selected_class
# TODO: Move to method, clean up
var has_no_classes = item_manager.classes.size() == 0
if has_no_classes:
change_display_name_button.set_disabled(has_no_classes)
duplicate_button.set_disabled(true)
save_button.set_disabled(true)
save_all_button.set_disabled(true)
save_all_button.set_disabled(true)
rename_button.set_disabled(true)
add_button.set_disabled(true)
delete_button.set_disabled(true)
copy_id_button.set_disabled(true)
edit_class_button.set_disabled(true)
no_classes.show()
instance_details.hide()
class_overview.hide()
id_label.set_text("No Classes")
# An item was selected
if selected_item:
# Context was lost, e.g. because of changes to the classes. Reload.
if selected_item and not selected_item.get("_id"):
self.item_manager.load_manager()
self.item_tree.load_tree(true)
selected_item = item_tree.select_first_element()
change_display_name_button.set_disabled(false)
duplicate_button.set_disabled(false)
save_button.set_disabled(false)
save_all_button.set_disabled(false)
rename_button.set_disabled(false)
add_button.set_disabled(false)
delete_button.set_disabled(false)
copy_id_button.set_disabled(false)
edit_class_button.set_disabled(false)
self.selected_item = selected_item
self.selected_id = selected_item._id
class_overview.hide()
no_classes.hide()
instance_details.show()
if selected_item._display_name == selected_id:
id_label.set_text(selected_id)
else:
id_label.set_text(selected_item._display_name + " (" + selected_id + ")")
class_properties.build_properties(selected_item)
custom_properties.build_properties(selected_item)
# A class was selected
elif selected_class:
change_display_name_button.set_disabled(true)
duplicate_button.set_disabled(true)
save_button.set_disabled(true)
save_all_button.set_disabled(false)
rename_button.set_disabled(false)
add_button.set_disabled(false)
delete_button.set_disabled(false)
copy_id_button.set_disabled(false)
edit_class_button.set_disabled(false)
self.selected_item = null
self.selected_id = null
id_label.set_text(selected_class.capitalize())
if item_manager.invalid_classes.has(selected_class):
class_overview.set_label("There is a problem with this class, please check if there are any issues. Press 'Reload' once you are ready.")
else:
class_overview.set_label("")
class_overview.show()
instance_details.hide()
no_classes.hide()
func _on_ItemTree_on_new_item_created(new_item):
selected_item = new_item
func create_shortcut(keys):
var short_cut = ShortCut.new()
var input_event = InputEvent()
input_event.type = InputEvent.KEY
input_event.ID = keys
short_cut.set_shortcut(input_event)
# TODO: Implement
func warn_about_reload():
if item_manager.has_unsaved_items():
input_dialog.popup(self, "reload_confirmed", tr("Confirm reload"), tr("Some changes have not been saved. \nThey will be discarded if you proceed. Are you sure you want to perform this action?"))
func reload():
item_manager.load_manager()
item_tree.load_tree(true)
if item_manager.get_item(selected_class, selected_id):
item_tree.select_item(item_manager.get_item(selected_class, selected_id))
func toggle_item_dirty_state(item):
item._dirty = true
item_tree.set_tree_item_label_text(item)
# Validation takes place in the item manager
func _on_NewCustomPropertyDialog_confirmed():
var custom_property_id = new_custom_property_name.get_text().strip_edges()
var custom_property_type = new_custom_property_type_options.get_selected_metadata()
var success = item_manager.add_custom_property(selected_item, custom_property_id, custom_property_type)
if success:
item_tree.set_tree_item_label_text(selected_item)
toggle_item_dirty_state(selected_item)
custom_properties.build_properties(selected_item)
# TODO: Show confirmation dialog
func delete_custom_property(property_name):
item_manager.delete_custom_property(selected_item, property_name)
toggle_item_dirty_state(selected_item)
custom_properties.build_properties(selected_item)
# TODO: New Class Dialog is still a mess
func _on_AddClassButton_button_down():
new_item_class_name.set_text("")
new_item_class_icon.set_text("")
new_item_class_icon_dialog.set_current_path("")
new_item_class_dialog.popup_centered()
new_item_class_name.grab_focus()
func _on_NewClassDialog_confirmed():
var name = new_item_class_name.get_text().to_lower()
var icon_path = new_item_class_icon.get_text()
item_manager.create_class(name, icon_path)
item_tree.load_tree()
item_tree.select_class(name)
reload()
edit_class()
# New Class Dialog
func _on_NewClassIconSearchButton_button_down():
new_item_class_icon_dialog.popup_centered()
# Icon for new class was selected
func _on_NewClassIconFileDialog_file_selected(path):
new_item_class_icon.set_text(path)
# General handler for a lot of actions to centralize the GUI logic a bit
func handle_actions(action, argument = ""):
if action == "add":
input_dialog.popup(self, "_on_add_item_confirmed", tr("New Item"), tr("Please enter an ID for and optionally a display name the new item"), tr("ID"), "", tr("Display Name (optional)"), "")
elif action == "rename":
if selected_item:
input_dialog.popup(self, "_on_rename_item_confirmed", tr("Rename Item"), tr("Please enter a new ID for this item."), "ID", selected_id)
else:
input_dialog.popup(self, "_on_rename_class_confirmed", tr("Rename Class"), tr("Please enter a new name for this class. All pending changes will be discarded!"), "ID", selected_class)
elif action == "duplicate":
var new_display_name = ""
if selected_item._dirty:
input_dialog.popup(self, "item_duplication_failed", tr("Item duplication failed"), tr("Before duplicating this item, please first save it."))
return
selected_item._display_name = ""
input_dialog.popup(self, "_on_duplicate_confirmed", tr("Duplicate Item"), tr("Please enter a new ID for this item"), "ID", selected_id, tr("Display Name (optional)"), new_display_name)
elif action == "save":
item_manager.save_item(selected_item)
item_tree.load_tree()
#reload()
elif action == "save_all":
item_manager.save_all_items()
item_tree.load_tree()
#reload()
elif action == "reload":
item_manager.load_manager()
reload()
elif action == "new_class":
_on_AddClassButton_button_down() # TODO: Incorporate into dialog handling
elif action == "delete":
if selected_item:
input_dialog.popup(self, "_on_delete_item_confirmed", tr("Delete Item"), tr("Are you sure you want to delete this item?"))
else:
input_dialog.popup(self, "_on_delete_class_confirmed", tr("Delete Class"), tr("Are you sure you want to delete class along with all items?"))
elif action == "options":
options_screen.popup_centered()
elif action == "edit_class":
edit_class()
elif action == "copy_id":
copy_id()
elif action == "change_display_name":
input_dialog.popup(self, "change_display_name", tr("Change Display Name"), tr("Please enter a display name for this item."), "Display Name", selected_item._display_name)
elif action == "add_custom_property":
new_custom_property_name.set_text("")
new_custom_property_dialog.popup_centered()
new_custom_property_name.grab_focus()
#########################################################################
# Handlers #
#########################################################################
func _on_add_item_confirmed(id, display_name):
var new_item = item_manager.create_and_add_new_item(selected_class, id, display_name)
if new_item:
item_tree.add_leaf(new_item, true)
func _on_rename_item_confirmed(id):
item_manager.rename_item(selected_item, id)
reload()
func _on_rename_class_confirmed(name):
item_manager.rename_class(selected_class, name)
reload()
func _on_duplicate_confirmed(id, display_name):
var duplicated_item = item_manager.duplicate_item(selected_item, id, display_name, false)
item_tree.add_leaf(duplicated_item, true)
reload()
func _on_delete_item_confirmed():
item_manager.delete_item(selected_item)
reload()
func _on_delete_class_confirmed():
item_manager.delete_class(selected_class)
if item_manager.classes.size() > 0:
item_tree.select_class(item_manager.class_names[0])
else:
change_item_context(null, null)
reload()
#########################################################################
# Buttons on the right #
#########################################################################
func change_display_name(new_name):
selected_item._display_name = new_name
toggle_item_dirty_state(selected_item)
change_item_context(selected_item, selected_class)
func copy_id():
if selected_item:
OS.set_clipboard(selected_id)
else:
OS.set_clipboard(selected_class)
func edit_class():
var script = item_manager.classes[selected_class]
emit_signal("class_edit_requested", script)
#####################################################
# OTHERS
#####################################################
func show_warning(title, text):
warn_dialog.set_title(title)
warn_dialog.set_text(text)
warn_dialog.popup_centered()
func log_text(text):
var file = File.new()
file.open("res://test.log", File.READ_WRITE)
var old_text = file.get_as_text()
var date = str(OS.get_datetime()["hour"]) + ":" + str(OS.get_datetime()["minute"]) + ":" + str(OS.get_datetime()["second"]) + "\t"
file.store_line(old_text + date + text)

View File

@ -0,0 +1,834 @@
[gd_scene load_steps=22 format=1]
[ext_resource path="res://addons/godot_data_editor/data_editor_gui.gd" type="Script" id=1]
[ext_resource path="res://addons/godot_data_editor/icons/icon_add.png" type="Texture" id=2]
[ext_resource path="res://addons/godot_data_editor/icons/icon_save.png" type="Texture" id=3]
[ext_resource path="res://addons/godot_data_editor/icons/icon_rename.png" type="Texture" id=4]
[ext_resource path="res://addons/godot_data_editor/icons/icon_duplicate.png" type="Texture" id=5]
[ext_resource path="res://addons/godot_data_editor/icons/icon_remove.png" type="Texture" id=6]
[ext_resource path="res://addons/godot_data_editor/icons/icon_reload_small.png" type="Texture" id=7]
[ext_resource path="res://addons/godot_data_editor/icons/icon_script.png" type="Texture" id=8]
[ext_resource path="res://addons/godot_data_editor/icons/icon_options.png" type="Texture" id=9]
[ext_resource path="res://addons/godot_data_editor/item_tree.tscn" type="PackedScene" id=10]
[ext_resource path="res://addons/godot_data_editor/icons/icon_display-name.png" type="Texture" id=11]
[ext_resource path="res://addons/godot_data_editor/icons/icon_copy.png" type="Texture" id=12]
[ext_resource path="res://addons/godot_data_editor/icons/icon_edit.png" type="Texture" id=13]
[ext_resource path="res://addons/godot_data_editor/fonts/droid_sans_title.tres" type="DynamicFont" id=14]
[ext_resource path="res://addons/godot_data_editor/class_properties.tscn" type="PackedScene" id=15]
[ext_resource path="res://addons/godot_data_editor/custom_properties.tscn" type="PackedScene" id=16]
[ext_resource path="res://addons/godot_data_editor/class_overview.tscn" type="PackedScene" id=17]
[ext_resource path="res://addons/godot_data_editor/no_classes.tscn" type="PackedScene" id=18]
[ext_resource path="res://addons/godot_data_editor/warn.gd" type="Script" id=19]
[ext_resource path="res://addons/godot_data_editor/options.tscn" type="PackedScene" id=20]
[ext_resource path="res://addons/godot_data_editor/input_dialog.tscn" type="PackedScene" id=21]
[node name="godot_data_editor" type="Control"]
anchor/right = 1
anchor/bottom = 1
rect/min_size = Vector2( 800, 0 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 0.0
margin/right = 0.0
margin/bottom = 0.0
script/script = ExtResource( 1 )
[node name="VBox" type="VBoxContainer" parent="."]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 0.0
margin/right = 0.0
margin/bottom = 0.0
alignment = 0
[node name="Head" type="HBoxContainer" parent="VBox"]
rect/min_size = Vector2( 0, 22 )
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 1280.0
margin/bottom = 28.0
alignment = 0
[node name="Add" type="ToolButton" parent="VBox/Head"]
rect/min_size = Vector2( 28, 28 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 56.0
margin/bottom = 28.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Add"
icon = ExtResource( 2 )
flat = true
align = 0
[node name="VSeparator5" type="VSeparator" parent="VBox/Head"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 60.0
margin/top = 0.0
margin/right = 63.0
margin/bottom = 28.0
[node name="Save" type="ToolButton" parent="VBox/Head"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 67.0
margin/top = 0.0
margin/right = 127.0
margin/bottom = 28.0
disabled = true
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Save"
icon = ExtResource( 3 )
flat = false
[node name="SaveAll" type="ToolButton" parent="VBox/Head"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 131.0
margin/top = 0.0
margin/right = 212.0
margin/bottom = 28.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Save All"
icon = ExtResource( 3 )
flat = false
[node name="VSeparator" type="VSeparator" parent="VBox/Head"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 216.0
margin/top = 0.0
margin/right = 219.0
margin/bottom = 28.0
[node name="Rename" type="ToolButton" parent="VBox/Head"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 223.0
margin/top = 0.0
margin/right = 306.0
margin/bottom = 28.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Rename"
icon = ExtResource( 4 )
flat = false
[node name="Duplicate" type="ToolButton" parent="VBox/Head"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 310.0
margin/top = 0.0
margin/right = 402.0
margin/bottom = 28.0
disabled = true
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Duplicate"
icon = ExtResource( 5 )
flat = false
[node name="Delete" type="ToolButton" parent="VBox/Head"]
rect/min_size = Vector2( 28, 28 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 406.0
margin/top = 0.0
margin/right = 480.0
margin/bottom = 28.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Delete"
icon = ExtResource( 6 )
flat = true
[node name="VSeparator3" type="VSeparator" parent="VBox/Head"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 484.0
margin/top = 0.0
margin/right = 487.0
margin/bottom = 28.0
[node name="Refresh2" type="ToolButton" parent="VBox/Head"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 491.0
margin/top = 0.0
margin/right = 563.0
margin/bottom = 28.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Reload"
icon = ExtResource( 7 )
flat = false
[node name="VSeparator2" type="VSeparator" parent="VBox/Head"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 567.0
margin/top = 0.0
margin/right = 570.0
margin/bottom = 28.0
[node name="NewClass" type="ToolButton" parent="VBox/Head"]
rect/min_size = Vector2( 28, 28 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 574.0
margin/top = 0.0
margin/right = 670.0
margin/bottom = 28.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "New Class"
icon = ExtResource( 8 )
flat = true
align = 0
[node name="VSeparator4" type="VSeparator" parent="VBox/Head"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 674.0
margin/top = 0.0
margin/right = 677.0
margin/bottom = 28.0
[node name="Options" type="ToolButton" parent="VBox/Head"]
rect/min_size = Vector2( 28, 28 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 681.0
margin/top = 0.0
margin/right = 763.0
margin/bottom = 28.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Options"
icon = ExtResource( 9 )
flat = true
align = 0
[node name="Search" type="LineEdit" parent="VBox/Head"]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 377.0
margin/top = 0.0
margin/right = 435.0
margin/bottom = 28.0
placeholder/text = "Search"
placeholder/alpha = 0.6
focus_mode = 2
caret/caret_blink = false
caret/caret_blink_speed = 0.65
[node name="HSeparator" type="HSeparator" parent="VBox"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 32.0
margin/right = 1280.0
margin/bottom = 35.0
[node name="Body" type="HSplitContainer" parent="VBox"]
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 39.0
margin/right = 1280.0
margin/bottom = 600.0
split/offset = 0
split/collapsed = false
split/dragger_visibility = 0
[node name="ItemTree" parent="VBox/Body" instance=ExtResource( 10 )]
anchor/right = 0
anchor/bottom = 0
rect/min_size = Vector2( 165, 0 )
size_flags/horizontal = 2
size_flags/stretch_ratio = 0.0
margin/right = 165.0
margin/bottom = 561.0
[node name="Content" type="Panel" parent="VBox/Body"]
visibility/self_opacity = 0.0
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 177.0
margin/top = 0.0
margin/right = 1280.0
margin/bottom = 561.0
[node name="VBox" type="VBoxContainer" parent="VBox/Body/Content"]
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 3
size_flags/vertical = 3
size_flags/stretch_ratio = 0.0
margin/left = 0.0
margin/top = 0.0
margin/right = 0.0
margin/bottom = 0.0
alignment = 0
[node name="Container" type="MarginContainer" parent="VBox/Body/Content/VBox"]
rect/min_size = Vector2( 0, 25 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 1103.0
margin/bottom = 25.0
[node name="HBox" type="HBoxContainer" parent="VBox/Body/Content/VBox/Container"]
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 8.0
margin/top = 0.0
margin/right = 1103.0
margin/bottom = 25.0
custom_constants/separation = 15
alignment = 2
[node name="DisplayName" type="ToolButton" parent="VBox/Body/Content/VBox/Container/HBox"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 0
size_flags/vertical = 2
margin/left = 722.0
margin/top = 0.0
margin/right = 892.0
margin/bottom = 25.0
disabled = true
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Change Display Name"
icon = ExtResource( 11 )
flat = true
align = 0
[node name="CopyId" type="ToolButton" parent="VBox/Body/Content/VBox/Container/HBox"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 0
size_flags/vertical = 2
margin/left = 907.0
margin/top = 0.0
margin/right = 988.0
margin/bottom = 25.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Copy ID"
icon = ExtResource( 12 )
flat = true
align = 0
[node name="EditClass" type="ToolButton" parent="VBox/Body/Content/VBox/Container/HBox"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 0
size_flags/vertical = 2
margin/left = 1003.0
margin/top = 0.0
margin/right = 1095.0
margin/bottom = 25.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Edit Class"
icon = ExtResource( 13 )
flat = true
align = 0
[node name="ItemIdLabel" type="Label" parent="VBox/Body/Content/VBox/Container"]
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 8.0
margin/top = 0.0
margin/right = 1103.0
margin/bottom = 25.0
custom_fonts/font = ExtResource( 14 )
custom_colors/font_color_shadow = Color( 0.300781, 0.300781, 0.300781, 1 )
custom_constants/shadow_offset_x = 1
custom_constants/shadow_offset_y = 1
text = "Actor"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="GridContainer" type="GridContainer" parent="VBox/Body/Content/VBox/Container"]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 0
size_flags/vertical = 2
margin/left = 555.0
margin/top = 0.0
margin/right = 555.0
margin/bottom = 25.0
custom_constants/hseparation = 10
columns = 2
[node name="Created" type="Label" parent="VBox/Body/Content/VBox/Container/GridContainer"]
visibility/opacity = 0.25
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 0.0
margin/right = 91.0
margin/bottom = 14.0
text = "Created:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="CreatedDate" type="Label" parent="VBox/Body/Content/VBox/Container/GridContainer"]
visibility/opacity = 0.25
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 101.0
margin/top = 0.0
margin/right = 217.0
margin/bottom = 14.0
text = "01.01.01 01:01:01"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="LastModifiedLabel" type="Label" parent="VBox/Body/Content/VBox/Container/GridContainer"]
visibility/opacity = 0.25
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 0.0
margin/top = 18.0
margin/right = 91.0
margin/bottom = 32.0
text = "Last modified:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="LastModifiedDate" type="Label" parent="VBox/Body/Content/VBox/Container/GridContainer"]
visibility/opacity = 0.25
focus/ignore_mouse = true
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 0
margin/left = 101.0
margin/top = 18.0
margin/right = 217.0
margin/bottom = 32.0
text = "01.01.01 01:01:01"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="VBoxContainer" type="VBoxContainer" parent="VBox/Body/Content/VBox/Container"]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 8.0
margin/top = 0.0
margin/right = 1103.0
margin/bottom = 25.0
alignment = 0
[node name="HSeparator" type="HSeparator" parent="VBox/Body/Content/VBox"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 2
margin/left = 0.0
margin/top = 29.0
margin/right = 1103.0
margin/bottom = 32.0
[node name="Spacer" type="Control" parent="VBox/Body/Content/VBox"]
rect/min_size = Vector2( 0, 10 )
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 2
margin/left = 0.0
margin/top = 36.0
margin/right = 1103.0
margin/bottom = 46.0
[node name="InstanceDetails" type="PanelContainer" parent="VBox/Body/Content/VBox"]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 0.0
margin/top = 50.0
margin/right = 1103.0
margin/bottom = 561.0
[node name="HBox" type="HBoxContainer" parent="VBox/Body/Content/VBox/InstanceDetails"]
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 7.0
margin/top = 7.0
margin/right = 1096.0
margin/bottom = 504.0
alignment = 0
[node name="ClassProperties" parent="VBox/Body/Content/VBox/InstanceDetails/HBox" instance=ExtResource( 15 )]
anchor/right = 0
anchor/bottom = 0
margin/right = 542.0
margin/bottom = 497.0
[node name="CustomProperties" parent="VBox/Body/Content/VBox/InstanceDetails/HBox" instance=ExtResource( 16 )]
anchor/right = 0
anchor/bottom = 0
size_flags/horizontal = 3
size_flags/vertical = 3
margin/left = 546.0
margin/right = 1089.0
margin/bottom = 497.0
[node name="ClassOverview" parent="VBox/Body/Content/VBox" instance=ExtResource( 17 )]
anchor/right = 0
anchor/bottom = 0
margin/top = 50.0
margin/right = 1103.0
margin/bottom = 561.0
[node name="NoClasses" parent="VBox/Body/Content/VBox" instance=ExtResource( 18 )]
visibility/visible = false
anchor/right = 0
anchor/bottom = 0
margin/left = 0.0
margin/top = 307.0
margin/right = 1103.0
margin/bottom = 561.0
[node name="WarnDialog" type="AcceptDialog" parent="."]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 350.0
margin/bottom = 110.0
popup/exclusive = true
window/title = ""
dialog/hide_on_ok = true
script/script = ExtResource( 19 )
[node name="NewClassDialog" type="ConfirmationDialog" parent="."]
editor/display_folded = true
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 519.0
margin/top = 193.0
margin/right = 990.0
margin/bottom = 316.0
popup/exclusive = true
window/title = "New Class"
dialog/text = "Enter the name and the path to an optional icon"
dialog/hide_on_ok = true
[node name="ClassName" type="LineEdit" parent="NewClassDialog"]
focus_neighbour/bottom = NodePath("../ClassIconPath")
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 8.0
margin/top = 27.0
margin/right = 466.0
margin/bottom = 51.0
placeholder/text = "Name"
placeholder/alpha = 0.6
focus_mode = 2
caret/caret_blink = false
caret/caret_blink_speed = 0.65
[node name="ClassIconPath" type="LineEdit" parent="NewClassDialog"]
focus_neighbour/top = NodePath("../ClassName")
focus_neighbour/right = NodePath("../NewClassIconSearchButton")
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 8.0
margin/top = 60.0
margin/right = 393.0
margin/bottom = 84.0
placeholder/text = "Icon Path (optional)"
placeholder/alpha = 0.6
focus_mode = 2
caret/caret_blink = false
caret/caret_blink_speed = 0.65
[node name="ClassIconFileDialog" type="FileDialog" parent="NewClassDialog"]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 393.0
margin/bottom = 404.0
popup/exclusive = true
window/title = "Open a File"
dialog/hide_on_ok = true
mode = 0
access = 2
filters = StringArray( "*.png" )
show_hidden_files = false
[node name="NewClassIconSearchButton" type="Button" parent="NewClassDialog"]
focus_neighbour/left = NodePath("../ClassIconPath")
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 399.0
margin/top = 61.0
margin/right = 466.0
margin/bottom = 83.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "Search"
flat = false
[node name="OptionsDialog" parent="." instance=ExtResource( 20 )]
visibility/visible = false
margin/right = 550.0
margin/bottom = 310.0
[node name="InputDialog" parent="." instance=ExtResource( 21 )]
visibility/visible = false
[node name="NewCustomPropertyDialog" type="ConfirmationDialog" parent="."]
visibility/visible = false
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 117.0
margin/top = 117.0
margin/right = 489.0
margin/bottom = 243.0
popup/exclusive = false
window/title = "New custom property"
dialog/text = "Enter the name and type of the property"
dialog/hide_on_ok = true
[node name="LineEdit" type="LineEdit" parent="NewCustomPropertyDialog"]
focus_neighbour/bottom = NodePath("../TypeOptions")
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 2
margin/left = 7.0
margin/top = 29.0
margin/right = 363.0
margin/bottom = 53.0
placeholder/text = "Name"
placeholder/alpha = 0.6
focus_mode = 2
caret/caret_blink = false
caret/caret_blink_speed = 0.65
[node name="TypeOptions" type="OptionButton" parent="NewCustomPropertyDialog"]
focus_neighbour/top = NodePath("../LineEdit")
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 7.0
margin/top = 64.0
margin/right = 363.0
margin/bottom = 84.0
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
text = "BOOL"
flat = false
align = 0
selected = 0
items = [ "BOOL", null, false, -1, 1, "COLOR", null, false, -1, 14, "IMAGE", null, false, -1, 15, "INT", null, false, -1, 2, "NODE_PATH", null, false, -1, 16, "OBJECT", null, false, -1, 18, "PLANE", null, false, -1, 9, "QUAT", null, false, -1, 10, "REAL", null, false, -1, 3, "RECT2", null, false, -1, 6, "STRING", null, false, -1, 4, "TRANSFORM", null, false, -1, 13, "VECTOR2", null, false, -1, 5, "VECTOR3", null, false, -1, 7 ]
[connection signal="button_down" from="VBox/Head/Add" to="." method="handle_actions" binds= [ "add" ]]
[connection signal="button_down" from="VBox/Head/Save" to="." method="handle_actions" binds= [ "save" ]]
[connection signal="button_down" from="VBox/Head/SaveAll" to="." method="handle_actions" binds= [ "save_all" ]]
[connection signal="button_down" from="VBox/Head/Rename" to="." method="handle_actions" binds= [ "rename" ]]
[connection signal="button_down" from="VBox/Head/Duplicate" to="." method="handle_actions" binds= [ "duplicate" ]]
[connection signal="button_down" from="VBox/Head/Delete" to="." method="handle_actions" binds= [ "delete" ]]
[connection signal="button_down" from="VBox/Head/Refresh2" to="." method="handle_actions" binds= [ "reload" ]]
[connection signal="button_down" from="VBox/Head/NewClass" to="." method="handle_actions" binds= [ "new_class" ]]
[connection signal="button_down" from="VBox/Head/Options" to="." method="handle_actions" binds= [ "options" ]]
[connection signal="button_down" from="VBox/Body/Content/VBox/Container/HBox/DisplayName" to="." method="handle_actions" binds= [ "change_display_name" ]]
[connection signal="button_down" from="VBox/Body/Content/VBox/Container/HBox/CopyId" to="." method="handle_actions" binds= [ "copy_id" ]]
[connection signal="button_down" from="VBox/Body/Content/VBox/Container/HBox/EditClass" to="." method="handle_actions" binds= [ "edit_class" ]]
[connection signal="confirmed" from="NewClassDialog" to="." method="_on_NewClassDialog_confirmed"]
[connection signal="file_selected" from="NewClassDialog/ClassIconFileDialog" to="." method="_on_NewClassIconFileDialog_file_selected"]
[connection signal="button_down" from="NewClassDialog/NewClassIconSearchButton" to="." method="_on_NewClassIconSearchButton_button_down"]
[connection signal="confirmed" from="NewCustomPropertyDialog" to="." method="_on_NewCustomPropertyDialog_confirmed"]

View File

@ -0,0 +1,55 @@
extends Node
# Class information
# No setter, that's why there is a comma
var _class setget ,get_class
var _class_name setget ,get_class_name
var _dirty = false # TODO: Exclude
var _persistent = false # TODO: Exclude
var _id = ""
var _display_name setget set_display_name,get_display_name
var _created = 0
var _last_modified = 0
# Instance-level custom properties, consists of arrays containing name, type, (hint and hint_text), default value
var _custom_properties = {}
func _ready():
pass
func get_class():
if _class:
return _class
else:
_class = self.get_script().get_path().get_file().basename()
return _class
func get_class_name():
return self.get_class().capitalize()
func get_display_name():
if _display_name == null or _display_name == "":
return self._id
else:
return _display_name
func set_display_name(name):
_display_name = name
func update_property(property, value):
var data_singleton = Globals.get_singleton("data")
if data_singleton:
data_singleton.set_progress(_class, _id, property, value)
func _init(id):
self._id = id

Binary file not shown.

View File

@ -0,0 +1,11 @@
[gd_resource type="DynamicFont" load_steps=2 format=1]
[ext_resource path="res://addons/godot_data_editor/fonts/DroidSans.ttf" type="DynamicFontData" id=1]
[resource]
font/size = 22
font/use_mipmaps = false
font/use_filter = false
font/font = ExtResource( 1 )

View File

@ -0,0 +1,11 @@
[gd_resource type="DynamicFont" load_steps=2 format=1]
[ext_resource path="res://addons/godot_data_editor/fonts/DroidSerif-Bold.ttf" type="DynamicFontData" id=1]
[resource]
font/size = 16
font/use_mipmaps = false
font/use_filter = false
font/font = ExtResource( 1 )

View File

@ -0,0 +1,11 @@
[gd_resource type="DynamicFont" load_steps=2 format=1]
[ext_resource path="res://addons/godot_data_editor/fonts/DroidSerif-Italic.ttf" type="DynamicFontData" id=1]
[resource]
font/size = 16
font/use_mipmaps = false
font/use_filter = false
font/font = ExtResource( 1 )

View File

@ -0,0 +1,11 @@
[gd_resource type="DynamicFont" load_steps=2 format=1]
[ext_resource path="res://addons/godot_data_editor/fonts/DroidSerif-Italic.ttf" type="DynamicFontData" id=1]
[resource]
font/size = 16
font/use_mipmaps = false
font/use_filter = false
font/font = ExtResource( 1 )

Binary file not shown.

After

Width:  |  Height:  |  Size: 939 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

View File

@ -0,0 +1,58 @@
tool
extends ConfirmationDialog
#var text = ""
#var title = ""
var placeholder_1 = ""
var placeholder_2 = ""
var caller = null
var callback_method = ""
onready var line_edit_1 = get_node("VBox/LineEdit1")
onready var line_edit_2 = get_node("VBox/LineEdit2")
#func _init(text, placerholder_1 = "", placeholder_2 = ""):
func popup(caller, callback_method, title, text, placeholder_1 = "", default_text_1 = "", placeholder_2 = "", default_text_2 = ""):
self.caller = caller
self.callback_method = callback_method
self.placeholder_1 = placeholder_1
self.placeholder_2 = placeholder_2
if not caller.is_connected("input_dialog_confirmed", caller, callback_method):
caller.connect("input_dialog_confirmed", caller, callback_method, [])
set_text(text)
set_title(title)
if placeholder_1 == "":
line_edit_1.hide()
else:
line_edit_1.show()
line_edit_1.set_placeholder(placeholder_1)
if placeholder_2 == "":
line_edit_2.hide()
else:
line_edit_2.show()
line_edit_2.set_placeholder(placeholder_2)
line_edit_1.set_text(default_text_1)
line_edit_2.set_text(default_text_2)
self.popup_centered()
if not line_edit_1.is_hidden():
line_edit_1.grab_focus()
func _on_ConfirmationDialog_confirmed():
var text1 = line_edit_1.get_text().strip_edges()
var text2 = line_edit_2.get_text().strip_edges()
if placeholder_2:
caller.emit_signal("input_dialog_confirmed", text1, text2)
elif placeholder_1:
caller.emit_signal("input_dialog_confirmed", text1)
else:
caller.emit_signal("input_dialog_confirmed")
caller.disconnect("input_dialog_confirmed", caller, callback_method)

View File

@ -0,0 +1,71 @@
[gd_scene load_steps=2 format=1]
[ext_resource path="res://addons/godot_data_editor/input_dialog.gd" type="Script" id=1]
[node name="ConfirmationDialog" type="ConfirmationDialog"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 440.0
margin/bottom = 150.0
popup/exclusive = true
window/title = "Please Confirm..."
dialog/text = "Text"
dialog/hide_on_ok = true
script/script = ExtResource( 1 )
[node name="VBox" type="VBoxContainer" parent="."]
anchor/top = 1
anchor/right = 1
anchor/bottom = 1
focus/ignore_mouse = false
focus/stop_mouse = false
size_flags/horizontal = 2
size_flags/vertical = 2
margin/left = 8.0
margin/top = 103.0
margin/right = 8.0
margin/bottom = 45.0
custom_constants/separation = 10
alignment = 0
[node name="LineEdit1" type="LineEdit" parent="VBox"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 2
margin/left = 0.0
margin/top = 0.0
margin/right = 424.0
margin/bottom = 24.0
placeholder/text = "Hint 1"
placeholder/alpha = 0.6
focus_mode = 2
caret/caret_blink = false
caret/caret_blink_speed = 0.65
[node name="LineEdit2" type="LineEdit" parent="VBox"]
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 3
size_flags/vertical = 2
margin/left = 0.0
margin/top = 34.0
margin/right = 424.0
margin/bottom = 58.0
placeholder/text = "Hint 2"
placeholder/alpha = 0.6
focus_mode = 2
caret/caret_blink = false
caret/caret_blink_speed = 0.65
[connection signal="confirmed" from="." to="." method="_on_ConfirmationDialog_confirmed"]

Some files were not shown because too many files have changed in this diff Show More