173 lines
4.5 KiB
GDScript
173 lines
4.5 KiB
GDScript
@tool
|
|
# @singleton IconsFonts
|
|
extends Node
|
|
|
|
const docked_setting_path := "application/addons/icon_finder/is_docked"
|
|
const prev_size_setting_path := "application/addons/icon_finder/preview_size"
|
|
|
|
## Material Icons
|
|
const material_icons_json := "res://addons/icons-fonts/icons_fonts/MaterialIcons/icons.json"
|
|
const material_icons_font := "res://addons/icons-fonts/icons_fonts/MaterialIcons/material_design_icons.ttf"
|
|
|
|
## Emojis
|
|
const emojis_json := "res://addons/icons-fonts/icons_fonts/emojis/emojis.json"
|
|
const emojis_font := "res://addons/icons-fonts/icons_fonts/emojis/NotoColorEmoji.ttf"
|
|
|
|
signal font_loaded(font_name: String)
|
|
var material_icons := {}
|
|
var emojis := {}
|
|
|
|
static var is_docked: bool:
|
|
set(value):
|
|
ProjectSettings.set_setting(docked_setting_path, value)
|
|
get:
|
|
return ProjectSettings.get_setting(docked_setting_path, true)
|
|
|
|
static var preview_size: int:
|
|
set(value):
|
|
ProjectSettings.set_setting(prev_size_setting_path, value)
|
|
get:
|
|
return ProjectSettings.get_setting(prev_size_setting_path, 24)
|
|
|
|
func _ready():
|
|
var json: JSON
|
|
var content: String
|
|
if Engine.is_editor_hint():
|
|
json = load(material_icons_json)
|
|
init_material_icons_dict(json.data)
|
|
else:
|
|
json = JSON.new()
|
|
content = get_file_content(material_icons_json)
|
|
if json.parse(content) == OK:
|
|
init_material_icons_dict(json.data)
|
|
|
|
if Engine.is_editor_hint():
|
|
json = load(emojis_json)
|
|
init_emoji_dictionaries(json.data)
|
|
else:
|
|
json = JSON.new()
|
|
content = get_file_content(emojis_json)
|
|
if json.parse(content) == OK:
|
|
init_emoji_dictionaries(json.data)
|
|
|
|
func get_file_content(path: String) -> String:
|
|
var file := FileAccess.open(path, FileAccess.READ)
|
|
var content := ""
|
|
|
|
if file.get_error() == OK:
|
|
content = file.get_as_text()
|
|
file.close()
|
|
|
|
return content
|
|
|
|
func init_material_icons_dict(data: Dictionary):
|
|
material_icons = data
|
|
for id in data:
|
|
var hex = material_icons[id]
|
|
material_icons[id] = ("0x" + hex).hex_to_int()
|
|
# prints(id, material_icons[id])
|
|
|
|
prints("FontsIcons: MaterialIcons loaded")
|
|
font_loaded.emit("MaterialIcons")
|
|
|
|
func init_emoji_dictionaries(dict: Dictionary):
|
|
for emoji in dict:
|
|
var keys = dict[emoji]
|
|
for key in keys:
|
|
emojis[key] = emoji
|
|
|
|
prints("FontsIcons: Emojis loaded")
|
|
font_loaded.emit("Emojis")
|
|
|
|
func get_icon_code(font: String, id: String) -> int:
|
|
if "," in id:
|
|
id = id.split(",")[0]
|
|
|
|
match font:
|
|
"MaterialIcons":
|
|
if id in material_icons:
|
|
return material_icons[id]
|
|
|
|
push_warning("Icon '%s' in font %s not found." % [id, font])
|
|
return 0
|
|
|
|
func get_emoji_unicode(id: String) -> String:
|
|
if id in emojis:
|
|
# prints(id, emojis[id])
|
|
return emojis[id]
|
|
|
|
push_warning("Emoji %s not found." % id)
|
|
return ""
|
|
|
|
func get_icon_char(font: String, id: String) -> String:
|
|
match font:
|
|
"MaterialIcons":
|
|
return char(get_icon_code(font, id))
|
|
|
|
"Emojis":
|
|
return get_emoji_unicode(id)
|
|
|
|
return ""
|
|
|
|
## will parse text using:
|
|
## - parse_material_icons()
|
|
## - parse_emojis()
|
|
## - parse_game_icons()
|
|
func parse_text(text: String) -> String:
|
|
text = parse_material_icons(text)
|
|
text = parse_emojis(text)
|
|
# todo add game-icons parse
|
|
return text
|
|
|
|
## will replace [mi:icon_name] with [font=MaterialIcons]icon_char[/font]
|
|
func parse_material_icons(text: String) -> String:
|
|
var regex = RegEx.new()
|
|
regex.compile("\\[mi:(.*?)\\]")
|
|
var x = regex.search(text)
|
|
while x != null:
|
|
var icon = x.get_string(1)
|
|
var char = get_icon_char("MaterialIcons", icon)
|
|
var r = "[font={font}]{char}[/font]"
|
|
r = r.format({"font": material_icons_font, "char": char})
|
|
|
|
if icon.split(",").size() > 1:
|
|
var size = icon.split(",")[1]
|
|
var s = "[font_size={size}]{r}[/font_size]"
|
|
r = s.format({"size": size, "r": r})
|
|
|
|
text = text.replace(x.get_string(), r)
|
|
x = regex.search(text)
|
|
|
|
return text
|
|
|
|
func get_emoji_bbcode(id: String, size := 0) -> String:
|
|
var emoji := get_icon_char("Emojis", id)
|
|
if !emoji: return ""
|
|
|
|
var bbcode := "[font=%s]%s[/font]" % [emojis_font, emoji]
|
|
if size <= 0: return bbcode
|
|
|
|
return "[font_size=%s]%s[/font_size]" % [size, bbcode]
|
|
|
|
## will replace :emoji_name: with [font=Emojis]emoji_char[/font]
|
|
func parse_emojis(text: String):
|
|
var re = RegEx.new()
|
|
re.compile(":[\\w\\d]+(,\\s*\\d+)?:")
|
|
var result = re.search(text)
|
|
while result != null:
|
|
var temp := result.get_string()
|
|
temp = temp.replace(":", "")
|
|
var emoji := temp
|
|
var size := 0
|
|
|
|
if "," in temp:
|
|
var splited := temp.split(",")
|
|
emoji = splited[0]
|
|
size = int(splited[1].replace(" ", ""))
|
|
|
|
var replacement := get_emoji_bbcode(emoji, size)
|
|
text = text.replace(result.get_string(), replacement)
|
|
result = re.search(text)
|
|
|
|
return text
|