Skip to content

Commit

Permalink
Localization Feature Patch: English, French, Chinese (SC)
Browse files Browse the repository at this point in the history
  • Loading branch information
TinyTakinTeller authored Jan 5, 2025
1 parent 95dde8a commit 1e73a72
Show file tree
Hide file tree
Showing 74 changed files with 2,765 additions and 1,051 deletions.
3 changes: 3 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ audio music tracks ["axes_arr_mstr_loop.mp3", "forest_arr_mstr_loop.mp3", "stron

- res://global/const/locale/locale_en.gd by Abyssal_Novelist, Reed, TinyTakinTeller licensed under CC-BY-NC-SA 4.0 (https://creativecommons.org/licenses/by-nc-sa/4.0/)

## Localization (res://assets/i18n/)
- "fr" FRENCH by Marion Veber licensed under CC-BY-NC-SA 4.0 (https://creativecommons.org/licenses/by-nc-sa/4.0/)
- "zh" CHINESE (SC) by vikky2604 and gloria_1023 (Middlebury Institute of International Studies) licensed under CC-BY-NC-SA 4.0 (https://creativecommons.org/licenses/by-nc-sa/4.0/)


## Godot License(s)
Expand Down
21 changes: 21 additions & 0 deletions addons/label_font_auto_sizer/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Lescandez

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
46 changes: 46 additions & 0 deletions addons/label_font_auto_sizer/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions addons/label_font_auto_sizer/icon.svg.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[remap]

importer="texture"
type="CompressedTexture2D"
uid="uid://blcr2i0opqem8"
path="res://.godot/imported/icon.svg-678c72dc12642c8e5f0b56a46fd750a5.ctex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://addons/label_font_auto_sizer/icon.svg"
dest_files=["res://.godot/imported/icon.svg-678c72dc12642c8e5f0b56a46fd750a5.ctex"]

[params]

compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
216 changes: 216 additions & 0 deletions addons/label_font_auto_sizer/label_auto_sizer.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
@tool
@icon("res://addons/label_font_auto_sizer/icon.svg")
extends Label
class_name LabelAutoSizer

#region External variables
## The maximum size value in pixels that the font will grow to.
@export_range(1, 192, 1, "or_greater", "suffix:px") var _max_size: int = 64:
set(value):
if value > _min_size:
_max_size = value
else:
_max_size = _min_size
if is_node_ready(): ## This setter gets called when the label enters the tree in the editor, even before it's ready. This if check prevents it.
call_deferred(_check_line_count.get_method())
## The minimum size value in pixels that the font will shrink to.
@export_range(1, 192, 1, "or_greater", "suffix:px") var _min_size: int = 1:
set(value):
if value < _max_size:
_min_size = value
else:
_min_size = _max_size
if is_node_ready(): ## Same as _max_size comment.
call_deferred(_check_line_count.get_method())
@export var _lock_size_in_editor: bool = false:
set(value):
_lock_size_in_editor = value
if value == false:
call_deferred(_check_line_count.get_method())
#endregion

#region Internal variables
@export_storage var _current_font_size: int
@export_storage var _last_size_state: LABEL_SIZE_STATE = LABEL_SIZE_STATE.IDLE
@export_storage var _size_just_modified_by_autosizer: bool = false
@export_storage var _editor_defaults_set: bool = false
var _label_settings_just_duplicated: bool = false
enum LABEL_SIZE_STATE { JUST_SHRUNK, IDLE, JUST_ENLARGED }
#endregion


#region Virtual/Signal functions
## Gets called in-editor and in-game. Sets some default values if necessary.
func _ready() -> void:
if !_editor_defaults_set:
call_deferred(_set_editor_defaults.get_method())
if Engine.is_editor_hint():
call_deferred(_connect_signals.get_method())
else:
call_deferred(_check_line_count.get_method())
LabelFontAutoSizeManager.register_label(self)


## Gets called when there are changes in either the Theme or Label Settings resources.
## Checks if the change was made by the script of by the user and if not, sets the base font size value.
func _on_font_resource_changed() -> void:
if _size_just_modified_by_autosizer:
_size_just_modified_by_autosizer = false ## Early return because the change wasn't made by the user.
else:
_apply_font_size(_current_font_size)


## Gets called whenever the size of the control rect is modified (in editor). Calls the line count check.
func _on_label_rect_resized() -> void:
if !_editor_defaults_set:
return
call_deferred(_check_line_count.get_method())


## Called by autosize manager whenever the locale_chaged() method is called, as the tr() object changes don't trigger
## the set_text() method of the label, thus the size and line_amount doesn't get checked.
func _on_locale_changed() -> void:
call_deferred(_check_line_count.get_method())


## Gets called on scene changes and when the label is freed and erases itself from the autosize manager.
func _exit_tree() -> void:
LabelFontAutoSizeManager.erase_label(self)


#endregion


#region Private functions
##Only in-editor, keeps stuff in check while manually changing font resources and resizing the label (if you are going to change the label settings or the theme via code runtime, connect these signals at runtime tooby deleting "if Engine.is_editor_hint():" at line 44)
func _connect_signals() -> void:
if label_settings != null:
if !label_settings.changed.is_connected(_on_font_resource_changed):
label_settings.changed.connect(_on_font_resource_changed)
if !theme_changed.is_connected(_on_font_resource_changed):
theme_changed.connect(_on_font_resource_changed)
if !resized.is_connected(_on_label_rect_resized):
resized.connect(_on_label_rect_resized)


## Text can be changed via either: set_text(value), or _my_label.text = value. Both will trigger a line check.
## This func also checks whenever a new LabelSettings resource is un/loaded.
##**If you're doing some testing/developing, if you are changing the text from withit one of the label classes themselves, do it like self.set_text(value) or self.text = value, othersise it doesn't trigger a size check.
##In a real scenario you wouldn't be changing the text from within the class itself though.**
func _set(property: StringName, value: Variant) -> bool:
match property:
"text":
text = value
call_deferred(_check_line_count.get_method())
return true
"label_settings":
if _label_settings_just_duplicated: ## Need to check because this gets called whenever we duplicate the resource as well.
_label_settings_just_duplicated = false
return true
else:
if value != null:
label_settings = value
_label_settings_just_duplicated = true
label_settings = label_settings.duplicate() ## Label Settings are not unique by default, so we it gets duplicated to not override every instance.
if !label_settings.changed.is_connected(_on_font_resource_changed):
label_settings.changed.connect(_on_font_resource_changed)
_apply_font_size(_current_font_size)
else:
label_settings = null
_apply_font_size(_current_font_size)
return true
_:
return false


## Goes through the resources in the label and sets the base font size value.
## Priority: Label Settings > Override Theme Font Size > Theme Font Size.
func _check_font_size() -> void:
if label_settings != null:
_current_font_size = label_settings.font_size
elif get("theme_override_font_sizes/font_size") != null:
_current_font_size = get("theme_override_font_sizes/font_size")
elif get_theme_font_size("font_size") != null:
_current_font_size = get_theme_font_size("font_size")


## Checks the current font size and amount of lines in the text against the visible lines inside the rect.
## Calls for the shrink or enlarge methods accordingly.
func _check_line_count() -> void:
if Engine.is_editor_hint() and _lock_size_in_editor:
return

if _current_font_size > _max_size and _current_font_size > _min_size:
_shrink_font()
return
elif get_line_count() > get_visible_line_count() and _current_font_size > _min_size:
_shrink_font()
return

if _current_font_size < _max_size and _current_font_size < _min_size:
_enlarge_font()
return
elif get_line_count() == get_visible_line_count() and _current_font_size < _max_size:
_enlarge_font()
return
_last_size_state = LABEL_SIZE_STATE.IDLE


## Makes the font size smaller. Rechecks or stops the cycle depending on the conditions.
func _shrink_font():
_apply_font_size(_current_font_size - 1)
if _last_size_state == LABEL_SIZE_STATE.JUST_ENLARGED: ## To stop infinite cycles.
_last_size_state = LABEL_SIZE_STATE.IDLE
else:
_last_size_state = LABEL_SIZE_STATE.JUST_SHRUNK
_check_line_count()


## Makes the font size larger. Rechecks/Shrinks/stops the cycle depending on the conditions.
func _enlarge_font():
_apply_font_size(_current_font_size + 1)
if _last_size_state == LABEL_SIZE_STATE.JUST_SHRUNK:
if get_line_count() > get_visible_line_count():
_last_size_state = LABEL_SIZE_STATE.JUST_ENLARGED
_shrink_font()
else: ## To stop infinite cycles.
_last_size_state = LABEL_SIZE_STATE.IDLE
else:
_last_size_state = LABEL_SIZE_STATE.JUST_ENLARGED
_check_line_count()


## Applies the new font size.
func _apply_font_size(new_size: int) -> void:
_size_just_modified_by_autosizer = true
if label_settings != null:
label_settings.font_size = new_size
else:
set("theme_override_font_sizes/font_size", new_size)
_current_font_size = new_size


#endregion


#region Public functions
## Gets called in-editor and sets the default values.
func _set_editor_defaults() -> void:
_editor_defaults_set = true
clip_text = true
autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
if label_settings != null:
label_settings = label_settings.duplicate() ## These are not unique by default, so we it gets duplicated to not override every instance.
label_settings.changed.connect(_on_font_resource_changed)
_check_font_size()
_connect_signals()
set_deferred("_max_size", _current_font_size)


## Text can be changed via either: set_text(value), or _my_label.text = value. Both will trigger a line check.
##**If you're doing some testing/developing, if you are changing the text from withit one of the label classes themselves, do it like self.set_text(value) or self.text = value, othersise it doesn't trigger a size check.
##In a real scenario you wouldn't be changing the text from within the class itself though.**
func set_text(new_text: String) -> void:
text = new_text
call_deferred(_check_line_count.get_method())
#endregion
26 changes: 26 additions & 0 deletions addons/label_font_auto_sizer/label_font_auto_size_manager.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@tool
extends Node
class_name LabelFontAutoSizeManager

#region Variables
static var _active_labels : Array[Control]
#endregion


#region Public functions
static func register_label(label: Control) -> void:
_active_labels.append(label)


static func erase_label(label: Control) -> void:
_active_labels.erase(label)


## This function is to be called by the user after manually changing the locale of the game.
## Will cause to check the size of all the active labels, useful after changing the language of text pieces.
## Call it with: LabelFotAutoSizeManager.locale_changed()
static func locale_chaged() -> void:
for label: Control in _active_labels:
label._on_locale_changed()
#endregion

7 changes: 7 additions & 0 deletions addons/label_font_auto_sizer/plugin.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[plugin]

name="LabelFontAutoSizer - Godot 4.3"
description="Tool that makes labels text fit into the rect."
author="Lescandez"
version="1.1.0"
script="plugin.gd"
15 changes: 15 additions & 0 deletions addons/label_font_auto_sizer/plugin.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@tool
extends EditorPlugin


#region Virtual functions
func _enter_tree():
add_custom_type("AutoSizeLabel", "Label", preload("label_auto_sizer.gd"), preload("icon.svg"))
add_custom_type("AutoSizeRichTextlabel", "RichTextLabel", preload("rich_label_auto_sizer.gd"), preload("icon.svg"))


func _exit_tree():
remove_custom_type("AutoSizeLabel")
remove_custom_type("AutoSizeRichTextlabel")
#endregion

Loading

0 comments on commit 1e73a72

Please sign in to comment.