Created Godot project, implemented GDScript input field, added icon.svg, readme, license

This commit is contained in:
blujai831 2023-10-10 14:29:15 -07:00
parent cef29ef7f7
commit 57f90f9f0c
Signed by: blujai831
GPG Key ID: DDC31A0363AA5E66
13 changed files with 475 additions and 0 deletions

7
.gitattributes vendored Normal file
View File

@ -0,0 +1,7 @@
# Normalize line endings for all files that Git considers text files.
* text=auto eol=lf
# Only include the addons folder when downloading from the Asset Library.
/** export-ignore
/addons !export-ignore
/addons/** !export-ignore

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
# Godot 4+ specific ignores
.godot/
# Godot-specific ignores
.import/
export.cfg
export_presets.cfg
# Imported translations (automatically generated from CSV files)
*.translation
# Mono-specific ignores
.mono/
data_*/
mono_crash.*.json

21
LICENSE.md Normal file
View File

@ -0,0 +1,21 @@
# MIT License
Copyright (c)2023 alias blujai831 <webmaster@blujai831.dev>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the “Software”),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

34
README.md Normal file
View File

@ -0,0 +1,34 @@
# GDScript Input Field Plugin
This is a plugin for Godot 4 that adds a GDScript input field
to the bottom of the editor output panel.
## Installation
Copy the directory `addons/gdscript_input_field`
into the directory `[your project]/addons`,
such that you wind up with `[your project]/addons/gdscript_input_field`.
You can then enable or disable the plugin in Godot under
`Project -> Project Settings... -> Plugins`.
Enabling it should place a new input field in the `Output` panel,
underneath `Filter Messages`, with the placeholder text
`Evaluate GDScript Expression`.
## Usage
The field functions like a REPL: you may type a GDScript expression there
and then a line break (return / enter), and the expression will be consumed
and evaluated, and its result printed to the log above.
This plugin can only evaluate expressions. An "expression"
is almost any valid code that's neither a declaration nor a block statement.
For more information, see:
https://docs.godotengine.org/en/stable/tutorials/scripting/evaluating_expressions.html
In the context of the expressions evaluated,
`self` is the root node of the scene you have open in the editor.
If you have no scene open in the editor, there will be no `self`;
in this case, you can still evaluate expressions,
but will have no access to any non-global non-static properties or methods.

View File

@ -0,0 +1,21 @@
# MIT License
Copyright (c)2023 alias blujai831 <webmaster@blujai831.dev>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the “Software”),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,34 @@
## GDScript Input Field Plugin
This is a plugin for Godot 4 that adds a GDScript input field
to the bottom of the editor output panel.
## Installation
Copy the directory `addons/gdscript_input_field`
into the directory `[your project]/addons`,
such that you wind up with `[your project]/addons/gdscript_input_field`.
You can then enable or disable the plugin in Godot under
`Project -> Project Settings... -> Plugins`.
Enabling it should place a new input field in the `Output` panel,
underneath `Filter Messages`, with the placeholder text
`Evaluate GDScript Expression`.
## Usage
The field functions like a REPL: you may type a GDScript expression there
and then a line break (return / enter), and the expression will be consumed
and evaluated, and its result printed to the log above.
This plugin can only evaluate expressions. An "expression"
is almost any valid code that's neither a declaration nor a block statement.
For more information, see:
https://docs.godotengine.org/en/stable/tutorials/scripting/evaluating_expressions.html
In the context of the expressions evaluated,
`self` is the root node of the scene you have open in the editor.
If you have no scene open in the editor, there will be no `self`;
in this case, you can still evaluate expressions,
but will have no access to any non-global non-static properties or methods.

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 67.733332 67.733333"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="icon-gdscript-input-field.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
inkscape:zoom="2.0485264"
inkscape:cx="232.36215"
inkscape:cy="102.26863"
inkscape:window-width="1916"
inkscape:window-height="1017"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid2"
units="px"
originx="0"
originy="0"
spacingx="0.26458333"
spacingy="0.26458333"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="rect4"
style="stroke-width:0.264583"
d="M 8.4666662,0 H 59.266664 c 4.690533,0 8.466666,3.7761331 8.466666,8.4666662 V 59.266664 c 0,4.690533 -3.776133,8.466666 -8.466666,8.466666 H 8.4666662 C 3.7761331,67.73333 0,63.957197 0,59.266664 V 8.4666662 C 0,3.7761331 3.7761331,0 8.4666662,0 Z" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:67.7333px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono';fill:#f9f9f9;stroke-width:0.264583"
x="22.489584"
y="9.2604151"
id="text3"><tspan
sodipodi:role="line"
id="tspan3"
style="stroke-width:0.264583"
x="22.489584"
y="9.2604151" /></text>
<path
d="M 9.5031243,13.123752 V 6.6298194 L 36.959473,17.435724 v 6.130273 L 9.5031243,34.345926 V 27.877968 L 30.153831,20.526836 Z M 71.273414,44.78817 v 4.935389 H 39.245336 V 44.78817 Z"
id="text4"
style="font-weight:bold;font-size:53.1983px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono Bold';fill:#f9f9f9;stroke-width:0.415611"
transform="scale(0.83525152,1.1972442)"
aria-label="&gt;_" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://q0no2b7hbmse"
path="res://.godot/imported/icon.svg-05c86a2a87165d339e50dc7800d711dd.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/gdscript_input_field/icon.svg"
dest_files=["res://.godot/imported/icon.svg-05c86a2a87165d339e50dc7800d711dd.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -0,0 +1,7 @@
[plugin]
name="GDScript Input Field Plugin"
description="Provides an input field in the editor output panel for executing arbitrary GDScript in a REPL-like fashion."
author="blujai831"
version="0.1.0"
script="plugin.gd"

View File

@ -0,0 +1,80 @@
@tool
extends EditorPlugin
## Adds a GDScript input field to the EditorLog.
var _field: CodeEdit
## Traverses the editor's interface tree in search of the EditorLog.
func _find_editor_log(start: Node = null) -> Node:
if not start:
start = get_editor_interface().get_base_control()
var result: Node = null
if start.get_class() == 'EditorLog':
result = start
else:
for child in start.get_children():
result = _find_editor_log(child)
if result:
break
return result
## Our desired parent should be the second child of the EditorLog.
func _find_parent_for_field() -> VBoxContainer:
var editor_log := _find_editor_log()
if editor_log:
return editor_log.get_child(1) as VBoxContainer
else:
return null
## Creates and executes an Expression from a given code string.
func _exec(code: String) -> Variant:
var expr := Expression.new()
var error := OK
var result: Variant
error = expr.parse(code)
if error == OK:
result = expr.execute(
[], get_editor_interface().get_edited_scene_root()
)
if expr.has_execute_failed():
error = FAILED
if error == OK:
return result
else:
push_error(expr.get_error_text())
return error
## Executes and clears the field the instant it contains line breaks.
func _on_field_text_changed() -> void:
if _field.text.contains("\n") or _field.text.contains("\r"):
var code := _field.text.replace("\n", '').replace("\r", '')
_field.text = ""
if not code.is_empty():
print("> %s" % code)
var result := _exec(code)
print("=> %s" % var_to_str(result))
## Creates the input field, connects it to our handler, and inserts it.
func _enter_tree() -> void:
_field = CodeEdit.new()
_field.text_changed.connect(_on_field_text_changed)
_field.caret_blink = true
_field.scroll_fit_content_height = true
_field.placeholder_text = "Evaluate GDScript Expression"
var parent := _find_parent_for_field()
if parent:
parent.add_child(_field)
else:
push_error("Couldn't find the EditorLog's first VBoxContainer")
queue_free()
## Disconnects and deletes the input field.
func _exit_tree() -> void:
_field.text_changed.disconnect(_on_field_text_changed)
_field.queue_free()

81
icon.svg Normal file
View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 67.733332 67.733333"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="icon-gdscript-input-field.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
inkscape:zoom="2.0485264"
inkscape:cx="232.36215"
inkscape:cy="102.26863"
inkscape:window-width="1916"
inkscape:window-height="1017"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid2"
units="px"
originx="0"
originy="0"
spacingx="0.26458333"
spacingy="0.26458333"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="rect4"
style="stroke-width:0.264583"
d="M 8.4666662,0 H 59.266664 c 4.690533,0 8.466666,3.7761331 8.466666,8.4666662 V 59.266664 c 0,4.690533 -3.776133,8.466666 -8.466666,8.466666 H 8.4666662 C 3.7761331,67.73333 0,63.957197 0,59.266664 V 8.4666662 C 0,3.7761331 3.7761331,0 8.4666662,0 Z" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:67.7333px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono';fill:#f9f9f9;stroke-width:0.264583"
x="22.489584"
y="9.2604151"
id="text3"><tspan
sodipodi:role="line"
id="tspan3"
style="stroke-width:0.264583"
x="22.489584"
y="9.2604151" /></text>
<path
d="M 9.5031243,13.123752 V 6.6298194 L 36.959473,17.435724 v 6.130273 L 9.5031243,34.345926 V 27.877968 L 30.153831,20.526836 Z M 71.273414,44.78817 v 4.935389 H 39.245336 V 44.78817 Z"
id="text4"
style="font-weight:bold;font-size:53.1983px;font-family:'DejaVu Sans Mono';-inkscape-font-specification:'DejaVu Sans Mono Bold';fill:#f9f9f9;stroke-width:0.415611"
transform="scale(0.83525152,1.1972442)"
aria-label="&gt;_" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

37
icon.svg.import Normal file
View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dx8onofrb02ay"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

20
project.godot Normal file
View File

@ -0,0 +1,20 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="GDScript Input Field Plugin"
config/description="Provides an input field in the editor output panel for executing arbitrary GDScript in a REPL-like fashion."
config/features=PackedStringArray("4.1", "Forward Plus")
config/icon="res://icon.svg"
[editor_plugins]
enabled=PackedStringArray("res://addons/gdscript_input_field/plugin.cfg")