mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2025-12-16 13:30:07 +01:00
Use static typing in all demos (#1063)
This leads to code that is easier to understand and runs faster thanks to GDScript's typed instructions. The untyped declaration warning is now enabled on all projects where type hints were added. All projects currently run without any untyped declration warnings. Dodge the Creeps and Squash the Creeps demos intentionally don't use type hints to match the documentation, where type hints haven't been adopted yet (given its beginner focus).
This commit is contained in:
@@ -45,7 +45,7 @@ func _on_variable_size_value_changed(value: float) -> void:
|
||||
func _on_variable_weight_value_changed(value: float) -> void:
|
||||
$"TabContainer/Variable fonts/Variables/Weight/Value".text = str(value)
|
||||
# Workaround to make the variable font axis value effective. This requires duplicating the dictionary.
|
||||
var dict = variable_font_variation.variation_opentype.duplicate()
|
||||
var dict := variable_font_variation.variation_opentype.duplicate()
|
||||
dict["weight"] = value
|
||||
variable_font_variation.variation_opentype = dict
|
||||
|
||||
@@ -53,7 +53,7 @@ func _on_variable_weight_value_changed(value: float) -> void:
|
||||
func _on_variable_slant_value_changed(value: float) -> void:
|
||||
$"TabContainer/Variable fonts/Variables/Slant/Value".text = str(value)
|
||||
# Workaround to make the variable font axis value effective. This requires duplicating the dictionary.
|
||||
var dict = variable_font_variation.variation_opentype.duplicate()
|
||||
var dict := variable_font_variation.variation_opentype.duplicate()
|
||||
dict["slant"] = value
|
||||
variable_font_variation.variation_opentype = dict
|
||||
|
||||
@@ -61,7 +61,7 @@ func _on_variable_slant_value_changed(value: float) -> void:
|
||||
func _on_variable_cursive_toggled(button_pressed: bool) -> void:
|
||||
$"TabContainer/Variable fonts/Variables/Cursive".button_pressed = button_pressed
|
||||
# Workaround to make the variable font axis value effective. This requires duplicating the dictionary.
|
||||
var dict = variable_font_variation.variation_opentype.duplicate()
|
||||
var dict := variable_font_variation.variation_opentype.duplicate()
|
||||
dict["custom_CRSV"] = int(button_pressed)
|
||||
variable_font_variation.variation_opentype = dict
|
||||
|
||||
@@ -69,7 +69,7 @@ func _on_variable_cursive_toggled(button_pressed: bool) -> void:
|
||||
func _on_variable_casual_toggled(button_pressed: bool) -> void:
|
||||
$"TabContainer/Variable fonts/Variables/Casual".button_pressed = button_pressed
|
||||
# Workaround to make the variable font axis value effective. This requires duplicating the dictionary.
|
||||
var dict = variable_font_variation.variation_opentype.duplicate()
|
||||
var dict := variable_font_variation.variation_opentype.duplicate()
|
||||
dict["custom_CASL"] = int(button_pressed)
|
||||
variable_font_variation.variation_opentype = dict
|
||||
|
||||
@@ -77,13 +77,13 @@ func _on_variable_casual_toggled(button_pressed: bool) -> void:
|
||||
func _on_variable_monospace_toggled(button_pressed: bool) -> void:
|
||||
$"TabContainer/Variable fonts/Variables/Monospace".button_pressed = button_pressed
|
||||
# Workaround to make the variable font axis value effective. This requires duplicating the dictionary.
|
||||
var dict = variable_font_variation.variation_opentype.duplicate()
|
||||
var dict := variable_font_variation.variation_opentype.duplicate()
|
||||
dict["custom_MONO"] = int(button_pressed)
|
||||
variable_font_variation.variation_opentype = dict
|
||||
|
||||
|
||||
func _on_system_font_value_text_changed(new_text: String) -> void:
|
||||
for label in [
|
||||
for label: Label in [
|
||||
$"TabContainer/System fonts/VBoxContainer/SansSerif/Value",
|
||||
$"TabContainer/System fonts/VBoxContainer/Serif/Value",
|
||||
$"TabContainer/System fonts/VBoxContainer/Monospace/Value",
|
||||
@@ -96,7 +96,7 @@ func _on_system_font_value_text_changed(new_text: String) -> void:
|
||||
|
||||
func _on_system_font_weight_value_changed(value: float) -> void:
|
||||
$"TabContainer/System fonts/Weight/Value".text = str(value)
|
||||
for label in [
|
||||
for label: Label in [
|
||||
$"TabContainer/System fonts/VBoxContainer/SansSerif/Value",
|
||||
$"TabContainer/System fonts/VBoxContainer/Serif/Value",
|
||||
$"TabContainer/System fonts/VBoxContainer/Monospace/Value",
|
||||
@@ -105,10 +105,10 @@ func _on_system_font_weight_value_changed(value: float) -> void:
|
||||
$"TabContainer/System fonts/VBoxContainer/Custom/Value"
|
||||
]:
|
||||
var system_font: SystemFont = label.get_theme_font("font")
|
||||
system_font.font_weight = value
|
||||
system_font.font_weight = int(value)
|
||||
|
||||
func _on_system_font_italic_toggled(button_pressed: bool) -> void:
|
||||
for label in [
|
||||
for label: Label in [
|
||||
$"TabContainer/System fonts/VBoxContainer/SansSerif/Value",
|
||||
$"TabContainer/System fonts/VBoxContainer/Serif/Value",
|
||||
$"TabContainer/System fonts/VBoxContainer/Monospace/Value",
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
extends LineEdit
|
||||
|
||||
func _structured_text_parser(args, p_text):
|
||||
var output = []
|
||||
var tags = p_text.split(":")
|
||||
var prev = 0
|
||||
var count = int(tags.size())
|
||||
func _structured_text_parser(_args: Variant, p_text: String) -> Array:
|
||||
var output: Array[Vector3i] = []
|
||||
var tags := p_text.split(":")
|
||||
var prev := 0
|
||||
var count := tags.size()
|
||||
output.clear()
|
||||
for i in range(count):
|
||||
var range1 = Vector3i(prev, prev + tags[i].length(), TextServer.DIRECTION_AUTO)
|
||||
var range2 = Vector3i(prev + tags[i].length(), prev + tags[i].length() + 1, TextServer.DIRECTION_AUTO)
|
||||
|
||||
for i in count:
|
||||
var range1 := Vector3i(prev, prev + tags[i].length(), TextServer.DIRECTION_AUTO)
|
||||
var range2 := Vector3i(prev + tags[i].length(), prev + tags[i].length() + 1, TextServer.DIRECTION_AUTO)
|
||||
output.push_front(range1)
|
||||
output.push_front(range2)
|
||||
prev = prev + tags[i].length() + 1
|
||||
|
||||
return output
|
||||
|
||||
@@ -17,6 +17,10 @@ config/features=PackedStringArray("4.2")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -18,6 +18,10 @@ config/features=PackedStringArray("4.2")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
extends ColorPickerButton
|
||||
|
||||
# Returns the data to pass from an object when you click and drag away from
|
||||
# this object. Also calls set_drag_preview() to show the mouse dragging
|
||||
# this object. Also calls `set_drag_preview()` to show the mouse dragging
|
||||
# something so the user knows that the operation is working.
|
||||
func _get_drag_data(_pos):
|
||||
func _get_drag_data(_at_position: Vector2) -> Color:
|
||||
# Use another colorpicker as drag preview.
|
||||
var cpb = ColorPickerButton.new()
|
||||
var cpb := ColorPickerButton.new()
|
||||
cpb.color = color
|
||||
cpb.size = Vector2(80.0, 50.0)
|
||||
|
||||
# Allows us to center the color picker on the mouse
|
||||
var preview = Control.new()
|
||||
# Allows us to center the color picker on the mouse.
|
||||
var preview := Control.new()
|
||||
preview.add_child(cpb)
|
||||
cpb.position = -0.5 * cpb.size
|
||||
|
||||
# Sets what the user will see they are dragging
|
||||
# Sets what the user will see they are dragging.
|
||||
set_drag_preview(preview)
|
||||
|
||||
# Return color as drag data.
|
||||
@@ -23,10 +23,11 @@ func _get_drag_data(_pos):
|
||||
|
||||
# Returns a boolean by examining the data being dragged to see if it's valid
|
||||
# to drop here.
|
||||
func _can_drop_data(_pos, data):
|
||||
func _can_drop_data(_at_position: Vector2, data: Variant) -> bool:
|
||||
return typeof(data) == TYPE_COLOR
|
||||
|
||||
|
||||
# Takes the data being dragged and processes it. In this case, we are
|
||||
# assigning a new color to the target color picker button.
|
||||
func _drop_data(_pos, data):
|
||||
func _drop_data(_at_position: Vector2, data: Variant) -> void:
|
||||
color = data
|
||||
|
||||
@@ -21,6 +21,10 @@ config/features=PackedStringArray("4.2")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,53 +1,52 @@
|
||||
extends Control
|
||||
|
||||
# A constant for whether or not we're needing to undo a shape.
|
||||
const UNDO_MODE_SHAPE = -2
|
||||
# A constant for whether or not we can undo.
|
||||
const UNDO_NONE = -1
|
||||
|
||||
# Enums for the various modes and brush shapes that can be applied.
|
||||
enum BrushModes {
|
||||
enum BrushMode {
|
||||
PENCIL,
|
||||
ERASER,
|
||||
CIRCLE_SHAPE,
|
||||
RECTANGLE_SHAPE,
|
||||
}
|
||||
|
||||
enum BrushShapes {
|
||||
enum BrushShape {
|
||||
RECTANGLE,
|
||||
CIRCLE,
|
||||
}
|
||||
|
||||
# A constant for whether or not we're needing to undo a shape.
|
||||
const UNDO_MODE_SHAPE = -2
|
||||
# A constant for whether or not we can undo.
|
||||
const UNDO_NONE = -1
|
||||
|
||||
# A list to hold all of the dictionaries that make up each brush.
|
||||
var brush_data_list = []
|
||||
var brush_data_list: Array[Dictionary] = []
|
||||
|
||||
# A boolean to hold whether or not the mouse is inside the drawing area, the mouse position last _process call
|
||||
# and the position of the mouse when the left mouse button was pressed.
|
||||
var is_mouse_in_drawing_area = false
|
||||
var last_mouse_pos = Vector2()
|
||||
var mouse_click_start_pos = null
|
||||
var is_mouse_in_drawing_area := false
|
||||
var last_mouse_pos := Vector2()
|
||||
var mouse_click_start_pos := Vector2.INF
|
||||
|
||||
# A boolean to tell whether we've set undo_elements_list_num, which holds the size of draw_elements_list
|
||||
# before a new stroke is added (unless the current brush mode is 'rectangle shape' or 'circle shape', in
|
||||
# which case we do things a litte differently. See the undo_stroke function for more details).
|
||||
var undo_set = false
|
||||
var undo_element_list_num = -1
|
||||
var undo_set := false
|
||||
var undo_element_list_num := -1
|
||||
|
||||
# The current brush settings: The mode, size, color, and shape we have currently selected.
|
||||
var brush_mode = BrushModes.PENCIL
|
||||
var brush_size = 32
|
||||
var brush_color = Color.BLACK
|
||||
var brush_shape = BrushShapes.CIRCLE;
|
||||
var brush_mode := BrushMode.PENCIL
|
||||
var brush_size := 32
|
||||
var brush_color := Color.BLACK
|
||||
var brush_shape := BrushShape.CIRCLE
|
||||
|
||||
# The color of the background. We need this for the eraser (see the how we handle the eraser
|
||||
# in the _draw function for more details).
|
||||
var bg_color = Color.WHITE
|
||||
var bg_color := Color.WHITE
|
||||
|
||||
@onready var drawing_area = $"../DrawingAreaBG"
|
||||
@onready var drawing_area: Panel = $"../DrawingAreaBG"
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
var mouse_pos = get_viewport().get_mouse_position()
|
||||
func _process(_delta: float) -> void:
|
||||
var mouse_pos := get_viewport().get_mouse_position()
|
||||
|
||||
# Check if the mouse is currently inside the canvas/drawing-area.
|
||||
var drawing_area_rect := Rect2(drawing_area.position, drawing_area.size)
|
||||
@@ -57,14 +56,14 @@ func _process(_delta):
|
||||
# If we do not have a position for when the mouse was first clicked, then this must
|
||||
# be the first time is_mouse_button_pressed has been called since the mouse button was
|
||||
# released, so we need to store the position.
|
||||
if mouse_click_start_pos == null:
|
||||
if mouse_click_start_pos.is_equal_approx(Vector2.INF):
|
||||
mouse_click_start_pos = mouse_pos
|
||||
|
||||
# If the mouse is inside the canvas and the mouse is 1px away from the position of the mouse last _process call.
|
||||
if check_if_mouse_is_inside_canvas():
|
||||
if mouse_pos.distance_to(last_mouse_pos) >= 1:
|
||||
# If we are in pencil or eraser mode, then we need to draw.
|
||||
if brush_mode == BrushModes.PENCIL or brush_mode == BrushModes.ERASER:
|
||||
if brush_mode == BrushMode.PENCIL or brush_mode == BrushMode.ERASER:
|
||||
# If undo has not been set, meaning we've started a new stroke, then store the size of the
|
||||
# draw_elements_list so we can undo from this point in time.
|
||||
if undo_set == false:
|
||||
@@ -81,20 +80,20 @@ func _process(_delta):
|
||||
if check_if_mouse_is_inside_canvas():
|
||||
# If we're using either the circle shape mode, or the rectangle shape mode, then
|
||||
# add the brush object to draw_elements_array.
|
||||
if brush_mode == BrushModes.CIRCLE_SHAPE or brush_mode == BrushModes.RECTANGLE_SHAPE:
|
||||
if brush_mode == BrushMode.CIRCLE_SHAPE or brush_mode == BrushMode.RECTANGLE_SHAPE:
|
||||
add_brush(mouse_pos, brush_mode)
|
||||
# We handle undo's differently than either pencil or eraser mode, so we need to set undo
|
||||
# element_list_num to -2 so we can tell if we need to undo a shape. See undo_stroke for details.
|
||||
undo_element_list_num = UNDO_MODE_SHAPE
|
||||
# Since we've released the left mouse, we need to get a new mouse_click_start_pos next time
|
||||
#is_mouse_button_pressed is true.
|
||||
mouse_click_start_pos = null
|
||||
# is_mouse_button_pressed is true.
|
||||
mouse_click_start_pos = Vector2.INF
|
||||
|
||||
# Store mouse_pos as last_mouse_pos now that we're done with _process.
|
||||
last_mouse_pos = mouse_pos
|
||||
|
||||
|
||||
func check_if_mouse_is_inside_canvas():
|
||||
func check_if_mouse_is_inside_canvas() -> bool:
|
||||
# Make sure we have a mouse click starting position.
|
||||
if mouse_click_start_pos != null:
|
||||
# Make sure the mouse click starting position is inside the canvas.
|
||||
@@ -107,7 +106,7 @@ func check_if_mouse_is_inside_canvas():
|
||||
return false
|
||||
|
||||
|
||||
func undo_stroke():
|
||||
func undo_stroke() -> void:
|
||||
# Only undo a stroke if we have one.
|
||||
if undo_element_list_num == UNDO_NONE:
|
||||
return
|
||||
@@ -125,22 +124,22 @@ func undo_stroke():
|
||||
# Otherwise we're removing a either a pencil stroke or a eraser stroke.
|
||||
else:
|
||||
# Figure out how many elements/brushes we've added in the last stroke.
|
||||
var elements_to_remove = brush_data_list.size() - undo_element_list_num
|
||||
var elements_to_remove := brush_data_list.size() - undo_element_list_num
|
||||
# Remove all of the elements we've added this in the last stroke.
|
||||
#warning-ignore:unused_variable
|
||||
for elment_num in range(0, elements_to_remove):
|
||||
for elment_num in elements_to_remove:
|
||||
brush_data_list.pop_back()
|
||||
|
||||
# Now that we've undone a stoke, we cannot undo again until another stoke is added.
|
||||
undo_element_list_num = UNDO_NONE
|
||||
|
||||
# Redraw the brushes
|
||||
# Redraw the brushes.
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func add_brush(mouse_pos, type):
|
||||
func add_brush(mouse_pos: Vector2, type: BrushMode) -> void:
|
||||
# Make new brush dictionary that will hold all of the data we need for the brush.
|
||||
var new_brush = {}
|
||||
var new_brush := {}
|
||||
|
||||
# Populate the dictionary with values based on the global brush variables.
|
||||
# We will override these as needed if the brush is a rectange or circle.
|
||||
@@ -152,9 +151,9 @@ func add_brush(mouse_pos, type):
|
||||
|
||||
# If the new bursh is a rectangle shape, we need to calculate the top left corner of the rectangle and the
|
||||
# bottom right corner of the rectangle.
|
||||
if type == BrushModes.RECTANGLE_SHAPE:
|
||||
var TL_pos = Vector2()
|
||||
var BR_pos = Vector2()
|
||||
if type == BrushMode.RECTANGLE_SHAPE:
|
||||
var TL_pos := Vector2()
|
||||
var BR_pos := Vector2()
|
||||
|
||||
# Figure out the left and right positions of the corners and assign them to the proper variable.
|
||||
if mouse_pos.x < mouse_click_start_pos.x:
|
||||
@@ -177,9 +176,9 @@ func add_brush(mouse_pos, type):
|
||||
new_brush.brush_shape_rect_pos_BR = BR_pos
|
||||
|
||||
# If the brush isa circle shape, then we need to calculate the radius of the circle.
|
||||
if type == BrushModes.CIRCLE_SHAPE:
|
||||
if type == BrushMode.CIRCLE_SHAPE:
|
||||
# Get the center point inbetween the mouse position and the position of the mouse when we clicked.
|
||||
var center_pos = Vector2((mouse_pos.x + mouse_click_start_pos.x) / 2, (mouse_pos.y + mouse_click_start_pos.y) / 2)
|
||||
var center_pos := Vector2((mouse_pos.x + mouse_click_start_pos.x) / 2, (mouse_pos.y + mouse_click_start_pos.y) / 2)
|
||||
# Assign the brush position to the center point, and calculate the radius of the circle using the distance from
|
||||
# the center to the top/bottom positon of the mouse.
|
||||
new_brush.brush_pos = center_pos
|
||||
@@ -190,50 +189,56 @@ func add_brush(mouse_pos, type):
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _draw():
|
||||
# Go through all of the brushes in brush_data_list.
|
||||
func _draw() -> void:
|
||||
for brush in brush_data_list:
|
||||
match brush.brush_type:
|
||||
BrushModes.PENCIL:
|
||||
BrushMode.PENCIL:
|
||||
# If the brush shape is a rectangle, then we need to make a Rect2 so we can use draw_rect.
|
||||
# Draw_rect draws a rectagle at the top left corner, using the scale for the size.
|
||||
# So we offset the position by half of the brush size so the rectangle's center is at mouse position.
|
||||
if brush.brush_shape == BrushShapes.RECTANGLE:
|
||||
var rect = Rect2(brush.brush_pos - Vector2(brush.brush_size / 2, brush.brush_size / 2), Vector2(brush.brush_size, brush.brush_size))
|
||||
if brush.brush_shape == BrushShape.RECTANGLE:
|
||||
var rect := Rect2(brush.brush_pos - Vector2(brush.brush_size / 2, brush.brush_size / 2), Vector2(brush.brush_size, brush.brush_size))
|
||||
draw_rect(rect, brush.brush_color)
|
||||
# If the brush shape is a circle, then we draw a circle at the mouse position,
|
||||
# making the radius half of brush size (so the circle is brush size pixels in diameter).
|
||||
elif brush.brush_shape == BrushShapes.CIRCLE:
|
||||
elif brush.brush_shape == BrushShape.CIRCLE:
|
||||
draw_circle(brush.brush_pos, brush.brush_size / 2, brush.brush_color)
|
||||
BrushModes.ERASER:
|
||||
BrushMode.ERASER:
|
||||
# NOTE: this is a really cheap way of erasing that isn't really erasing!
|
||||
# However, this gives similar results in a fairy simple way!
|
||||
|
||||
# Erasing works exactly the same was as pencil does for both the rectangle shape and the circle shape,
|
||||
# but instead of using brush.brush_color, we instead use bg_color instead.
|
||||
if brush.brush_shape == BrushShapes.RECTANGLE:
|
||||
var rect = Rect2(brush.brush_pos - Vector2(brush.brush_size / 2, brush.brush_size / 2), Vector2(brush.brush_size, brush.brush_size))
|
||||
if brush.brush_shape == BrushShape.RECTANGLE:
|
||||
var rect := Rect2(brush.brush_pos - Vector2(brush.brush_size / 2, brush.brush_size / 2), Vector2(brush.brush_size, brush.brush_size))
|
||||
draw_rect(rect, bg_color)
|
||||
elif brush.brush_shape == BrushShapes.CIRCLE:
|
||||
elif brush.brush_shape == BrushShape.CIRCLE:
|
||||
draw_circle(brush.brush_pos, brush.brush_size / 2, bg_color)
|
||||
BrushModes.RECTANGLE_SHAPE:
|
||||
BrushMode.RECTANGLE_SHAPE:
|
||||
# We make a Rect2 with the postion at the top left. To get the size we take the bottom right position
|
||||
# and subtract the top left corner's position.
|
||||
var rect = Rect2(brush.brush_pos, brush.brush_shape_rect_pos_BR - brush.brush_pos)
|
||||
var rect := Rect2(brush.brush_pos, brush.brush_shape_rect_pos_BR - brush.brush_pos)
|
||||
draw_rect(rect, brush.brush_color)
|
||||
BrushModes.CIRCLE_SHAPE:
|
||||
BrushMode.CIRCLE_SHAPE:
|
||||
# We simply draw a circle using stored in brush.
|
||||
draw_circle(brush.brush_pos, brush.brush_shape_circle_radius, brush.brush_color)
|
||||
|
||||
|
||||
func save_picture(path):
|
||||
func save_picture(path: String) -> void:
|
||||
# Wait until the frame has finished before getting the texture.
|
||||
await RenderingServer.frame_post_draw
|
||||
|
||||
# Get the viewport image.
|
||||
var img = get_viewport().get_texture().get_image()
|
||||
var img := get_viewport().get_texture().get_image()
|
||||
# Crop the image so we only have canvas area.
|
||||
var cropped_image = img.get_region(Rect2(drawing_area.position, drawing_area.size))
|
||||
var cropped_image := img.get_region(Rect2(drawing_area.position, drawing_area.size))
|
||||
|
||||
# Save the image with the passed in path we got from the save dialog.
|
||||
cropped_image.save_png(path)
|
||||
# File format is based on the extension given by the user in the save dialog.
|
||||
if path.to_lower().ends_with(".png"):
|
||||
cropped_image.save_png(path)
|
||||
elif path.to_lower().ends_with(".webp"):
|
||||
# `save_webp()` is lossless by default.
|
||||
cropped_image.save_webp(path)
|
||||
elif path.to_lower().ends_with(".jpg") or path.to_lower().ends_with(".jpeg"):
|
||||
# JPEG is always a lossy format, so use the highest possible quality.
|
||||
cropped_image.save_jpg(path, 1.0)
|
||||
|
||||
@@ -335,5 +335,5 @@ metadata/_edit_use_custom_anchors = false
|
||||
size = Vector2i(800, 300)
|
||||
min_size = Vector2i(800, 300)
|
||||
access = 2
|
||||
filters = PackedStringArray("*.png")
|
||||
filters = PackedStringArray("*.png ; PNG Image", "*.webp ; WebP Image", "*.jpeg, *.jpg ; JPEG Image")
|
||||
show_hidden_files = true
|
||||
|
||||
@@ -21,6 +21,7 @@ config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
gdscript/warnings/redundant_await=false
|
||||
|
||||
[display]
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
extends Panel
|
||||
|
||||
@onready var brush_settings = $BrushSettings
|
||||
@onready var label_brush_size = brush_settings.get_node(^"LabelBrushSize")
|
||||
@onready var label_brush_shape = brush_settings.get_node(^"LabelBrushShape")
|
||||
@onready var label_stats = $LabelStats
|
||||
@onready var label_tools = $LabelTools
|
||||
@onready var brush_settings: Control = $BrushSettings
|
||||
@onready var label_brush_size: Label = brush_settings.get_node(^"LabelBrushSize")
|
||||
@onready var label_brush_shape: Label = brush_settings.get_node(^"LabelBrushShape")
|
||||
@onready var label_stats: Label = $LabelStats
|
||||
@onready var label_tools: Label = $LabelTools
|
||||
|
||||
@onready var _parent = get_parent()
|
||||
@onready var save_dialog = _parent.get_node(^"SaveFileDialog")
|
||||
@onready var paint_control = _parent.get_node(^"PaintControl")
|
||||
@onready var _parent: Control = get_parent()
|
||||
@onready var save_dialog: FileDialog = _parent.get_node(^"SaveFileDialog")
|
||||
@onready var paint_control: Control = _parent.get_node(^"PaintControl")
|
||||
|
||||
func _ready():
|
||||
# Assign all of the needed signals for the oppersation buttons.
|
||||
func _ready() -> void:
|
||||
# Assign all of the needed signals for the option buttons.
|
||||
$ButtonUndo.pressed.connect(button_pressed.bind("undo_stroke"))
|
||||
$ButtonSave.pressed.connect(button_pressed.bind("save_picture"))
|
||||
$ButtonClear.pressed.connect(button_pressed.bind("clear_picture"))
|
||||
@@ -32,48 +32,45 @@ func _ready():
|
||||
# Assign the "file_selected" signal in SaveFileDialog.
|
||||
save_dialog.file_selected.connect(save_file_selected)
|
||||
|
||||
# Set physics process so we can update the status label.
|
||||
set_physics_process(true)
|
||||
|
||||
|
||||
func _physics_process(_delta):
|
||||
func _physics_process(_delta: float) -> void:
|
||||
# Update the status label with the newest brush element count.
|
||||
label_stats.text = "Brush objects: " + str(paint_control.brush_data_list.size())
|
||||
label_stats.text = "Brush objects: %d" % paint_control.brush_data_list.size()
|
||||
|
||||
|
||||
func button_pressed(button_name):
|
||||
func button_pressed(button_name: String) -> void:
|
||||
# If a brush mode button is pressed.
|
||||
var tool_name = null
|
||||
var shape_name = null
|
||||
var tool_name := ""
|
||||
var shape_name := ""
|
||||
|
||||
if button_name == "mode_pencil":
|
||||
paint_control.brush_mode = paint_control.BrushModes.PENCIL
|
||||
brush_settings.modulate = Color(1, 1, 1, 1)
|
||||
paint_control.brush_mode = paint_control.BrushMode.PENCIL
|
||||
brush_settings.modulate = Color(1, 1, 1)
|
||||
tool_name = "Pencil"
|
||||
elif button_name == "mode_eraser":
|
||||
paint_control.brush_mode = paint_control.BrushModes.ERASER
|
||||
brush_settings.modulate = Color(1, 1, 1, 1)
|
||||
paint_control.brush_mode = paint_control.BrushMode.ERASER
|
||||
brush_settings.modulate = Color(1, 1, 1)
|
||||
tool_name = "Eraser"
|
||||
elif button_name == "mode_rectangle":
|
||||
paint_control.brush_mode = paint_control.BrushModes.RECTANGLE_SHAPE
|
||||
paint_control.brush_mode = paint_control.BrushMode.RECTANGLE_SHAPE
|
||||
brush_settings.modulate = Color(1, 1, 1, 0.5)
|
||||
tool_name = "Rectangle shape"
|
||||
elif button_name == "mode_circle":
|
||||
paint_control.brush_mode = paint_control.BrushModes.CIRCLE_SHAPE
|
||||
paint_control.brush_mode = paint_control.BrushMode.CIRCLE_SHAPE
|
||||
brush_settings.modulate = Color(1, 1, 1, 0.5)
|
||||
tool_name = "Circle shape"
|
||||
|
||||
# If a brush shape button is pressed
|
||||
elif button_name == "shape_rectangle":
|
||||
paint_control.brush_shape = paint_control.BrushShapes.RECTANGLE
|
||||
paint_control.brush_shape = paint_control.BrushShape.RECTANGLE
|
||||
shape_name = "Rectangle"
|
||||
elif button_name == "shape_circle":
|
||||
paint_control.brush_shape = paint_control.BrushShapes.CIRCLE
|
||||
shape_name = "Circle";
|
||||
paint_control.brush_shape = paint_control.BrushShape.CIRCLE
|
||||
shape_name = "Circle"
|
||||
|
||||
# If a opperation button is pressed
|
||||
elif button_name == "clear_picture":
|
||||
paint_control.brush_data_list = []
|
||||
paint_control.brush_data_list.clear()
|
||||
paint_control.queue_redraw()
|
||||
elif button_name == "save_picture":
|
||||
save_dialog.popup_centered()
|
||||
@@ -81,18 +78,18 @@ func button_pressed(button_name):
|
||||
paint_control.undo_stroke()
|
||||
|
||||
# Update the labels (in case the brush mode or brush shape has changed).
|
||||
if tool_name != null:
|
||||
label_tools.text = "Selected tool: " + tool_name
|
||||
if shape_name != null:
|
||||
label_brush_shape.text = "Brush shape: " + shape_name
|
||||
if not tool_name.is_empty():
|
||||
label_tools.text = "Selected tool: %s" % tool_name
|
||||
if not shape_name.is_empty():
|
||||
label_brush_shape.text = "Brush shape: %s" % shape_name
|
||||
|
||||
|
||||
func brush_color_changed(color):
|
||||
func brush_color_changed(color: Color) -> void:
|
||||
# Change the brush color to whatever color the color picker is.
|
||||
paint_control.brush_color = color
|
||||
|
||||
|
||||
func background_color_changed(color):
|
||||
func background_color_changed(color: Color) -> void:
|
||||
# Change the background color to whatever colorthe background color picker is.
|
||||
get_parent().get_node(^"DrawingAreaBG").modulate = color
|
||||
paint_control.bg_color = color
|
||||
@@ -100,12 +97,12 @@ func background_color_changed(color):
|
||||
paint_control.queue_redraw()
|
||||
|
||||
|
||||
func brush_size_changed(value):
|
||||
func brush_size_changed(value: float) -> void:
|
||||
# Change the size of the brush, and update the label to reflect the new value.
|
||||
paint_control.brush_size = ceil(value)
|
||||
paint_control.brush_size = ceilf(value)
|
||||
label_brush_size.text = "Brush size: " + str(ceil(value)) + "px"
|
||||
|
||||
|
||||
func save_file_selected(path):
|
||||
func save_file_selected(path: String) -> void:
|
||||
# Call save_picture in paint_control, passing in the path we recieved from SaveFileDialog.
|
||||
paint_control.save_picture(path)
|
||||
|
||||
@@ -1,39 +1,48 @@
|
||||
extends Button
|
||||
|
||||
@export var action: String = "ui_up"
|
||||
@export var action := "ui_up"
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
assert(InputMap.has_action(action))
|
||||
set_process_unhandled_key_input(false)
|
||||
display_current_key()
|
||||
|
||||
|
||||
func _toggled(is_button_pressed):
|
||||
func _toggled(is_button_pressed: bool) -> void:
|
||||
set_process_unhandled_key_input(is_button_pressed)
|
||||
if is_button_pressed:
|
||||
text = "<press a key>"
|
||||
modulate = Color.YELLOW
|
||||
release_focus()
|
||||
else:
|
||||
display_current_key()
|
||||
modulate = Color.WHITE
|
||||
# Grab focus after assigning a key, so that you can go to the next
|
||||
# key using the keyboard.
|
||||
grab_focus()
|
||||
|
||||
|
||||
func _unhandled_key_input(event):
|
||||
# Note that you can use the _input callback instead, especially if
|
||||
# you want to work with gamepads.
|
||||
remap_action_to(event)
|
||||
button_pressed = false
|
||||
# NOTE: You can use the `_input()` callback instead, especially if
|
||||
# you want to work with gamepads.
|
||||
func _unhandled_key_input(event: InputEvent) -> void:
|
||||
# Skip if pressing Enter, so that the input mapping GUI can be navigated
|
||||
# with the keyboard. The downside of this approach is that the Enter
|
||||
# key can't be bound to actions.
|
||||
if event is InputEventKey and event.keycode != KEY_ENTER:
|
||||
remap_action_to(event)
|
||||
button_pressed = false
|
||||
|
||||
|
||||
func remap_action_to(event):
|
||||
func remap_action_to(event: InputEvent) -> void:
|
||||
# We first change the event in this game instance.
|
||||
InputMap.action_erase_events(action)
|
||||
InputMap.action_add_event(action, event)
|
||||
# And then save it to the keymaps file
|
||||
# And then save it to the keymaps file.
|
||||
KeyPersistence.keymaps[action] = event
|
||||
KeyPersistence.save_keymap()
|
||||
text = event.as_text()
|
||||
|
||||
|
||||
func display_current_key():
|
||||
var current_key = InputMap.action_get_events(action)[0].as_text()
|
||||
func display_current_key() -> void:
|
||||
var current_key := InputMap.action_get_events(action)[0].as_text()
|
||||
text = current_key
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# the key maps in a simple way through a dictionary.
|
||||
extends Node
|
||||
|
||||
const keymaps_path = "user://keymaps.dat"
|
||||
const keymaps_path := "user://keymaps.dat"
|
||||
var keymaps: Dictionary
|
||||
|
||||
|
||||
@@ -10,27 +10,30 @@ func _ready() -> void:
|
||||
# First we create the keymap dictionary on startup with all
|
||||
# the keymap actions we have.
|
||||
for action in InputMap.get_actions():
|
||||
if InputMap.action_get_events(action).size() != 0:
|
||||
if not InputMap.action_get_events(action).is_empty():
|
||||
keymaps[action] = InputMap.action_get_events(action)[0]
|
||||
|
||||
load_keymap()
|
||||
|
||||
|
||||
func load_keymap() -> void:
|
||||
if not FileAccess.file_exists(keymaps_path):
|
||||
save_keymap() # There is no save file yet, so let's create one.
|
||||
# There is no save file yet, so let's create one.
|
||||
save_keymap()
|
||||
return
|
||||
var file = FileAccess.open(keymaps_path, FileAccess.READ)
|
||||
var temp_keymap = file.get_var(true) as Dictionary
|
||||
|
||||
var file := FileAccess.open(keymaps_path, FileAccess.READ)
|
||||
var temp_keymap: Dictionary = file.get_var(true)
|
||||
file.close()
|
||||
# We don't just replace the keymaps dictionary, because if you
|
||||
# updated your game and removed/added keymaps, the data of this
|
||||
# save file may have invalid actions. So we check one by one to
|
||||
# make sure that the keymap dictionary really has all current actions.
|
||||
for action in keymaps.keys():
|
||||
for action: StringName in keymaps.keys():
|
||||
if temp_keymap.has(action):
|
||||
keymaps[action] = temp_keymap[action]
|
||||
# Whilst setting the keymap dictionary, we also set the
|
||||
# correct InputMap event
|
||||
# correct InputMap event.
|
||||
InputMap.action_erase_events(action)
|
||||
InputMap.action_add_event(action, keymaps[action])
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@ config/icon="res://icon.webp"
|
||||
|
||||
KeyPersistence="*res://KeyPersistence.gd"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=640
|
||||
|
||||
@@ -22,6 +22,10 @@ run/main_scene="res://sdf_font_demo.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
extends Control
|
||||
|
||||
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("toggle_msdf_font"):
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed(&"toggle_msdf_font"):
|
||||
if %FontLabel.get_theme_font("font").multichannel_signed_distance_field:
|
||||
%FontLabel.add_theme_font_override("font", preload("res://montserrat_semibold.ttf"))
|
||||
else:
|
||||
@@ -12,10 +10,12 @@ func _input(event):
|
||||
update_label()
|
||||
|
||||
|
||||
func update_label():
|
||||
%FontMode.text = "Font rendering: %s" % ("MSDF" if %FontLabel.get_theme_font("font").multichannel_signed_distance_field else "Traditional")
|
||||
func update_label() -> void:
|
||||
%FontMode.text = "Font rendering: %s" % (
|
||||
"MSDF" if %FontLabel.get_theme_font("font").multichannel_signed_distance_field else "Traditional"
|
||||
)
|
||||
|
||||
|
||||
func _on_outline_size_value_changed(value):
|
||||
func _on_outline_size_value_changed(value: float) -> void:
|
||||
%FontLabel.add_theme_constant_override("outline_size", int(value))
|
||||
%Value.text = str(value)
|
||||
|
||||
@@ -4,25 +4,24 @@
|
||||
# (with their rect spread across the whole viewport, and Anchor set to Full Rect).
|
||||
extends Control
|
||||
|
||||
var base_window_size = Vector2(
|
||||
var base_window_size := Vector2(
|
||||
ProjectSettings.get_setting("display/window/size/viewport_width"),
|
||||
ProjectSettings.get_setting("display/window/size/viewport_height")
|
||||
)
|
||||
|
||||
# These defaults match this demo's project settings. Adjust as needed if adapting this
|
||||
# in your own project.
|
||||
var stretch_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
|
||||
var stretch_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND
|
||||
var stretch_mode := Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
|
||||
var stretch_aspect := Window.CONTENT_SCALE_ASPECT_EXPAND
|
||||
|
||||
var scale_factor = 1.0
|
||||
var gui_aspect_ratio = -1.0
|
||||
var gui_margin = 0.0
|
||||
var scale_factor := 1.0
|
||||
var gui_aspect_ratio := -1.0
|
||||
var gui_margin := 0.0
|
||||
|
||||
@onready var panel = $Panel
|
||||
@onready var arc = $Panel/AspectRatioContainer
|
||||
@onready var panel: Panel = $Panel
|
||||
@onready var arc: AspectRatioContainer = $Panel/AspectRatioContainer
|
||||
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
# The `resized` signal will be emitted when the window size changes, as the root Control node
|
||||
# is resized whenever the window size changes. This is because the root Control node
|
||||
# uses a Full Rect anchor, so its size will always be equal to the window size.
|
||||
@@ -30,7 +29,7 @@ func _ready():
|
||||
update_container.call_deferred()
|
||||
|
||||
|
||||
func update_container():
|
||||
func update_container() -> void:
|
||||
# The code within this function needs to be run deferred to work around an issue with containers
|
||||
# having a 1-frame delay with updates.
|
||||
# Otherwise, `panel.size` returns a value of the previous frame, which results in incorrect
|
||||
@@ -58,7 +57,7 @@ func update_container():
|
||||
panel.offset_right = -gui_margin
|
||||
|
||||
|
||||
func _on_gui_aspect_ratio_item_selected(index):
|
||||
func _on_gui_aspect_ratio_item_selected(index: int) -> void:
|
||||
match index:
|
||||
0: # Fit to Window
|
||||
gui_aspect_ratio = -1.0
|
||||
@@ -78,17 +77,17 @@ func _on_gui_aspect_ratio_item_selected(index):
|
||||
update_container.call_deferred()
|
||||
|
||||
|
||||
func _on_resized():
|
||||
func _on_resized() -> void:
|
||||
update_container.call_deferred()
|
||||
|
||||
|
||||
func _on_gui_margin_drag_ended(_value_changed):
|
||||
func _on_gui_margin_drag_ended(_value_changed: bool) -> void:
|
||||
gui_margin = $"Panel/AspectRatioContainer/Panel/CenterContainer/Options/GUIMargin/HSlider".value
|
||||
$"Panel/AspectRatioContainer/Panel/CenterContainer/Options/GUIMargin/Value".text = str(gui_margin)
|
||||
update_container.call_deferred()
|
||||
|
||||
|
||||
func _on_window_base_size_item_selected(index):
|
||||
func _on_window_base_size_item_selected(index: int) -> void:
|
||||
match index:
|
||||
0: # 648×648 (1:1)
|
||||
base_window_size = Vector2(648, 648)
|
||||
@@ -111,8 +110,8 @@ func _on_window_base_size_item_selected(index):
|
||||
update_container.call_deferred()
|
||||
|
||||
|
||||
func _on_window_stretch_mode_item_selected(index):
|
||||
stretch_mode = index
|
||||
func _on_window_stretch_mode_item_selected(index: int) -> void:
|
||||
stretch_mode = index as Window.ContentScaleMode
|
||||
get_viewport().content_scale_mode = stretch_mode
|
||||
|
||||
# Disable irrelevant options when the stretch mode is Disabled.
|
||||
@@ -120,12 +119,12 @@ func _on_window_stretch_mode_item_selected(index):
|
||||
$"Panel/AspectRatioContainer/Panel/CenterContainer/Options/WindowStretchAspect/OptionButton".disabled = stretch_mode == Window.CONTENT_SCALE_MODE_DISABLED
|
||||
|
||||
|
||||
func _on_window_stretch_aspect_item_selected(index):
|
||||
stretch_aspect = index
|
||||
func _on_window_stretch_aspect_item_selected(index: int) -> void:
|
||||
stretch_aspect = index as Window.ContentScaleAspect
|
||||
get_viewport().content_scale_aspect = stretch_aspect
|
||||
|
||||
|
||||
func _on_window_scale_factor_drag_ended(_value_changed):
|
||||
func _on_window_scale_factor_drag_ended(_value_changed: bool) -> void:
|
||||
scale_factor = $"Panel/AspectRatioContainer/Panel/CenterContainer/Options/WindowScaleFactor/HSlider".value
|
||||
$"Panel/AspectRatioContainer/Panel/CenterContainer/Options/WindowScaleFactor/Value".text = "%d%%" % (scale_factor * 100)
|
||||
get_viewport().content_scale_factor = scale_factor
|
||||
|
||||
@@ -33,6 +33,10 @@ config/features=PackedStringArray("4.2")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=648
|
||||
|
||||
@@ -1,67 +1,60 @@
|
||||
extends Control
|
||||
|
||||
func _ready():
|
||||
$Main/Pseudolocalization_options/accents.button_pressed = ProjectSettings.get("internationalization/pseudolocalization/replace_with_accents")
|
||||
func _ready() -> void:
|
||||
$Main/Pseudolocalization_options/accents.button_pressed = ProjectSettings.get_setting("internationalization/pseudolocalization/replace_with_accents")
|
||||
$Main/Pseudolocalization_options/toggle.button_pressed = TranslationServer.pseudolocalization_enabled
|
||||
$Main/Pseudolocalization_options/fakebidi.button_pressed = ProjectSettings.get("internationalization/pseudolocalization/fake_bidi")
|
||||
$Main/Pseudolocalization_options/doublevowels.button_pressed = ProjectSettings.get("internationalization/pseudolocalization/double_vowels")
|
||||
$Main/Pseudolocalization_options/override.button_pressed = ProjectSettings.get("internationalization/pseudolocalization/override")
|
||||
$Main/Pseudolocalization_options/skipplaceholders.button_pressed = ProjectSettings.get("internationalization/pseudolocalization/skip_placeholders")
|
||||
$Main/Pseudolocalization_options/prefix/TextEdit.text = ProjectSettings.get("internationalization/pseudolocalization/prefix")
|
||||
$Main/Pseudolocalization_options/suffix/TextEdit.text = ProjectSettings.get("internationalization/pseudolocalization/suffix")
|
||||
$Main/Pseudolocalization_options/exp_ratio/TextEdit.text = str(ProjectSettings.get("internationalization/pseudolocalization/expansion_ratio"))
|
||||
$Main/Pseudolocalization_options/fakebidi.button_pressed = ProjectSettings.get_setting("internationalization/pseudolocalization/fake_bidi")
|
||||
$Main/Pseudolocalization_options/doublevowels.button_pressed = ProjectSettings.get_setting("internationalization/pseudolocalization/double_vowels")
|
||||
$Main/Pseudolocalization_options/override.button_pressed = ProjectSettings.get_setting("internationalization/pseudolocalization/override")
|
||||
$Main/Pseudolocalization_options/skipplaceholders.button_pressed = ProjectSettings.get_setting("internationalization/pseudolocalization/skip_placeholders")
|
||||
$Main/Pseudolocalization_options/prefix/TextEdit.text = ProjectSettings.get_setting("internationalization/pseudolocalization/prefix")
|
||||
$Main/Pseudolocalization_options/suffix/TextEdit.text = ProjectSettings.get_setting("internationalization/pseudolocalization/suffix")
|
||||
$Main/Pseudolocalization_options/exp_ratio/SpinBox.value = float(ProjectSettings.get_setting("internationalization/pseudolocalization/expansion_ratio"))
|
||||
|
||||
|
||||
func _on_accents_toggled(button_pressed):
|
||||
ProjectSettings.set("internationalization/pseudolocalization/replace_with_accents", button_pressed)
|
||||
func _on_accents_toggled(button_pressed: bool) -> void:
|
||||
ProjectSettings.set_setting("internationalization/pseudolocalization/replace_with_accents", button_pressed)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
|
||||
|
||||
func _on_toggle_toggled(button_pressed):
|
||||
func _on_toggle_toggled(button_pressed: bool) -> void:
|
||||
TranslationServer.pseudolocalization_enabled = button_pressed
|
||||
|
||||
|
||||
func _on_fakebidi_toggled(button_pressed):
|
||||
ProjectSettings.set("internationalization/pseudolocalization/fake_bidi", button_pressed)
|
||||
func _on_fake_bidi_toggled(button_pressed: bool) -> void:
|
||||
ProjectSettings.set_setting("internationalization/pseudolocalization/fake_bidi", button_pressed)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
|
||||
|
||||
func _on_prefix_changed():
|
||||
ProjectSettings.set("internationalization/pseudolocalization/prefix", $Main/Pseudolocalization_options/prefix/TextEdit.text)
|
||||
func _on_prefix_changed(new_text: String) -> void:
|
||||
ProjectSettings.set_setting("internationalization/pseudolocalization/prefix", new_text)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
|
||||
|
||||
func _on_suffix_changed():
|
||||
ProjectSettings.set("internationalization/pseudolocalization/suffix", $Main/Pseudolocalization_options/suffix/TextEdit.text)
|
||||
func _on_suffix_changed(new_text: String) -> void:
|
||||
ProjectSettings.set_setting("internationalization/pseudolocalization/suffix", new_text)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
|
||||
|
||||
func _on_Pseudolocalize_pressed():
|
||||
func _on_pseudolocalize_pressed() -> void:
|
||||
$Main/Pseudolocalizer/Result.text = TranslationServer.pseudolocalize($Main/Pseudolocalizer/Key.text)
|
||||
|
||||
|
||||
func _on_doublevowels_toggled(button_pressed):
|
||||
ProjectSettings.set("internationalization/pseudolocalization/double_vowels", button_pressed)
|
||||
func _on_double_vowels_toggled(button_pressed: bool) -> void:
|
||||
ProjectSettings.set_setting("internationalization/pseudolocalization/double_vowels", button_pressed)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
|
||||
|
||||
func _on_expansion_ratio_text_changed():
|
||||
var ratio = ($Main/Pseudolocalization_options/exp_ratio/TextEdit.text).to_float()
|
||||
if ratio > 1:
|
||||
ratio = 1
|
||||
$Main/Pseudolocalization_options/exp_ratio/TextEdit.text = str(ratio)
|
||||
if ratio < 0:
|
||||
ratio = 0
|
||||
$Main/Pseudolocalization_options/exp_ratio/TextEdit.text = str(ratio)
|
||||
ProjectSettings.set("internationalization/pseudolocalization/expansion_ratio", ratio)
|
||||
func _on_expansion_ratio_value_changed(value: float) -> void:
|
||||
ProjectSettings.set_setting("internationalization/pseudolocalization/expansion_ratio", value)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
|
||||
|
||||
func _on_override_toggled(button_pressed):
|
||||
ProjectSettings.set("internationalization/pseudolocalization/override", button_pressed)
|
||||
func _on_override_toggled(button_pressed: bool) -> void:
|
||||
ProjectSettings.set_setting("internationalization/pseudolocalization/override", button_pressed)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
|
||||
|
||||
func _on_skipplaceholders_toggled(button_pressed):
|
||||
ProjectSettings.set("internationalization/pseudolocalization/skip_placeholders", button_pressed)
|
||||
func _on_skip_placeholders_toggled(button_pressed: bool) -> void:
|
||||
ProjectSettings.set_setting("internationalization/pseudolocalization/skip_placeholders", button_pressed)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
|
||||
@@ -101,10 +101,11 @@ size_flags_vertical = 1
|
||||
size_flags_stretch_ratio = 4.0
|
||||
text = "Expansion Ratio : "
|
||||
|
||||
[node name="TextEdit" type="LineEdit" parent="Main/Pseudolocalization_options/exp_ratio"]
|
||||
[node name="SpinBox" type="SpinBox" parent="Main/Pseudolocalization_options/exp_ratio"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
caret_blink = true
|
||||
max_value = 1.0
|
||||
step = 0.05
|
||||
|
||||
[node name="prefix" type="Control" parent="Main/Pseudolocalization_options"]
|
||||
layout_mode = 2
|
||||
@@ -200,11 +201,11 @@ layout_mode = 2
|
||||
|
||||
[connection signal="toggled" from="Main/Pseudolocalization_options/toggle" to="." method="_on_toggle_toggled"]
|
||||
[connection signal="toggled" from="Main/Pseudolocalization_options/accents" to="." method="_on_accents_toggled"]
|
||||
[connection signal="toggled" from="Main/Pseudolocalization_options/doublevowels" to="." method="_on_doublevowels_toggled"]
|
||||
[connection signal="toggled" from="Main/Pseudolocalization_options/fakebidi" to="." method="_on_fakebidi_toggled"]
|
||||
[connection signal="toggled" from="Main/Pseudolocalization_options/doublevowels" to="." method="_on_double_vowels_toggled"]
|
||||
[connection signal="toggled" from="Main/Pseudolocalization_options/fakebidi" to="." method="_on_fake_bidi_toggled"]
|
||||
[connection signal="toggled" from="Main/Pseudolocalization_options/override" to="." method="_on_override_toggled"]
|
||||
[connection signal="toggled" from="Main/Pseudolocalization_options/skipplaceholders" to="." method="_on_skipplaceholders_toggled"]
|
||||
[connection signal="text_changed" from="Main/Pseudolocalization_options/exp_ratio/TextEdit" to="." method="_on_expansion_ratio_text_changed"]
|
||||
[connection signal="toggled" from="Main/Pseudolocalization_options/skipplaceholders" to="." method="_on_skip_placeholders_toggled"]
|
||||
[connection signal="value_changed" from="Main/Pseudolocalization_options/exp_ratio/SpinBox" to="." method="_on_expansion_ratio_value_changed"]
|
||||
[connection signal="text_changed" from="Main/Pseudolocalization_options/prefix/TextEdit" to="." method="_on_prefix_changed"]
|
||||
[connection signal="text_changed" from="Main/Pseudolocalization_options/suffix/TextEdit" to="." method="_on_suffix_changed"]
|
||||
[connection signal="pressed" from="Main/Pseudolocalizer/Pseudolocalize" to="." method="_on_Pseudolocalize_pressed"]
|
||||
[connection signal="pressed" from="Main/Pseudolocalizer/Pseudolocalize" to="." method="_on_pseudolocalize_pressed"]
|
||||
|
||||
@@ -16,6 +16,15 @@ run/main_scene="res://Pseudolocalization.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
window/stretch/aspect="expand"
|
||||
|
||||
[internationalization]
|
||||
|
||||
pseudolocalization/use_pseudolocalization=true
|
||||
|
||||
@@ -18,6 +18,10 @@ run/main_scene="res://regex.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,47 +1,48 @@
|
||||
extends VBoxContainer
|
||||
|
||||
var regex = RegEx.new()
|
||||
var regex := RegEx.new()
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
%Text.set_text("They asked me \"What's going on \\\"in the manor\\\"?\"")
|
||||
update_expression(%Expression.text)
|
||||
|
||||
|
||||
func update_expression(text):
|
||||
func update_expression(text: String) -> void:
|
||||
regex.compile(text)
|
||||
update_text()
|
||||
|
||||
|
||||
func update_text():
|
||||
func update_text() -> void:
|
||||
for child in %List.get_children():
|
||||
child.queue_free()
|
||||
|
||||
if regex.is_valid():
|
||||
$HBoxContainer.modulate = Color.WHITE
|
||||
var matches = regex.search_all(%Text.get_text())
|
||||
var matches := regex.search_all(%Text.get_text())
|
||||
if matches.size() >= 1:
|
||||
# List all matches and their respective captures.
|
||||
var match_number = 0
|
||||
var match_number := 0
|
||||
for regex_match in matches:
|
||||
match_number += 1
|
||||
# `match` is a reserved GDScript keyword.
|
||||
var match_label = Label.new()
|
||||
var match_label := Label.new()
|
||||
match_label.text = "RegEx match #%d:" % match_number
|
||||
match_label.modulate = Color(0.6, 0.9, 1.0)
|
||||
%List.add_child(match_label)
|
||||
|
||||
var capture_number = 0
|
||||
var capture_number := 0
|
||||
for result in regex_match.get_strings():
|
||||
capture_number += 1
|
||||
var capture_label = Label.new()
|
||||
var capture_label := Label.new()
|
||||
capture_label.text = " Capture group #%d: %s" % [capture_number, result]
|
||||
%List.add_child(capture_label)
|
||||
else:
|
||||
$HBoxContainer.modulate = Color(1, 0.2, 0.1)
|
||||
var label = Label.new()
|
||||
var label := Label.new()
|
||||
label.text = "Error: Invalid regular expression. Check if the expression is correctly escaped and terminated."
|
||||
%List.add_child(label)
|
||||
|
||||
|
||||
func _on_help_meta_clicked(_meta):
|
||||
func _on_help_meta_clicked(_meta: Variant) -> void:
|
||||
# Workaround for clickable link doing nothing when clicked.
|
||||
OS.shell_open("https://regexr.com")
|
||||
|
||||
@@ -18,6 +18,10 @@ config/features=PackedStringArray("4.2")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
extends Control
|
||||
|
||||
func _on_RichTextLabel_meta_clicked(meta):
|
||||
var err = OS.shell_open(meta)
|
||||
func _on_RichTextLabel_meta_clicked(meta: Variant) -> void:
|
||||
var err := OS.shell_open(str(meta))
|
||||
if err == OK:
|
||||
print("Opened link '%s' successfully!" % meta)
|
||||
print("Opened link '%s' successfully!" % str(meta))
|
||||
else:
|
||||
print("Failed opening the link '%s'!" % meta)
|
||||
print("Failed opening the link '%s'!" % str(meta))
|
||||
|
||||
|
||||
func _on_pause_toggled(button_pressed):
|
||||
func _on_pause_toggled(button_pressed: bool) -> void:
|
||||
get_tree().paused = button_pressed
|
||||
|
||||
@@ -18,6 +18,10 @@ config/features=PackedStringArray("4.2")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_height=576
|
||||
|
||||
@@ -5,51 +5,51 @@ extends Control
|
||||
# This means that you should use `add_theme_stylebox_override("normal", ...)`
|
||||
# instead of `set("custom_styles/normal", ...)`.
|
||||
|
||||
@onready var label = $Panel/MarginContainer/VBoxContainer/Label
|
||||
@onready var button = $Panel/MarginContainer/VBoxContainer/Button
|
||||
@onready var button2 = $Panel/MarginContainer/VBoxContainer/Button2
|
||||
@onready var reset_all_button = $Panel/MarginContainer/VBoxContainer/ResetAllButton
|
||||
@onready var label: Label = $Panel/MarginContainer/VBoxContainer/Label
|
||||
@onready var button: Button = $Panel/MarginContainer/VBoxContainer/Button
|
||||
@onready var button2: Button = $Panel/MarginContainer/VBoxContainer/Button2
|
||||
@onready var reset_all_button: Button = $Panel/MarginContainer/VBoxContainer/ResetAllButton
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
# Focus the first button automatically for keyboard/controller-friendly navigation.
|
||||
button.grab_focus()
|
||||
|
||||
|
||||
func _on_button_pressed():
|
||||
func _on_button_pressed() -> void:
|
||||
# We have to modify the normal, hover and pressed styleboxes all at once
|
||||
# to get a correct appearance when the button is hovered or pressed.
|
||||
# We can't use a single StyleBox for all of them as these have different
|
||||
# background colors.
|
||||
var new_stylebox_normal = button.get_theme_stylebox("normal").duplicate()
|
||||
var new_stylebox_normal: StyleBoxFlat = button.get_theme_stylebox("normal").duplicate()
|
||||
new_stylebox_normal.border_color = Color(1, 1, 0)
|
||||
var new_stylebox_hover = button.get_theme_stylebox("hover").duplicate()
|
||||
var new_stylebox_hover: StyleBoxFlat = button.get_theme_stylebox("hover").duplicate()
|
||||
new_stylebox_hover.border_color = Color(1, 1, 0)
|
||||
var new_stylebox_pressed = button.get_theme_stylebox("pressed").duplicate()
|
||||
var new_stylebox_pressed: StyleBoxFlat = button.get_theme_stylebox("pressed").duplicate()
|
||||
new_stylebox_pressed.border_color = Color(1, 1, 0)
|
||||
|
||||
button.add_theme_stylebox_override("normal", new_stylebox_normal)
|
||||
button.add_theme_stylebox_override("hover", new_stylebox_hover)
|
||||
button.add_theme_stylebox_override("pressed", new_stylebox_pressed)
|
||||
|
||||
label.add_theme_color_override("font_color", Color(1, 1, 0.5))
|
||||
label.add_theme_color_override("font_color", Color(1, 1, 0.375))
|
||||
|
||||
|
||||
func _on_button2_pressed():
|
||||
var new_stylebox_normal = button2.get_theme_stylebox("normal").duplicate()
|
||||
func _on_button2_pressed() -> void:
|
||||
var new_stylebox_normal: StyleBoxFlat = button2.get_theme_stylebox("normal").duplicate()
|
||||
new_stylebox_normal.border_color = Color(0, 1, 0.5)
|
||||
var new_stylebox_hover = button2.get_theme_stylebox("hover").duplicate()
|
||||
var new_stylebox_hover: StyleBoxFlat = button2.get_theme_stylebox("hover").duplicate()
|
||||
new_stylebox_hover.border_color = Color(0, 1, 0.5)
|
||||
var new_stylebox_pressed = button2.get_theme_stylebox("pressed").duplicate()
|
||||
var new_stylebox_pressed: StyleBoxFlat = button2.get_theme_stylebox("pressed").duplicate()
|
||||
new_stylebox_pressed.border_color = Color(0, 1, 0.5)
|
||||
|
||||
button2.add_theme_stylebox_override("normal", new_stylebox_normal)
|
||||
button2.add_theme_stylebox_override("hover", new_stylebox_hover)
|
||||
button2.add_theme_stylebox_override("pressed", new_stylebox_pressed)
|
||||
|
||||
label.add_theme_color_override("font_color", Color(0.5, 1, 0.75))
|
||||
label.add_theme_color_override("font_color", Color(0.375, 1, 0.75))
|
||||
|
||||
|
||||
func _on_reset_all_button_pressed():
|
||||
func _on_reset_all_button_pressed() -> void:
|
||||
button.remove_theme_stylebox_override("normal")
|
||||
button.remove_theme_stylebox_override("hover")
|
||||
button.remove_theme_stylebox_override("pressed")
|
||||
|
||||
@@ -15,7 +15,6 @@ dest_files=["res://.godot/imported/DroidSans.ttf-f4f3e617929333a8a3b131725141d72
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
|
||||
@@ -15,7 +15,6 @@ dest_files=["res://.godot/imported/DroidSansArabic.ttf-e3dcbe0c4bc0f3f609a01ac9b
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
|
||||
@@ -15,7 +15,6 @@ dest_files=["res://.godot/imported/DroidSansFallback.ttf-fefd6276707493f1293e2a6
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
|
||||
@@ -15,7 +15,6 @@ dest_files=["res://.godot/imported/DroidSansHebrew.ttf-12677dba89ba8356d90dbb456
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
|
||||
@@ -15,7 +15,6 @@ dest_files=["res://.godot/imported/DroidSansJapanese.ttf-70e19a56601aacaaf5d6d30
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
|
||||
@@ -15,7 +15,6 @@ dest_files=["res://.godot/imported/DroidSansThai.ttf-136cea21d69e1da7eb0a603f8d9
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
|
||||
@@ -18,6 +18,10 @@ run/main_scene="res://translation_demo_csv.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
[gd_scene load_steps=6 format=3 uid="uid://du3apufm66p3x"]
|
||||
|
||||
[ext_resource type="Script" path="res://translation_csv.gd" id="1_o1a7r"]
|
||||
[ext_resource type="Texture2D" uid="uid://bk44e7bkr4w4l" path="res://images/speaker.webp" id="3_d0i3f"]
|
||||
[ext_resource type="Texture2D" uid="uid://bk44e7bkr4w4l" path="res://images/speaker.webp" id="3_usrmd"]
|
||||
[ext_resource type="FontFile" uid="uid://b0887xnwnkgju" path="res://fonts/droid_sans.tres" id="3_wf1ar"]
|
||||
[ext_resource type="Texture2D" uid="uid://cy06u7558clgu" path="res://images/flag_uk.webp" id="4_xn1dg"]
|
||||
[ext_resource type="AudioStream" uid="uid://ciept8j0x21to" path="res://audio/hello_en.wav" id="6_a303u"]
|
||||
[ext_resource type="Texture2D" uid="uid://cy06u7558clgu" path="res://images/flag_uk.webp" id="4_j5852"]
|
||||
[ext_resource type="AudioStream" uid="uid://ciept8j0x21to" path="res://audio/hello_en.wav" id="5_6qqpb"]
|
||||
|
||||
[node name="TranslationDemoCSV" type="Panel"]
|
||||
anchors_preset = 8
|
||||
@@ -115,7 +115,7 @@ offset_right = 475.0
|
||||
offset_bottom = 498.0
|
||||
theme_override_fonts/font = ExtResource("3_wf1ar")
|
||||
text = "KEY_PUSH"
|
||||
icon = ExtResource("3_d0i3f")
|
||||
icon = ExtResource("3_usrmd")
|
||||
|
||||
[node name="Flag" type="TextureRect" parent="."]
|
||||
layout_mode = 0
|
||||
@@ -123,10 +123,10 @@ offset_left = 85.0
|
||||
offset_top = 406.0
|
||||
offset_right = 213.0
|
||||
offset_bottom = 491.0
|
||||
texture = ExtResource("4_xn1dg")
|
||||
texture = ExtResource("4_j5852")
|
||||
|
||||
[node name="Audio" type="AudioStreamPlayer2D" parent="."]
|
||||
stream = ExtResource("6_a303u")
|
||||
stream = ExtResource("5_6qqpb")
|
||||
|
||||
[node name="GoToPOTranslationDemo" type="Button" parent="."]
|
||||
layout_mode = 0
|
||||
|
||||
@@ -74,7 +74,7 @@ The resouce remapping process is the same with CSV. The in-game text translation
|
||||
process is also the same – use keys to fetch the appropriate translation.
|
||||
|
||||
The main difference between PO files and CSV files is the way both of them store
|
||||
the translated data in their files. Have a look at the \"translations/po\"
|
||||
the translated data in their files. Have a look at the \"translations/po\"
|
||||
and \"translations/csv\" folders to see the files involved."
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="."]
|
||||
|
||||
@@ -7,6 +7,7 @@ extends Panel
|
||||
func _ready() -> void:
|
||||
_print_intro()
|
||||
|
||||
|
||||
func _on_english_pressed() -> void:
|
||||
TranslationServer.set_locale("en")
|
||||
_print_intro()
|
||||
|
||||
@@ -16,6 +16,10 @@ run/main_scene="res://ui_mirroring.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
extends Control
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
$Label.text = TranslationServer.get_locale()
|
||||
|
||||
func _on_Button_pressed():
|
||||
|
||||
func _on_Button_pressed() -> void:
|
||||
if TranslationServer.get_locale() != "ar":
|
||||
TranslationServer.set_locale("ar")
|
||||
else:
|
||||
TranslationServer.set_locale("en")
|
||||
|
||||
$Label.text = TranslationServer.get_locale()
|
||||
|
||||
@@ -83,9 +83,9 @@ self_modulate = Color(0.819608, 0.254902, 0.254902, 1)
|
||||
layout_direction = 1
|
||||
layout_mode = 0
|
||||
offset_left = 20.0
|
||||
offset_top = 90.0
|
||||
offset_top = 101.0
|
||||
offset_right = 170.0
|
||||
offset_bottom = 130.0
|
||||
offset_bottom = 141.0
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="PanelLTR/PanelLocale"]
|
||||
layout_mode = 0
|
||||
|
||||
Reference in New Issue
Block a user