diff --git a/README.md b/README.md index a1478aa..86a9b41 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ `! Note:` this plugin only works for Godot 4.x Updated to 4.0.alpha15. Things may still break, older alphas may not be compatible right away. +If something did break in a newer version, please open an issue. Now available on the Godot Asset Library: [Color Preview](https://godotengine.org/asset-library/asset/1252) @@ -23,7 +24,8 @@ Go to `Project > Project Settings... > Plugins` and press Enable Once you have done this, every line containing a Color will have a preview left of the breakpoint gutter. Click any preview to open a color picker where you can edit the color directly. -![Addon Preview](https://github.com/Qubus0/GodotColorPreview/blob/main/colors.png) +![Color Preview in the main code editor](https://github.com/Qubus0/GodotColorPreview/blob/main/colors.png) +![Color Preview in the shader editor](https://github.com/Qubus0/GodotColorPreview/blob/main/colors_shader.png) *** diff --git a/addons/ColorPreview/ColorPreview.gd b/addons/ColorPreview/ColorPreview.gd index 0923ef3..f500d9f 100644 --- a/addons/ColorPreview/ColorPreview.gd +++ b/addons/ColorPreview/ColorPreview.gd @@ -11,8 +11,11 @@ var picker_popup: Popup func _enter_tree() -> void: - initialize_picker() initialize_gutter() + initialize_picker() + # the shader editor does not exist until opened for the first time + # so, to get it consistently, check if it's there whenever the focus changes + get_viewport().gui_focus_changed.connect(get_shader_editor_code_edit) func _exit_tree() -> void: @@ -26,7 +29,7 @@ func initialize_picker() -> void: picker_popup.connect("popup_hide", on_picker_popup_close) picker_popup.hide() - var picker = picker_popup.get_node("ColorPicker") + var picker: ColorPicker = picker_popup.get_node("ColorPicker") if not picker.is_connected("color_changed", picker_color_changed): picker.connect("color_changed", picker_color_changed) @@ -65,24 +68,30 @@ func get_all_text_editors(parent : Node) -> void: if child.get_child_count(): get_all_text_editors(child) - if child is TextEdit: - editors.append(child) - - if child.is_connected("text_changed", text_changed): - child.disconnect("text_changed", text_changed) - child.text_changed.connect(text_changed.bind(child)) - - if child.is_connected("caret_changed", caret_changed): - child.disconnect("caret_changed", caret_changed) - child.caret_changed.connect(caret_changed.bind(child)) + if child is CodeEdit: + add_code_edit_to_editors_array(child) + + +func get_shader_editor_code_edit(node: Node): + if not node is CodeEdit or not node.get_parent().get_class() == "ShaderTextEditor": + return + + if not editors.has(node): + add_code_edit_to_editors_array(node) + initialize_gutter() + initialize_picker() -func caret_changed(textedit: TextEdit) -> void: - handle_change(textedit) +func add_code_edit_to_editors_array(node: CodeEdit) -> void: + editors.append(node) + if node.is_connected("text_changed", handle_change): + node.disconnect("text_changed", handle_change) + node.text_changed.connect(handle_change.bind(node)) -func text_changed(textedit : TextEdit) -> void: - handle_change(textedit) + if node.is_connected("caret_changed", handle_change): + node.disconnect("caret_changed", handle_change) + node.caret_changed.connect(handle_change.bind(node)) func handle_change(textedit : TextEdit) -> void: @@ -98,8 +107,8 @@ func handle_change(textedit : TextEdit) -> void: func editor_script_changed(script: Script) -> void: - initialize_picker() initialize_gutter() + initialize_picker() if current_textedit: if current_textedit.is_connected("gui_input", textedit_clicked): current_textedit.disconnect("gui_input", textedit_clicked) @@ -254,7 +263,17 @@ func on_picker_popup_close() -> void: var text := current_textedit.get_line(hovering_line) var color_match : RegExMatch = match_color_in_string(text) var new_color = get_line_color(current_textedit, hovering_line) - text = text.replace(color_match.get_string(), "Color" + str(new_color)) + + if color_from_regex_match(color_match) == new_color: + return # don't change if equal -> doesn't mess up constants, strings etc. + + if color_match.get_string('const'): # replace the whole color string + text = text.replace(color_match.get_string(), "Color" + str(new_color)) + + else: # only replace inside parenthesis to cover Color(...) and vec4(...) + var color_string = str(new_color).replace("(", "").replace(")", "") + text = text.replace(color_match.get_string("params"), color_string) + current_textedit.set_line(hovering_line, text) @@ -315,10 +334,19 @@ func named_or_hex_color(string: String): # Color or null func match_color_in_string(string: String) -> RegExMatch: var re = RegEx.new() + var color + re.compile("Color\\((?(?R)*.*?)\\)") - var color = re.search(string) + color = re.search(string) if color != null: return color + re.compile("Color\\.(?[A-Z_]+)\\b") - return re.search(string) + color = re.search(string) + if color != null: + return color + + re.compile("source_color.*?vec4\\((?(?R)*.*?)\\)") + color = re.search(string) + return color diff --git a/colors_demo.gdshader b/colors_demo.gdshader new file mode 100644 index 0000000..015b475 --- /dev/null +++ b/colors_demo.gdshader @@ -0,0 +1,14 @@ +shader_type canvas_item; + +// supports shader uniforms with type hint source_color +uniform vec4 input_color : source_color = vec4(0.0952, 0.8355, 0.9494, 1); +uniform vec4 transparent_color : source_color = vec4(0.95, 0.24, 0.52, 0.6); + +// and any vec4 as color with this comment in front +/* source_color */ uniform vec4 not_type_hinted = vec4(1, 0.8549, 0.102, 1); + +// Color.BLACK <- technically you can also view these + + +// picking and selecting also works the same +uniform vec4 picker_color : source_color = vec4(0.9049, 0.5072, 0.0389, 1); \ No newline at end of file diff --git a/colors_shader.png b/colors_shader.png new file mode 100644 index 0000000..ac1ab13 Binary files /dev/null and b/colors_shader.png differ diff --git a/project.godot b/project.godot index b4203f8..037e984 100644 --- a/project.godot +++ b/project.godot @@ -18,6 +18,11 @@ config/icon="res://icon.png" enabled=PackedStringArray("res://addons/ColorPreview/plugin.cfg") +[filesystem] + +import/blender/enabled=false +import/fbx/enabled=false + [physics] common/enable_pause_aware_picking=true