image from code wooo
works mostly
bendn 2022-08-01
parent 75ca467 · commit 4c697b5
-rw-r--r--.gitignore1
-rw-r--r--CascadiaMono.tres8
-rw-r--r--CascadiaMono.ttfbin0 -> 624880 bytes
-rw-r--r--CodeDisplay.gd2
-rw-r--r--CodeView.tscn20
-rw-r--r--CodeViewport.gd13
-rw-r--r--HighlightedTextEdit.gd106
-rw-r--r--Main.gd72
-rw-r--r--Main.tscn45
-rw-r--r--ShrinkingTextEdit.gd52
-rw-r--r--main.themebin0 -> 509 bytes
-rw-r--r--project.godot39
-rw-r--r--textedit-panel.tres16
13 files changed, 364 insertions, 10 deletions
diff --git a/.gitignore b/.gitignore
index 5bbe921..3d753c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
new file mode 100644
index 0000000..662d891
--- /dev/null
+++ b/CascadiaMono.ttf
Binary files differ
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.
diff --git a/Main.gd b/Main.gd
new file mode 100644
index 0000000..612ab8f
--- /dev/null
+++ b/Main.gd
@@ -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()}]}
+ )
diff --git a/Main.tscn b/Main.tscn
index 70a653e..4fdfbc2 100644
--- a/Main.tscn
+++ b/Main.tscn
@@ -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
new file mode 100644
index 0000000..ddd2694
--- /dev/null
+++ b/main.theme
Binary files differ
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