-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Localization Feature Patch: English, French, Chinese (SC)
- Loading branch information
1 parent
95dde8a
commit 1e73a72
Showing
74 changed files
with
2,765 additions
and
1,051 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
26
addons/label_font_auto_sizer/label_font_auto_size_manager.gd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
Oops, something went wrong.