Initial Commit
Initial commit of Code Base.
This commit is contained in:
parent
293b1213e1
commit
c11a4ebbc2
653 changed files with 36893 additions and 1 deletions
116
addons/twitcher/sprite_frame_effect.gd
Normal file
116
addons/twitcher/sprite_frame_effect.gd
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
extends RichTextEffect
|
||||
|
||||
## Shows spriteframes within richtext label.[br]
|
||||
## @usage use prepare_message before to load the image and prepare the message accordingly
|
||||
class_name SpriteFrameEffect
|
||||
|
||||
const TRANSPARENT = preload("res://addons/twitcher/assets/transparent.tres")
|
||||
|
||||
static var regex: RegEx = RegEx.create_from_string("\\[sprite id=(?<id>.*?)\\](?<path>.*?)\\[/sprite\\]")
|
||||
|
||||
## Custom BB Code to use
|
||||
var bbcode = "sprite"
|
||||
## To track the emojis
|
||||
## Key: Id as String Value: Emoji
|
||||
var cache: Dictionary = {}
|
||||
## To check if the message got already prepared
|
||||
var ready: bool
|
||||
## Save theme for calculating line height
|
||||
var parent_label: RichTextLabel
|
||||
## If you don't want to have spaces between images (made for Foolbox <3)
|
||||
var no_space: bool
|
||||
|
||||
func prepare_message(message: String, parent: RichTextLabel) -> String:
|
||||
parent_label = parent
|
||||
var found_matches = regex.search_all(message) as Array[RegExMatch]
|
||||
|
||||
# We are changing the message content and want to preserve the match beginnings.
|
||||
# So we need to handle them in reverse
|
||||
found_matches.reverse()
|
||||
for m: RegExMatch in found_matches:
|
||||
var path = m.get_string("path")
|
||||
var id = m.get_string("id")
|
||||
var resource = ResourceLoader.load(path, "SpriteFrames") as SpriteFrames
|
||||
if resource == null: continue
|
||||
var tex = resource.get_frame_texture("default", 0)
|
||||
var size = tex.get_size()
|
||||
var start = m.get_start(0)
|
||||
# Add an empty image to make the correct amount of space
|
||||
message = message.replace(path, "[img width=%s height=%s]%s[/img]" % [size.x, size.y, TRANSPARENT.resource_path])
|
||||
var emoji = _create_emoji(resource)
|
||||
emoji.name = id
|
||||
emoji.set_meta("size", size)
|
||||
cache[id] = emoji
|
||||
parent.add_child(emoji)
|
||||
|
||||
if no_space: message = message.replace("[/sprite] [sprite", "[/sprite][sprite")
|
||||
|
||||
ready = true
|
||||
return message
|
||||
|
||||
|
||||
func _create_emoji(resource: SpriteFrames):
|
||||
var node = AnimatedSprite2D.new()
|
||||
node.sprite_frames = resource
|
||||
node.centered = true
|
||||
node.play()
|
||||
return node
|
||||
|
||||
|
||||
func _process_custom_fx(char_fx: CharFXTransform) -> bool:
|
||||
if not ready: return true
|
||||
var id = char_fx.env['id']
|
||||
# unknown image just ignore
|
||||
if !cache.has(id): return true
|
||||
|
||||
# Hide the original characters of the [sprite] tag content
|
||||
# (which should just be the placeholder [img] tag now)
|
||||
char_fx.visible = false
|
||||
|
||||
# Only position the sprite once, using the first character's info
|
||||
if char_fx.relative_index != 0: return true
|
||||
|
||||
var node: AnimatedSprite2D = cache[id]
|
||||
var image_size: Vector2 = node.get_meta("size") # Already stored in prepare_message
|
||||
|
||||
# --- Get Font Metrics from RichTextLabel Theme ---
|
||||
var font: Font = char_fx.font if char_fx.font else parent_label.get_theme_font(&"normal_font")
|
||||
var font_size: int = parent_label.get_theme_font_size(&"normal_font_size")
|
||||
|
||||
var font_ascent: float = 0.0
|
||||
var font_descent: float = 0.0 # Distance below baseline (positive value)
|
||||
|
||||
if font:
|
||||
if font_size <= 0:
|
||||
font_size = parent_label.get_theme_default_font_size()
|
||||
if font_size <= 0: font_size = 16 # Absolute fallback
|
||||
|
||||
# Get ascent and descent, scaled by the RichTextLabel's scale
|
||||
font_ascent = font.get_ascent(font_size) * parent_label.scale.y
|
||||
font_descent = font.get_descent(font_size) * parent_label.scale.y
|
||||
else:
|
||||
# Fallback estimation
|
||||
if font_size <= 0: font_size = 16
|
||||
var scaled_font_size = float(font_size) * parent_label.scale.y
|
||||
font_ascent = scaled_font_size * 0.8 # Estimate
|
||||
font_descent = scaled_font_size * 0.2 # Estimate
|
||||
printerr("SpriteFrameEffect: Could not determine font for ascent/descent calculation, using estimate.")
|
||||
|
||||
# --- Calculate Position ---
|
||||
var baseline_origin: Vector2 = char_fx.transform.get_origin()
|
||||
|
||||
# Horizontal center (remains the same)
|
||||
var center_x: float = baseline_origin.x + image_size.x / 2.0
|
||||
|
||||
# Vertical position: Align sprite center with the vertical center of the font glyph box.
|
||||
# The top of the font box is at baseline_origin.y - font_ascent.
|
||||
# The bottom of the font box is at baseline_origin.y + font_descent.
|
||||
# The total height of the font box is font_ascent + font_descent.
|
||||
# The center relative to the baseline is baseline - ascent + (total_height / 2)
|
||||
# = baseline - ascent + (ascent + descent) / 2
|
||||
# = baseline - (ascent / 2) + (descent / 2)
|
||||
# = baseline - (ascent - descent) / 2.0
|
||||
var center_y: float = baseline_origin.y - (font_ascent - font_descent) / 2.0
|
||||
|
||||
node.position = Vector2(center_x, center_y)
|
||||
return true
|
||||
Loading…
Add table
Add a link
Reference in a new issue