From b9155df06303adf69d4e18ff38ea1b0459a416d8 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sat, 27 Feb 2016 23:10:44 -0300 Subject: [PATCH] Completed the support for plugins! It is not possible to add plugins. Not all APIs are provided yet, please request whathever you are missing. Some example plugins are provided in demos/plugins. Just copy them to a folder in your project named addons/ and then enable them from the project settings. Have fun! --- plugins/custom_dock/custom_dock.scn | Bin 0 -> 1494 bytes plugins/custom_dock/dock_plugin.gd | 23 ++++ plugins/custom_dock/plugin.cfg | 14 +++ plugins/custom_import_plugin/import_plugin.gd | 81 +++++++++++++ .../custom_import_plugin/material_dialog.gd | 67 +++++++++++ .../custom_import_plugin/material_dialog.tscn | 111 ++++++++++++++++++ .../custom_import_plugin/material_import.gd | 22 ++++ plugins/custom_import_plugin/plugin.cfg | 14 +++ plugins/custom_import_plugin/test.mtxt | 1 + plugins/custom_node/heart.gd | 12 ++ plugins/custom_node/heart.png | Bin 0 -> 12584 bytes plugins/custom_node/heart_icon.png | Bin 0 -> 809 bytes plugins/custom_node/heart_plugin.gd | 18 +++ plugins/custom_node/plugin.cfg | 14 +++ plugins/readme.txt | 13 ++ 15 files changed, 390 insertions(+) create mode 100644 plugins/custom_dock/custom_dock.scn create mode 100644 plugins/custom_dock/dock_plugin.gd create mode 100644 plugins/custom_dock/plugin.cfg create mode 100644 plugins/custom_import_plugin/import_plugin.gd create mode 100644 plugins/custom_import_plugin/material_dialog.gd create mode 100644 plugins/custom_import_plugin/material_dialog.tscn create mode 100644 plugins/custom_import_plugin/material_import.gd create mode 100644 plugins/custom_import_plugin/plugin.cfg create mode 100644 plugins/custom_import_plugin/test.mtxt create mode 100644 plugins/custom_node/heart.gd create mode 100644 plugins/custom_node/heart.png create mode 100644 plugins/custom_node/heart_icon.png create mode 100644 plugins/custom_node/heart_plugin.gd create mode 100644 plugins/custom_node/plugin.cfg create mode 100644 plugins/readme.txt diff --git a/plugins/custom_dock/custom_dock.scn b/plugins/custom_dock/custom_dock.scn new file mode 100644 index 0000000000000000000000000000000000000000..0e32ece2649b83c82e32785c41216a881747c99f GIT binary patch literal 1494 zcmWku3rrMO6uq;vyTc!J5h|ejfGDj*RuN+&wcMFqRQ&O^RY{y3mSK0;*%`Vs3uv2k zl~~ZCrnQZ={!mk!+K-K?U^FSCY5Y{Hv8f@Zq>M2!O-zgFC#J-dK3;O(d%5?#ch1Yb zc}>lJKg^6AfG4Q{-?;!7fFuKsq?-YTu#iF6%myhGmD`&`vL?g%6p~|C0pogN6NwU&oQar3^zPJ*On87_m zIgU2nBnuhvkP=Ua9!eNKC9LUjS&ZokLxx#47A@_s7Fp^5PvN2gRgCm?M#$;0x#o#{Y>w@0vN1jzQIUc<0Y*9>A z4vxD_xz~go@&?l-7dLX6DRwJ{(ngB-2&iO<+YpVY($!Vm3bV-qHYW9o$vIXTKhM2E zYLivqh?fx(CuC$hc>gS++hZHvMrIgoNR#AB_3&?tG>%rbZuxao{$QpJeMJ>a>yjNG0&-( za?FsN{5{af$DG(DnGpl#lO6>A1s*I8gFzY@TI5_|0`sww3+b9BhV(?SL4ySdRzYy1 z%@kZ)hn%}xiYt<4COe>zRN=2I01X679E?PE-vH8fGr5>a)?fgp2_&Y{OS+RRfe(ka!R6p&K8T>!El(sZmhaUWhKD-+Xv5~GvFh-4(+Eh22WCW7fiea0p!4)_I z&T188tmjQ!5m2z)e+=s>)Binn9>T&vE7sU-6xUF$$L6Be4gVAL((ClVWz43;zyKvi z@gxOcnRNxvP`b?)T2Yuos`zReEvH2-7fw^zzo?!E%jjIjQ$M5l9M5AvKBj>yl-AE@ zQ~C_*A)lno=nKoO=hmp59i_A=pKp7k{$VSMXJ%ZD@$2!Z&5c=6zKkXU71Tq>8nao$ zny~W?zR&g;76h(Qg9dNVQm@uJ$;! z1Sn!n?cToobT~>GU0afKeGbtYTnbhxgC!RgUtk zzUq?|BTrW?-`aU$>S6a+`$r#cn3^6q^2w9U-rVe`D<>!VA8%JK3?CdFFWLp4UOIRC zT*YYVvbVfFpD*w_n7jX;>Zv)iaj^1wV7znJGtau&%MYwOKNZb#=Dhz?Rn~#dsrrlV xFScu0sdxyg?77a2Z-3<82I1_Y@rGAi0b*xCUG1j8*FtbNKvQ#*zlr|n{{tSf;!ywq literal 0 HcmV?d00001 diff --git a/plugins/custom_dock/dock_plugin.gd b/plugins/custom_dock/dock_plugin.gd new file mode 100644 index 00000000..ce8a3bcd --- /dev/null +++ b/plugins/custom_dock/dock_plugin.gd @@ -0,0 +1,23 @@ +tool +extends EditorPlugin + +var dock = null + +func _enter_tree(): + # When this plugin node enters tree, add the custom type + + dock = preload("res://addons/custom_dock/custom_dock.scn").instance() + + add_control_to_dock( DOCK_SLOT_LEFT_UL, dock ) + +func _exit_tree(): + + # Remove from docks (must be called so layout is updated and saved) + remove_control_from_docks(dock) + # Remove the node + dock.free() + + + + + \ No newline at end of file diff --git a/plugins/custom_dock/plugin.cfg b/plugins/custom_dock/plugin.cfg new file mode 100644 index 00000000..e295384c --- /dev/null +++ b/plugins/custom_dock/plugin.cfg @@ -0,0 +1,14 @@ +[plugin] + +name="Custom Dock" +description="Adds a new Customizable Dock" +author="Juan Linietsky" +version="1.0" +script="dock_plugin.gd" + + + + + + + diff --git a/plugins/custom_import_plugin/import_plugin.gd b/plugins/custom_import_plugin/import_plugin.gd new file mode 100644 index 00000000..2cf8a030 --- /dev/null +++ b/plugins/custom_import_plugin/import_plugin.gd @@ -0,0 +1,81 @@ +tool + +extends EditorImportPlugin + + +# Simple plugin that imports a text file with extension .mtxt +# which contains 3 integers in format R,G,B (0-255) +# (see example .mtxt in this folder) +# Imported file is converted to a material + +var dialog = null + +func get_name(): + return "silly_material" + +func get_visible_name(): + return "Silly Material" + +func import_dialog(path): + var md = null + if (path!=""): + md = ResourceLoader.load_import_metadata(path) + dialog.configure(self,path,md) + dialog.popup_centered() + +func import(path,metadata): + + assert(metadata.get_source_count() == 1) + + var source = metadata.get_source_path(0) + var use_red_anyway = metadata.get_option("use_red_anyway") + + var f = File.new() + var err = f.open(source,File.READ) + if (err!=OK): + return ERR_CANT_OPEN + + var l = f.get_line() + + f.close() + + var channels = l.split(",") + if (channels.size()!=3): + return ERR_PARSE_ERROR + + var color = Color8(int(channels[0]),int(channels[1]),int(channels[2])) + + var material + + if (ResourceLoader.has(path)): + # Material is in use, update it + material = ResourceLoader.load(path) + else: + # Material not in use, create + material = FixedMaterial.new() + + if (use_red_anyway): + color=Color8(255,0,0) + + material.set_parameter(FixedMaterial.PARAM_DIFFUSE,color) + + # Make sure import metadata links to this plugin + + metadata.set_editor("silly_material") + + # Update the import metadata + + material.set_import_metadata(metadata) + + + # Save + err = ResourceSaver.save(path,material) + + return err + + +func config(base_control): + + dialog = preload("res://addons/custom_import_plugin/material_dialog.tscn").instance() + base_control.add_child(dialog) + diff --git a/plugins/custom_import_plugin/material_dialog.gd b/plugins/custom_import_plugin/material_dialog.gd new file mode 100644 index 00000000..10227432 --- /dev/null +++ b/plugins/custom_import_plugin/material_dialog.gd @@ -0,0 +1,67 @@ +tool +extends ConfirmationDialog + +var src_fs +var dst_fs +var import_plugin + +func configure(p_import_plugin,path,metadata): + import_plugin=p_import_plugin + if (metadata): + # metadata from previous import exists, fill in fields + assert( metadata.get_source_count() > 0 ) + # Always expand the source paths + var src_path = import_plugin.expand_source_path( metadata.get_source_path(0) ) + get_node("src_file").set_text(src_path) + get_node("dst_file").set_text(path) + # Fill in from metadata options + get_node("use_red_anyway").set_pressed( metadata.get_option("use_red_anyway") ) + + +func _ready(): + + src_fs = FileDialog.new() + src_fs.set_mode(FileDialog.MODE_OPEN_FILE) + src_fs.set_access(FileDialog.ACCESS_FILESYSTEM) #access all filesystem, not only res:// + src_fs.add_filter("*.mtxt") + src_fs.connect("file_selected",self,"_on_src_selected") + + add_child(src_fs) + + dst_fs = EditorFileDialog.new() + dst_fs.set_mode(EditorFileDialog.MODE_SAVE_FILE) + dst_fs.add_filter("*.mtl") # Use binary extension always, text can't save metadata + dst_fs.connect("file_selected",self,"_on_dst_selected") + + add_child(dst_fs) + + set_hide_on_ok(true) + get_ok().set_text("Import!") + + +func _on_src_browse_pressed(): + src_fs.popup_centered_ratio() + +func _on_dst_browse_pressed(): + dst_fs.popup_centered_ratio() + +func _on_src_selected(path): + get_node("src_file").set_text(path) + +func _on_dst_selected(path): + get_node("dst_file").set_text(path) + +func _on_MaterialImport_confirmed(): + # Create an import metadata + var imd = ResourceImportMetadata.new() + # Add the source files, always validate the source path + imd.add_source( import_plugin.validate_source_path( get_node("src_file").get_text() )) + # Add the options + imd.set_option( "use_red_anyway", get_node("use_red_anyway").is_pressed() ) + # Perform regular import + var err = import_plugin.import( get_node("dst_file").get_text(), imd ) + # Warn if error + if (err!=OK): + get_node("error").set_text("Error Importing!") + get_node("error").popup_centered_minsize() + diff --git a/plugins/custom_import_plugin/material_dialog.tscn b/plugins/custom_import_plugin/material_dialog.tscn new file mode 100644 index 00000000..9ad6f492 --- /dev/null +++ b/plugins/custom_import_plugin/material_dialog.tscn @@ -0,0 +1,111 @@ +[gd_scene load_steps=2 format=1] + +[ext_resource path="res://addons/custom_import_plugin/material_dialog.gd" type="Script" id=1] + +[node name="MaterialImport" type="ConfirmationDialog"] + +margin/right = 276.0 +margin/bottom = 154.0 +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +popup/exclusive = false +window/title = "Silly Material Import" +dialog/hide_on_ok = true +script/script = ExtResource( 1 ) +__meta__ = { "__editor_plugin_screen__":"Script" } + +[node name="src_file" type="LineEdit" parent="."] + +margin/left = 19.0 +margin/top = 6.0 +margin/right = 190.0 +margin/bottom = 29.0 +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +text = "" +max_length = 0 +editable = true +secret = false + +[node name="src_browse" type="Button" parent="."] + +margin/left = 195.0 +margin/top = 7.0 +margin/right = 249.0 +margin/bottom = 29.0 +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +toggle_mode = false +text = "browse" +flat = false + +[node name="dst_browse" type="Button" parent="."] + +margin/left = 195.0 +margin/top = 47.0 +margin/right = 249.0 +margin/bottom = 69.0 +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +toggle_mode = false +text = "browse" +flat = false + +[node name="dst_file" type="LineEdit" parent="."] + +margin/left = 19.0 +margin/top = 46.0 +margin/right = 190.0 +margin/bottom = 69.0 +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +text = "" +max_length = 0 +editable = true +secret = false + +[node name="use_red_anyway" type="CheckBox" parent="."] + +margin/left = 20.0 +margin/top = 84.0 +margin/right = 144.0 +margin/bottom = 106.0 +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +toggle_mode = true +text = "Use Red Anyway" +flat = false +align = 0 + +[node name="error" type="AcceptDialog" parent="."] + +visibility/visible = false +margin/right = 40.0 +margin/bottom = 40.0 +focus/ignore_mouse = false +focus/stop_mouse = true +size_flags/horizontal = 2 +size_flags/vertical = 2 +popup/exclusive = false +window/title = "Alert!" +dialog/hide_on_ok = true + +[connection signal="confirmed" from="." to="." method="_on_MaterialImport_confirmed"] + +[connection signal="pressed" from="src_browse" to="." method="_on_src_browse_pressed"] + +[connection signal="pressed" from="dst_browse" to="." method="_on_dst_browse_pressed"] + + diff --git a/plugins/custom_import_plugin/material_import.gd b/plugins/custom_import_plugin/material_import.gd new file mode 100644 index 00000000..f9859251 --- /dev/null +++ b/plugins/custom_import_plugin/material_import.gd @@ -0,0 +1,22 @@ +tool +extends EditorPlugin + +var import_plugin + +func _enter_tree(): + + import_plugin = preload("res://addons/custom_import_plugin/import_plugin.gd").new() + + # pass the GUI base control, so the dialog has a parent node + import_plugin.config( get_base_control() ) + + add_import_plugin( import_plugin) + +func _exit_tree(): + + remove_import_plugin( import_plugin ) + + + + + \ No newline at end of file diff --git a/plugins/custom_import_plugin/plugin.cfg b/plugins/custom_import_plugin/plugin.cfg new file mode 100644 index 00000000..a002ad68 --- /dev/null +++ b/plugins/custom_import_plugin/plugin.cfg @@ -0,0 +1,14 @@ +[plugin] + +name="Silly Material Importer" +description="Imports a 3D Material from an external text file" +author="Juan Linietsky" +version="1.0" +script="material_import.gd" + + + + + + + diff --git a/plugins/custom_import_plugin/test.mtxt b/plugins/custom_import_plugin/test.mtxt new file mode 100644 index 00000000..546ea2af --- /dev/null +++ b/plugins/custom_import_plugin/test.mtxt @@ -0,0 +1 @@ +0,0,255 diff --git a/plugins/custom_node/heart.gd b/plugins/custom_node/heart.gd new file mode 100644 index 00000000..d53c92d8 --- /dev/null +++ b/plugins/custom_node/heart.gd @@ -0,0 +1,12 @@ +tool +extends Node2D + + +var heart = preload("res://addons/custom_node/heart.png") + +func _draw(): + draw_texture(heart,-heart.get_size()/2) + +func _get_item_rect(): + #override + return Rect2(-heart.get_size()/2,heart.get_size()) diff --git a/plugins/custom_node/heart.png b/plugins/custom_node/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..1dfd14a456e46be311f69bc29f8b12a02e60b965 GIT binary patch literal 12584 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 KMNUMnLSTZNZ)Ac1 literal 0 HcmV?d00001 diff --git a/plugins/custom_node/heart_icon.png b/plugins/custom_node/heart_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2eb819aa24d49c85bd675b385abdfbb422b5df97 GIT binary patch literal 809 zcmV+^1J?YBP)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00NOoL_t(I%YBpEi%nq|#((d( zj{7h(teI_4(s0En)5MVEctufMa4&|;AK=2pa3?AE+;Jr(OeBZQ+ykw&6i(2hAU z!``#kT6?Y6#hN`1;i;$I-k$gCd7tn57!cux>k5D1P6@kF-);L@H*mvoWIzO?s!mH! zk8`tFy!!mW0e#umr^DMfy|0h6t09i3+5c$6y0MWXhxJ8oZ~ayfT9&O!f zS4KzUj-yAzXnfq&BoV8rDGfioG1ZYPeL&7%vHMJZ*~+v&{mqCm>Xu5;`*Y_!%XK}u z4i|EZ7w?NEC%vRr!^wlcz`|=S;1sE&sTEf&2`9c&8%u~QV0j)+5QJg5d`$*KJ_Bta z;5ZHBy9E#?EsYA+bHM ze6Vxi6v1tVTq&d5ob~K{Lt}8}&r2;=FPR+`J?XaKAgCBc42T8B2IJ1s&Uzx56HO9r zUbV#D8FI?pUn)*+0h`4jX$(mO^_k3e_$6ap$$Ciy@s!fOXTN-XFtYhxJI>q-eB34d zNyLf#LM2xMuN9ox5aTM;CSaxvh1GkRxO?UF#!-%u<@ys(*KoGuc5esifYJlyri_j$7R z7bk1!9b7It)FC>wOmwhAbhw-TIqe$$k7wJEhn>=MI}p7ch(7F;ZF5<5|E`sP9Wu0B n-0COhp=fRqU$?x~_;0!&x>f`NsA%>300000NkvXXu0mjf*4k#0 literal 0 HcmV?d00001 diff --git a/plugins/custom_node/heart_plugin.gd b/plugins/custom_node/heart_plugin.gd new file mode 100644 index 00000000..01a6177c --- /dev/null +++ b/plugins/custom_node/heart_plugin.gd @@ -0,0 +1,18 @@ +tool +extends EditorPlugin + + +func _enter_tree(): + # When this plugin node enters tree, add the custom type + + add_custom_type("Heart","Node2D",preload("res://addons/custom_node/heart.gd"),preload("res://addons/custom_node/heart_icon.png")) + +func _exit_tree(): + # When the plugin node exits the tree, remove the custom type + + remove_custom_type("Heart") + + + + + \ No newline at end of file diff --git a/plugins/custom_node/plugin.cfg b/plugins/custom_node/plugin.cfg new file mode 100644 index 00000000..ebb4b564 --- /dev/null +++ b/plugins/custom_node/plugin.cfg @@ -0,0 +1,14 @@ +[plugin] + +name="Heart" +description="Adds a new Heart node in 2D" +author="Juan Linietsky" +version="1.0" +script="heart_plugin.gd" + + + + + + + diff --git a/plugins/readme.txt b/plugins/readme.txt new file mode 100644 index 00000000..963850dc --- /dev/null +++ b/plugins/readme.txt @@ -0,0 +1,13 @@ + +To install these, copy each of these folders to a folder: + +addons/ + +inside your projects, example: + +addons/custom_node + +To distribute and install from UI, make a zip that contains the folder, +example: + +zip -r custom_node.zip custom_node/* \ No newline at end of file