image from code wooo
works mostly
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | CascadiaMono.tres | 8 | ||||
| -rw-r--r-- | CascadiaMono.ttf | bin | 0 -> 624880 bytes | |||
| -rw-r--r-- | CodeDisplay.gd | 2 | ||||
| -rw-r--r-- | CodeView.tscn | 20 | ||||
| -rw-r--r-- | CodeViewport.gd | 13 | ||||
| -rw-r--r-- | HighlightedTextEdit.gd | 106 | ||||
| -rw-r--r-- | Main.gd | 72 | ||||
| -rw-r--r-- | Main.tscn | 45 | ||||
| -rw-r--r-- | ShrinkingTextEdit.gd | 52 | ||||
| -rw-r--r-- | main.theme | bin | 0 -> 509 bytes | |||
| -rw-r--r-- | project.godot | 39 | ||||
| -rw-r--r-- | textedit-panel.tres | 16 |
13 files changed, 364 insertions, 10 deletions
@@ -6,3 +6,4 @@ logs/ .vscode/ exports/ *.x86_64 +token diff --git a/CascadiaMono.tres b/CascadiaMono.tres new file mode 100644 index 0000000..3100eef --- /dev/null +++ b/CascadiaMono.tres @@ -0,0 +1,8 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://CascadiaMono.ttf" type="DynamicFontData" id=1] + +[resource] +size = 15 +use_mipmaps = true +font_data = ExtResource( 1 ) diff --git a/CascadiaMono.ttf b/CascadiaMono.ttf Binary files differnew file mode 100644 index 0000000..662d891 --- /dev/null +++ b/CascadiaMono.ttf diff --git a/CodeDisplay.gd b/CodeDisplay.gd new file mode 100644 index 0000000..543e718 --- /dev/null +++ b/CodeDisplay.gd @@ -0,0 +1,2 @@ +class_name CodeDisplay +extends HighlightedTextEdit diff --git a/CodeView.tscn b/CodeView.tscn new file mode 100644 index 0000000..ba58eaf --- /dev/null +++ b/CodeView.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://main.theme" type="Theme" id=1] +[ext_resource path="res://HighlightedTextEdit.gd" type="Script" id=2] + +[node name="CodeHolder" type="TextEdit"] +anchor_right = 1.0 +anchor_bottom = 1.0 +rect_min_size = Vector2( 0, 100 ) +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme = ExtResource( 1 ) +syntax_highlighting = true +context_menu_enabled = false +virtual_keyboard_enabled = false +middle_mouse_paste_enabled = false +selecting_enabled = false +deselect_on_focus_loss_enabled = false +drag_and_drop_selection_enabled = false +script = ExtResource( 2 ) diff --git a/CodeViewport.gd b/CodeViewport.gd new file mode 100644 index 0000000..2d0246d --- /dev/null +++ b/CodeViewport.gd @@ -0,0 +1,13 @@ +extends Viewport +class_name CodeViewport + +onready var code = $"%Code" + + +func warmup(): + size = code.rect_size + + +func save() -> Image: + var img := get_texture().get_data() + return img diff --git a/HighlightedTextEdit.gd b/HighlightedTextEdit.gd new file mode 100644 index 0000000..7692bae --- /dev/null +++ b/HighlightedTextEdit.gd @@ -0,0 +1,106 @@ +extends ShrinkingTextEdit +class_name HighlightedTextEdit + +const CLASS_COLOR = Color("ffd33682") +const KEYWORD_COLOR = Color("ffb58900") +const SYMBOL_COLOR = Color("ff839496") +const FUNCTION_COLOR = Color("ff268bd2") +const MEMBER_VAR_COLOR = Color("ff268bd2") +const NUMBER_COLOR = Color("ffd33682") +const STRING_COLOR = Color("ff2aa198") +const COMMENT_COLOR = Color("ff586e75") +const NODE_PATH_COLOR = Color("ffd33682") +const FONT_COLOR = Color("ff839496") + +const keyword_colors := { + "if": KEYWORD_COLOR, + "elif": KEYWORD_COLOR, + "else": KEYWORD_COLOR, + "for": KEYWORD_COLOR, + "while": KEYWORD_COLOR, + "match": KEYWORD_COLOR, + "break": KEYWORD_COLOR, + "continue": KEYWORD_COLOR, + "pass": KEYWORD_COLOR, + "return": KEYWORD_COLOR, + "class": KEYWORD_COLOR, + "class_name": KEYWORD_COLOR, + "extends": KEYWORD_COLOR, + "is": KEYWORD_COLOR, + "as": KEYWORD_COLOR, + "self": KEYWORD_COLOR, + "signal": KEYWORD_COLOR, + "func": KEYWORD_COLOR, + "static": KEYWORD_COLOR, + "const": KEYWORD_COLOR, + "enum": KEYWORD_COLOR, + "var": KEYWORD_COLOR, + "breakpoint": KEYWORD_COLOR, + "preload": KEYWORD_COLOR, + "await": KEYWORD_COLOR, + "yield": KEYWORD_COLOR, + "assert": KEYWORD_COLOR, + "void": KEYWORD_COLOR, + "in": KEYWORD_COLOR, + "not": KEYWORD_COLOR, + "and": KEYWORD_COLOR, + "or": KEYWORD_COLOR, + "PI": KEYWORD_COLOR, + "TAU": KEYWORD_COLOR, + "INF": KEYWORD_COLOR, + "NAN": KEYWORD_COLOR, + "null": KEYWORD_COLOR, + "int": KEYWORD_COLOR, + "float": KEYWORD_COLOR, + "bool": KEYWORD_COLOR, + "super": KEYWORD_COLOR, + "true": KEYWORD_COLOR, + "false": KEYWORD_COLOR, + "AABB": CLASS_COLOR, + "Array": CLASS_COLOR, + "Basis": CLASS_COLOR, + "Color": CLASS_COLOR, + "Dictionary": CLASS_COLOR, + "NodePath": CLASS_COLOR, + "Plane": CLASS_COLOR, + "PoolByteArray": CLASS_COLOR, + "PoolColorArray": CLASS_COLOR, + "PoolIntArray": CLASS_COLOR, + "PoolRealArray": CLASS_COLOR, + "PoolStringArray": CLASS_COLOR, + "PoolVector2Array": CLASS_COLOR, + "PoolVector3Array": CLASS_COLOR, + "Quat": CLASS_COLOR, + "RID": CLASS_COLOR, + "Rect2": CLASS_COLOR, + "String": CLASS_COLOR, + "Transform": CLASS_COLOR, + "Transform2D": CLASS_COLOR, + "Variant": CLASS_COLOR, + "Vector2": CLASS_COLOR, + "Vector3": CLASS_COLOR, + "ClassDB": CLASS_COLOR, +} + + +func _ready(): + for keyword in keyword_colors: + add_keyword_color(keyword, keyword_colors[keyword]) + + for cls in ClassDB.get_class_list(): + add_keyword_color(cls, CLASS_COLOR) + + add_color_region('"', '"', STRING_COLOR, false) + add_color_region("'", "'", STRING_COLOR, false) + add_color_region("$", " ", NODE_PATH_COLOR, true) + add_color_region("#", "", COMMENT_COLOR, true) + + add_color_override("font_color", FONT_COLOR) + add_color_override("function_color", FUNCTION_COLOR) + add_color_override("member_variable_color", MEMBER_VAR_COLOR) + add_color_override("number_color", NUMBER_COLOR) + add_color_override("symbol_color", SYMBOL_COLOR) + + +func _resized(): + pass # Replace with function body. @@ -0,0 +1,72 @@ +extends Node + +const prefix := "!c" + +onready var code_view: CodeDisplay = $"%Code" +onready var viewport: CodeViewport = $"%CodeViewport" + +var file = File.new() + + +func compile(source: String) -> RegEx: + var reg := RegEx.new() + reg.compile(source) + return reg + + +func _ready(): + var bot := DiscordBot.new() + add_child(bot) + var err = file.open("res://token", File.READ) + var token + if err == OK: + token = file.get_as_text() + elif OS.has_environment("TOKEN"): + token = OS.get_environment("TOKEN") + else: + push_error("token missing") + file.close() + bot.TOKEN = token + bot.connect("bot_ready", self, "_on_bot_ready") + bot.connect("message_create", self, "_on_message_create") + bot.login() + + +func _on_bot_ready(bot: DiscordBot): + bot.set_presence({"activity": {"type": "Game", "name": "Creating imagery"}}) + print("Logged in as " + bot.user.username + "#" + bot.user.discriminator) + print("Listening on " + str(bot.channels.size()) + " channels and " + str(bot.guilds.size()) + " guilds.") + + +func _on_message_create(bot: DiscordBot, message: Message, _channel: Dictionary): + var split = message.content.split(" ") + if message.author.bot or not prefix in split[0]: + return + var res + if message.content.find("```") != -1: + var reg := compile("```([\\s\\S]+)```") + res = reg.search(message.content) + elif message.content.find("`") != -1: + var reg := compile("`([^`]+)`") + res = reg.search(message.content) + split.remove(0) + var code: String = res.strings[1] if res else split.join(" ") + var lines = code.split("\n") + if res and lines[0] in ["swift", "py", "c", "c++"]: + lines.remove(0) + code = lines.join("\n") + + code = code.strip_edges() + + if !code: + return + + code_view.set_text(code) + code_view.emit_signal("text_changed") + viewport.warmup() + + yield(get_tree(), "idle_frame") + var img: Image = viewport.save() + bot.reply( + message, {"files": [{"name": "code.png", "media_type": "image/png", "data": img.save_png_to_buffer()}]} + ) @@ -1,3 +1,44 @@ -[gd_scene format=2] +[gd_scene load_steps=5 format=2] -[node name="Main" type="Node2D"] +[ext_resource path="res://Main.gd" type="Script" id=1] +[ext_resource path="res://main.theme" type="Theme" id=2] +[ext_resource path="res://CodeDisplay.gd" type="Script" id=3] +[ext_resource path="res://CodeViewport.gd" type="Script" id=4] + +[node name="Main" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +theme = ExtResource( 2 ) +script = ExtResource( 1 ) +__meta__ = { +"_edit_lock_": true +} + +[node name="CodeViewport" type="Viewport" parent="."] +unique_name_in_owner = true +size = Vector2( 500, 500 ) +transparent_bg = true +handle_input_locally = false +usage = 1 +render_target_v_flip = true +render_target_update_mode = 3 +script = ExtResource( 4 ) + +[node name="Code" type="TextEdit" parent="CodeViewport"] +unique_name_in_owner = true +anchor_right = 1.0 +anchor_bottom = 1.0 +rect_min_size = Vector2( 300, 140 ) +theme = ExtResource( 2 ) +text = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +syntax_highlighting = true +show_line_numbers = true +context_menu_enabled = false +virtual_keyboard_enabled = false +middle_mouse_paste_enabled = false +selecting_enabled = false +deselect_on_focus_loss_enabled = false +drag_and_drop_selection_enabled = false +script = ExtResource( 3 ) + +[connection signal="resized" from="CodeViewport/Code" to="CodeViewport/Code" method="_resized"] diff --git a/ShrinkingTextEdit.gd b/ShrinkingTextEdit.gd new file mode 100644 index 0000000..31bb96e --- /dev/null +++ b/ShrinkingTextEdit.gd @@ -0,0 +1,52 @@ +class_name ShrinkingTextEdit +extends TextEdit + +onready var font: DynamicFont = get_font("font") +var line_spacing +var line_height +var line_count = -1 setget set_line_count +var longest_line: String setget set_longest_line + +export(int) var min_line_count := 5 +onready var horizontal_min_size := rect_min_size.x - 57 + + +func _ready(): + line_spacing = get_constant("line_spacing") + line_height = font.get_height() + line_spacing + connect("text_changed", self, "_on_text_changed") + emit_signal("text_changed") + yield(get_tree(), "idle_frame") + update() + + +func set_line_count(count): + if line_count != max(min_line_count, count): + line_count = max(min_line_count, count) + rect_min_size.y = (line_count * line_height) + 20 + update() + + +func set_longest_line(new_longest_line): + if longest_line != new_longest_line: + longest_line = new_longest_line + rect_min_size.x = max(font.get_string_size(longest_line).x, horizontal_min_size) + 57 + update() + + +func _on_text_changed(): + self.line_count = get_line_count() + self.longest_line = get_longest_line() + + +func get_longest_line(): + var longest: String + for line in text.split("\n"): + if len(line) > len(longest): + longest = line + return longest + + +func update(): + rect_size = rect_min_size + .update() diff --git a/main.theme b/main.theme Binary files differnew file mode 100644 index 0000000..ddd2694 --- /dev/null +++ b/main.theme diff --git a/project.godot b/project.godot index b318bd3..c853132 100644 --- a/project.godot +++ b/project.godot @@ -19,6 +19,16 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/discord_gd/classes/bit_field.gd" }, { +"base": "HighlightedTextEdit", +"class": "CodeDisplay", +"language": "GDScript", +"path": "res://CodeDisplay.gd" +}, { +"base": "Viewport", +"class": "CodeViewport", +"language": "GDScript", +"path": "res://CodeViewport.gd" +}, { "base": "HTTPRequest", "class": "DiscordBot", "language": "GDScript", @@ -39,6 +49,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/discord_gd/classes/helpers.gd" }, { +"base": "ShrinkingTextEdit", +"class": "HighlightedTextEdit", +"language": "GDScript", +"path": "res://HighlightedTextEdit.gd" +}, { "base": "Reference", "class": "Message", "language": "GDScript", @@ -69,6 +84,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/discord_gd/classes/select_menu.gd" }, { +"base": "TextEdit", +"class": "ShrinkingTextEdit", +"language": "GDScript", +"path": "res://ShrinkingTextEdit.gd" +}, { "base": "Reference", "class": "User", "language": "GDScript", @@ -77,16 +97,20 @@ _global_script_classes=[ { _global_script_class_icons={ "ApplicationCommand": "", "BitField": "", +"CodeDisplay": "", +"CodeViewport": "", "DiscordBot": "", "DiscordInteraction": "", "Embed": "", "Helpers": "", +"HighlightedTextEdit": "", "Message": "", "MessageActionRow": "", "MessageButton": "", "MessageFlags": "", "Permissions": "", "SelectMenu": "", +"ShrinkingTextEdit": "", "User": "" } @@ -97,24 +121,22 @@ run/main_scene="res://Main.tscn" config/use_custom_user_dir=true config/custom_user_dir_name="GodotTemplate" -[autoload] - -CLI="*res://autoloads/CLI.gd" - [debug] gdscript/warnings/return_value_discarded=false [display] -window/size/width=320 -window/size/height=180 -window/size/test_width=1280 -window/size/test_height=720 +window/size/width=1280 +window/size/height=720 window/dpi/allow_hidpi=true window/stretch/mode="2d" window/stretch/aspect="keep" +[editor_plugins] + +enabled=PoolStringArray( "res://addons/discord_gd/plugin.cfg" ) + [logging] file_logging/enable_file_logging=true @@ -127,3 +149,4 @@ quality/intended_usage/framebuffer_allocation=0 quality/intended_usage/framebuffer_allocation.mobile=0 2d/snapping/use_gpu_pixel_snap=true vram_compression/import_etc=true +environment/default_clear_color=Color( 0.219608, 0.223529, 0.243137, 1 ) diff --git a/textedit-panel.tres b/textedit-panel.tres new file mode 100644 index 0000000..de5c914 --- /dev/null +++ b/textedit-panel.tres @@ -0,0 +1,16 @@ +[gd_resource type="StyleBoxFlat" format=2] + +[resource] +content_margin_left = 10.0 +content_margin_right = 10.0 +content_margin_top = 10.0 +content_margin_bottom = 10.0 +bg_color = Color( 0, 0.168627, 0.211765, 1 ) +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 +corner_detail = 10 +shadow_color = Color( 0, 0, 0, 0.368627 ) +shadow_size = 1 +anti_aliasing_size = 0.01 |