Skip to content

Commit

Permalink
Select scripts from list and create them in editor
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyjor committed Sep 9, 2024
1 parent 2cd0aff commit 7d90c08
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 34 deletions.
54 changes: 31 additions & 23 deletions src/editor/JulGameEditor/Components/ComponentInputs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ using JulGame.UI
show_field_editor(entity, field)
Creates inputs based on the component type and populates them.
"""
function show_field_editor(entity, fieldName, animation_window_dict, animator_preview_dict)
function show_field_editor(entity, fieldName, animation_window_dict, animator_preview_dict, newScriptText)
field = getfield(entity, fieldName)
if field == C_NULL || field === nothing
return
end

if !is_a_julgame_component(field)
show_component_field_input(entity, fieldName)
show_component_field_input(entity, fieldName, newScriptText)
return
end

Expand All @@ -39,7 +39,7 @@ function show_field_editor(entity, fieldName, animation_window_dict, animator_pr
show_animator_properties(entity.animator, animation_window_dict, animator_preview_dict)
else
for field in fieldnames(typeof(field))
show_component_field_input(getfield(entity, Symbol(lowercase(fieldName))), field)
show_component_field_input(getfield(entity, Symbol(lowercase(fieldName))), field, "")
end
end

Expand Down Expand Up @@ -84,7 +84,7 @@ This function displays the input fields for a given component field. It takes tw
The function checks the type of the field value and displays the corresponding input fields using CImGui library. It updates the field value based on the user input.
"""
function show_component_field_input(component, componentField)
function show_component_field_input(component, componentField, newScriptText)
fieldValue = getfield(component, componentField)
if isa(fieldValue, Math._Vector2{Float64}) || isa(fieldValue, Math._Vector2{Int32})
isFloat::Bool = isa(fieldValue, Math._Vector2{Float64}) ? true : false
Expand Down Expand Up @@ -164,7 +164,7 @@ function show_component_field_input(component, componentField)
end
setfield!(component, componentField, x)
elseif String(componentField) == "scripts"
show_script_editor(component)
show_script_editor(component, newScriptText)
elseif isa(fieldValue, Vector) # Then we need to unpack the nested items
for i = eachindex(fieldValue)
continue # TODO: Implement this
Expand Down Expand Up @@ -274,7 +274,7 @@ function show_animator_properties(animator, animation_window_dict, animator_prev
end
end
else
show_component_field_input(animator, field)
show_component_field_input(animator, field, "")
end
end
catch e
Expand Down Expand Up @@ -356,7 +356,7 @@ function show_sprite_fields(sprite, animation_window_dict)
window_info[]["points"][][2] = ImVec2(round(vec4i[1] + vec4i[3]), round(vec4i[2] + vec4i[4]))
sprite.crop = JulGame.Math.Vector4(Int32(vec4i[1]), Int32(vec4i[2]), Int32(vec4i[3]), Int32(vec4i[4]))
else
show_component_field_input(sprite, field)
show_component_field_input(sprite, field, "")
end
end
end
Expand Down Expand Up @@ -487,7 +487,7 @@ function show_sound_source_fields(soundSource)
CImGui.Button("Load Sound") && (Component.load_sound(soundSource, currentTextInTextBox, false))
CImGui.Button("Load Music") && (Component.load_sound(soundSource, currentTextInTextBox, true))
else
show_component_field_input(soundSource, field)
show_component_field_input(soundSource, field, "")
end
end
end
Expand All @@ -507,29 +507,37 @@ function is_a_julgame_component(field)
return isa(field, JulGame.TransformModule.Transform) || isa(field, JulGame.SpriteModule.InternalSprite) || isa(field, JulGame.ColliderModule.InternalCollider) || isa(field, JulGame.RigidbodyModule.InternalRigidbody) || isa(field, JulGame.SoundSourceModule.InternalSoundSource) || isa(field, JulGame.AnimatorModule.InternalAnimator) || isa(field, JulGame.ShapeModule.InternalShape) || isa(field, JulGame.CircleColliderModule.InternalCircleCollider) || isa(field, JulGame.AnimationModule.Animation)
end

function show_script_editor(entity)
function create_new_script(name)
path = joinpath(JulGame.BasePath, "scripts", "$(name).jl")
touch(joinpath(path))
file = open(path, "w")
println(file, newScriptContent(name))
close(file)

SDL2.SDL_OpenURL("vscode://file/$(path)")
end

function show_script_editor(entity, newScriptText)
if CImGui.TreeNode("Scripts")
show_help_marker("Add a script here to run it on the entity.")
CImGui.Button("Add Script") && (push!(entity.scripts, scriptObj("",[])); return;)
text = text_input_single_line("Name", newScriptText)
CImGui.SameLine()
CImGui.Button("Create New Script") && (push!(entity.scripts, scriptObj(String(text), [])); create_new_script(text);)

script = display_files(joinpath(JulGame.BasePath, "scripts"), "scripts", "Add Script")
if script != ""
push!(entity.scripts, scriptObj(script, []))
end

for i = eachindex(entity.scripts)
if CImGui.TreeNode("Script $(i)")
buf = "$(entity.scripts[i].name)"*"\0"^(64)
CImGui.Button("Delete $(i)") && (deleteat!(entity.scripts, i); return;)
CImGui.InputText("Script $(i)", buf, length(buf))
currentTextInTextBox = ""
for characterIndex = eachindex(buf)
if Int32(buf[characterIndex]) == 0
if characterIndex != 1
currentTextInTextBox = String(SubString(buf, 1, characterIndex-1))
end
break
end
end
CImGui.Text(entity.scripts[i].name)

entity.scripts[i] = scriptObj(currentTextInTextBox, entity.scripts[i].parameters)
entity.scripts[i] = scriptObj(entity.scripts[i].name, entity.scripts[i].parameters)
if CImGui.TreeNode("Script $(i) parameters")
params = entity.scripts[i].parameters
CImGui.Button("Add New Script Parameter") && (push!(params, ""); entity.scripts[i] = scriptObj(currentTextInTextBox, params); break;)
CImGui.Button("Add New Script Parameter") && (push!(params, ""); entity.scripts[i] = scriptObj(entity.scripts[i].name, params); break;)

for j = eachindex(entity.scripts[i].parameters)
buf = "$(entity.scripts[i].parameters[j])"*"\0"^(64)
Expand Down
15 changes: 12 additions & 3 deletions src/editor/JulGameEditor/Components/FileFinderMenu.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
imageExtensions = [".png", ".jpg", ".jpeg", ".bmp", ".gif"]
soundExtensions = [".wav", ".ogg", ".flac", ".mp3", ".aac", ".m4a", ".wma", ".aiff", ".aif", ".aifc", ".amr", ".au", ".snd", ".ra", ".rm", ".rmvb", ".mka", ".opus", ".sln", ".voc", ".vox", ".raw", ".wv", ".webm", ".dts", ".ac3", ".ec3", ".mlp", ".tta", ".mka", ".mks", ".m3u", ".m3u8", ".pls", ".asx", ".xspf", ".m4b", ".m4p", ".m4r", ".m4v", ".3gp", ".3g2", ".mp4", ".m4v", ".mkv", ".webm", ".flv", ".vob", ".ogv", ".avi", ".wmv", ".mov", ".qt", ".mpg", ".mpeg", ".m2v", ".m4v", ".svi", ".3gp", ".3g2", ".mxf", ".roq", ".nsv", ".f4v", ".f4p", ".f4a", ".f4b", ".f4m"]
fontExtensions = [".ttf", ".otf", ".ttc", ".woff", ".woff2", ".eot", ".sfnt", ".pfa", ".pfb", ".pfr", ".gsf", ".cid", ".cff", ".bdf", ".pcf", ".snf", ".mm", ".otb", ".dfont", ".bin", ".sfd", ".t42", ".t1", ".fon", ".fnt"]
scriptExtensions = [".jl"]
extensionsDict = Dict("images" => imageExtensions, "sounds" => soundExtensions, "fonts" => fontExtensions, "scripts" => scriptExtensions)

extensionsDict = Dict("images" => imageExtensions, "sounds" => soundExtensions, "fonts" => fontExtensions)
function display_files(base_path::String, file_type::String, depth::Int = 1)::String
function display_files(base_path::String, file_type::String, title::String = "", depth::Int = 1)::String
extensions = extensionsDict[file_type]
value = ""

pathName = split(base_path, "/")[end]
pathName = split(pathName, "\\")[end]
if CImGui.BeginMenu("$(pathName)")

if title == ""
title = pathName
end

if CImGui.BeginMenu("$(title)")
for file::String in readdir(joinpath(base_path))
if isdir(joinpath(base_path, file))
value = display_files(joinpath(base_path, file), file_type, depth+1)
Expand All @@ -21,6 +27,9 @@ function display_files(base_path::String, file_type::String, depth::Int = 1)::St
if extension in extensions
if CImGui.MenuItem(file)
value = "$(joinpath(base_path, file))"
if file_type == "scripts"
value = split(file, ".")[1]
end
end
end
end
Expand Down
46 changes: 46 additions & 0 deletions src/editor/JulGameEditor/Components/TextInputs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,50 @@ function text_input_single_line(name::String, currentText; maxBuf=128, filters =
end
CImGui.PopID()
return currentText[]
end

mutable struct TextInputSingleLine
name::String
currentText::String
maxBuf::Int
filters::CImGui.ImGuiInputTextFlags

function TextInputSingleLine(name::String, currentText::String; maxBuf=128, filters = CImGui.ImGuiInputTextFlags_None)
this = new()

this.name = name
this.currentText = currentText
this.maxBuf = maxBuf
this.filters = filters

return this
end
end

"""
text_input_single_line(this::TextInputSingleLine)
Create a single-line text input field.
# Arguments
- `this::TextInputSingleLine`: The text input field.
- `filters`: Optional. The ImGui filters to apply to the text input field.
# Returns
- `currentText`: The current text entered in the text input field.
"""

function text_input_single_line(this::TextInputSingleLine)
buf = "$(this.currentText)"*"\0"^this.maxBuf
CImGui.PushID(this.name)
CImGui.InputText(this.name, buf, length(buf), this.filters)
for characterIndex = eachindex(buf)
if Int32(buf[characterIndex]) == 0 # The end of the buffer will be recognized as a 0
this.currentText = characterIndex == 1 ? "" : String(SubString(buf, 1, characterIndex - 1))
break
end
end
CImGui.PopID()
return this.currentText
end
48 changes: 44 additions & 4 deletions src/editor/JulGameEditor/Editor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ module Editor
currentDialog::Base.RefValue{String} = Ref("")
newSceneText = Ref("")
newProjectText = Ref("")
newScriptText = Ref("")

panOffset = Math.Vector2(0, 0)
camera = JulGame.CameraModule.Camera(Vector2(500,500), Vector2f(),Vector2f(), C_NULL)
Expand Down Expand Up @@ -334,7 +335,20 @@ module Editor
end
CImGui.End()
catch e
log_exceptions("Hierarchy Window Error:", latest_exceptions, e, is_test_mode)
# Get the stack trace
bt = stacktrace(catch_backtrace())

file = ""
line = ""
if !isempty(bt)
top_frame = bt[1]
file = top_frame.file
line = top_frame.line
else
@info("Stack trace is empty.")
end

log_exceptions("Hierarchy Window Error:", latest_exceptions, e, "$(file):$(line)", is_test_mode)
end

show_debug_window(latest_exceptions)
Expand All @@ -351,7 +365,7 @@ module Editor
CImGui.PopID()
CImGui.Separator()
for entityField in fieldnames(Entity)
show_field_editor(currentSceneMain.selectedEntity, entityField, animation_window_dict, animator_preview_dict)
show_field_editor(currentSceneMain.selectedEntity, entityField, animation_window_dict, animator_preview_dict, newScriptText)
end

CImGui.Separator()
Expand All @@ -364,7 +378,20 @@ module Editor
end
CImGui.End()
catch e
log_exceptions("Entity Inspector Window Error:", latest_exceptions, e, is_test_mode)
# Get the stack trace
bt = stacktrace(catch_backtrace())

file = ""
line = ""
if !isempty(bt)
top_frame = bt[1]
file = top_frame.file
line = top_frame.line
else
@info("Stack trace is empty.")
end

log_exceptions("Entity Inspector Window Error:", latest_exceptions, e, "$(file):$(line)", is_test_mode)
end

try
Expand Down Expand Up @@ -402,7 +429,20 @@ module Editor
end
CImGui.End()
catch e
log_exceptions("UI Inspector Window Error:", latest_exceptions, e, is_test_mode)
# Get the stack trace
bt = stacktrace(catch_backtrace())

file = ""
line = ""
if !isempty(bt)
top_frame = bt[1]
file = top_frame.file
line = top_frame.line
else
@info("Stack trace is empty.")
end

log_exceptions("UI Inspector Window Error:", latest_exceptions, e, "$(file):$(line)", is_test_mode)
end

SDL2.SDL_SetRenderTarget(renderer, sceneTexture)
Expand Down
5 changes: 2 additions & 3 deletions src/editor/JulGameEditor/Utils/EditorUtils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,9 @@ function move_entities(entities, origin, destination)
splice!(entities, destinationIndex : destinationIndex, updatedEntities)
end

function log_exceptions(error_type, latest_exceptions, e, is_test_mode)
println("Error: ", e)
function log_exceptions(error_type, latest_exceptions, e, top_backtrace, is_test_mode)
Base.show_backtrace(stderr, catch_backtrace())
push!(latest_exceptions, [e, String("$(Dates.now())")])
push!(latest_exceptions, [e, String("$(Dates.now())"), top_backtrace])
if length(latest_exceptions) > 10
deleteat!(latest_exceptions, 1)
end
Expand Down
2 changes: 1 addition & 1 deletion src/editor/JulGameEditor/Windows/DebugWindow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function show_debug_window(latestExceptions)
for exception in latestExceptions
CImGui.Text("[$(counter)] $(exception[2]): $(exception[1])")
CImGui.Button("Copy to clipboard") && (CImGui.SetClipboardText("[$(counter)] $(exception[2]): $(exception[1])");)
CImGui.Button("Open link: ") && (SDL2.SDL_OpenURL("vscode://file/F:/Projects/Julia/julGame/src/editor/JulGameEditor/Windows/DebugWindow.jl").SetClipboardText("[$(counter)] $(exception[2]): $(exception[1])");)
CImGui.Button("Open in vscode") && (SDL2.SDL_OpenURL("vscode://file/$(exception[3])");)
counter += 1
end
CImGui.End()
Expand Down

0 comments on commit 7d90c08

Please sign in to comment.