mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-04 15:00:09 +01:00
Convert some 2D nodes to Control nodes in GDPaint and Pseudolocal demos
This commit is contained in:
15
gui/gd_paint/README.md
Normal file
15
gui/gd_paint/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# GD Paint
|
||||
|
||||
GD Paint is a simple image editor made using Godot and GDScript.
|
||||
It supports different types of "brushes": a basic pen/pencil
|
||||
and eraser, as well as a rectangle and a circle brush.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Vulkan Mobile
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/517
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
BIN
gui/gd_paint/icon.png
Normal file
BIN
gui/gd_paint/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 474 B |
34
gui/gd_paint/icon.png.import
Normal file
34
gui/gd_paint/icon.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://crrwsngk16wkg"
|
||||
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/bptc_ldr=0
|
||||
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
|
||||
239
gui/gd_paint/paint_control.gd
Normal file
239
gui/gd_paint/paint_control.gd
Normal file
@@ -0,0 +1,239 @@
|
||||
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 {
|
||||
PENCIL,
|
||||
ERASER,
|
||||
CIRCLE_SHAPE,
|
||||
RECTANGLE_SHAPE,
|
||||
}
|
||||
|
||||
enum BrushShapes {
|
||||
RECTANGLE,
|
||||
CIRCLE,
|
||||
}
|
||||
|
||||
# A list to hold all of the dictionaries that make up each brush.
|
||||
var brush_data_list = []
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
# 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;
|
||||
|
||||
# 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
|
||||
|
||||
@onready var drawing_area = $"../DrawingAreaBG"
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
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)
|
||||
is_mouse_in_drawing_area = drawing_area_rect.has_point(mouse_pos)
|
||||
|
||||
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
|
||||
# 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:
|
||||
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 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:
|
||||
undo_set = true
|
||||
undo_element_list_num = brush_data_list.size()
|
||||
# Add the brush object to draw_elements_array.
|
||||
add_brush(mouse_pos, brush_mode)
|
||||
|
||||
else:
|
||||
# We've finished our stroke, so we can set a new undo (if a new storke is made).
|
||||
undo_set = false
|
||||
|
||||
# If the mouse is inside the canvas.
|
||||
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:
|
||||
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
|
||||
|
||||
# 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():
|
||||
# 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.
|
||||
# This is so if we start out click outside the canvas (say chosing a color from the color picker)
|
||||
# and then move our mouse back into the canvas, it won't start painting.
|
||||
if Rect2(drawing_area.position, drawing_area.size).has_point(mouse_click_start_pos):
|
||||
# Make sure the current mouse position is inside the canvas.
|
||||
if is_mouse_in_drawing_area:
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func undo_stroke():
|
||||
# Only undo a stroke if we have one.
|
||||
if undo_element_list_num == UNDO_NONE:
|
||||
return
|
||||
|
||||
# If we are undoing a shape, then we can just remove the latest brush.
|
||||
if undo_element_list_num == UNDO_MODE_SHAPE:
|
||||
if brush_data_list.size() > 0:
|
||||
brush_data_list.remove(brush_data_list.size() - 1)
|
||||
|
||||
# Now that we've undone a shape, we cannot undo again until another stoke is added.
|
||||
undo_element_list_num = UNDO_NONE
|
||||
# NOTE: if we only had shape brushes, then we could remove the above line and could let the user
|
||||
# undo until we have a empty element list.
|
||||
|
||||
# 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
|
||||
# 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):
|
||||
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
|
||||
update()
|
||||
|
||||
|
||||
func add_brush(mouse_pos, type):
|
||||
# Make new brush dictionary that will hold all of the data we need for the 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.
|
||||
new_brush.brush_type = type
|
||||
new_brush.brush_pos = mouse_pos
|
||||
new_brush.brush_shape = brush_shape
|
||||
new_brush.brush_size = brush_size
|
||||
new_brush.brush_color = brush_color
|
||||
|
||||
# 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()
|
||||
|
||||
# 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:
|
||||
TL_pos.x = mouse_pos.x
|
||||
BR_pos.x = mouse_click_start_pos.x
|
||||
else:
|
||||
TL_pos.x = mouse_click_start_pos.x
|
||||
BR_pos.x = mouse_pos.x
|
||||
|
||||
# Figure out the top and bottom positions of the corners and assign them to the proper variable.
|
||||
if mouse_pos.y < mouse_click_start_pos.y:
|
||||
TL_pos.y = mouse_pos.y
|
||||
BR_pos.y = mouse_click_start_pos.y
|
||||
else:
|
||||
TL_pos.y = mouse_click_start_pos.y
|
||||
BR_pos.y = mouse_pos.y
|
||||
|
||||
# Assign the positions to the brush.
|
||||
new_brush.brush_pos = TL_pos
|
||||
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:
|
||||
# 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)
|
||||
# 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
|
||||
new_brush.brush_shape_circle_radius = center_pos.distance_to(Vector2(center_pos.x, mouse_pos.y))
|
||||
|
||||
# Add the brush and update/draw all of the brushes.
|
||||
brush_data_list.append(new_brush)
|
||||
update()
|
||||
|
||||
|
||||
func _draw():
|
||||
# Go through all of the brushes in brush_data_list.
|
||||
for brush in brush_data_list:
|
||||
match brush.brush_type:
|
||||
BrushModes.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))
|
||||
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:
|
||||
draw_circle(brush.brush_pos, brush.brush_size / 2, brush.brush_color)
|
||||
BrushModes.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))
|
||||
draw_rect(rect, bg_color)
|
||||
elif brush.brush_shape == BrushShapes.CIRCLE:
|
||||
draw_circle(brush.brush_pos, brush.brush_size / 2, bg_color)
|
||||
BrushModes.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)
|
||||
draw_rect(rect, brush.brush_color)
|
||||
BrushModes.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):
|
||||
# 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()
|
||||
# Crop the image so we only have canvas area.
|
||||
var cropped_image = img.get_rect(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)
|
||||
307
gui/gd_paint/paint_root.tscn
Normal file
307
gui/gd_paint/paint_root.tscn
Normal file
@@ -0,0 +1,307 @@
|
||||
[gd_scene load_steps=10 format=3 uid="uid://bhjmyer4wlwy2"]
|
||||
|
||||
[ext_resource type="Script" path="res://paint_control.gd" id="1"]
|
||||
[ext_resource type="Script" path="res://tools_panel.gd" id="2"]
|
||||
[ext_resource type="Texture2D" uid="uid://cdqq0m3rrlbva" path="res://paint_tools.png" id="3"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_4ksjc"]
|
||||
bg_color = Color(1, 1, 1, 1)
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_npkcn"]
|
||||
bg_color = Color(0.2, 0.2, 0.2, 1)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_v0gbg"]
|
||||
atlas = ExtResource( "3" )
|
||||
region = Rect2(0, 0, 16, 16)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_j7akv"]
|
||||
atlas = ExtResource( "3" )
|
||||
region = Rect2(16, 0, 16, 16)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_63q87"]
|
||||
atlas = ExtResource( "3" )
|
||||
region = Rect2(0, 16, 16, 16)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_t52fe"]
|
||||
atlas = ExtResource( "3" )
|
||||
region = Rect2(16, 16, 16, 16)
|
||||
|
||||
[node name="PaintRoot" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
||||
[node name="DrawingAreaBG" type="Panel" parent="."]
|
||||
anchor_left = 0.342
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -0.208008
|
||||
grow_horizontal = 2
|
||||
theme_override_styles/panel = SubResource( "StyleBoxFlat_4ksjc" )
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = true
|
||||
|
||||
[node name="PaintControl" type="Control" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource( "1" )
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ToolsPanel" type="Panel" parent="."]
|
||||
offset_right = 350.0
|
||||
offset_bottom = 600.0
|
||||
theme_override_styles/panel = SubResource( "StyleBoxFlat_npkcn" )
|
||||
script = ExtResource( "2" )
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = true
|
||||
|
||||
[node name="LabelTools" type="Label" parent="ToolsPanel"]
|
||||
offset_left = 20.0
|
||||
offset_top = 6.0
|
||||
offset_right = 330.0
|
||||
offset_bottom = 32.0
|
||||
text = "Selected tool: Pencil"
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ButtonToolPencil" type="Button" parent="ToolsPanel"]
|
||||
offset_left = 40.0
|
||||
offset_top = 30.0
|
||||
offset_right = 95.0
|
||||
offset_bottom = 85.0
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="ToolsPanel/ButtonToolPencil"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 5.0
|
||||
offset_top = 5.0
|
||||
offset_right = -5.0
|
||||
offset_bottom = -5.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = SubResource( "AtlasTexture_v0gbg" )
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ButtonToolEraser" type="Button" parent="ToolsPanel"]
|
||||
offset_left = 110.0
|
||||
offset_top = 30.0
|
||||
offset_right = 165.0
|
||||
offset_bottom = 85.0
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="TextureRect2" type="TextureRect" parent="ToolsPanel/ButtonToolEraser"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 5.0
|
||||
offset_top = 5.0
|
||||
offset_right = -5.0
|
||||
offset_bottom = -5.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = SubResource( "AtlasTexture_j7akv" )
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ButtonToolRectangle" type="Button" parent="ToolsPanel"]
|
||||
offset_left = 180.0
|
||||
offset_top = 30.0
|
||||
offset_right = 235.0
|
||||
offset_bottom = 85.0
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="ToolsPanel/ButtonToolRectangle"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 5.0
|
||||
offset_top = 5.0
|
||||
offset_right = -5.0
|
||||
offset_bottom = -5.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = SubResource( "AtlasTexture_63q87" )
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ButtonToolCircle" type="Button" parent="ToolsPanel"]
|
||||
offset_left = 250.0
|
||||
offset_top = 30.0
|
||||
offset_right = 305.0
|
||||
offset_bottom = 85.0
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="ToolsPanel/ButtonToolCircle"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 5.0
|
||||
offset_top = 5.0
|
||||
offset_right = -5.0
|
||||
offset_bottom = -5.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = SubResource( "AtlasTexture_t52fe" )
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="LabelBrushColor" type="Label" parent="ToolsPanel"]
|
||||
offset_left = 20.0
|
||||
offset_top = 91.0
|
||||
offset_right = 330.0
|
||||
offset_bottom = 117.0
|
||||
text = "Current color"
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ColorPickerBrush" type="ColorPickerButton" parent="ToolsPanel"]
|
||||
offset_left = 20.0
|
||||
offset_top = 115.0
|
||||
offset_right = 330.0
|
||||
offset_bottom = 155.0
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="BrushSettings" type="Control" parent="ToolsPanel"]
|
||||
offset_top = 200.0
|
||||
offset_right = 350.0
|
||||
offset_bottom = 375.0
|
||||
|
||||
[node name="LabelBrushSize" type="Label" parent="ToolsPanel/BrushSettings"]
|
||||
offset_left = 20.0
|
||||
offset_top = -37.0
|
||||
offset_right = 330.0
|
||||
offset_bottom = -11.0
|
||||
text = "Brush size: 32px"
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="HScrollBarBrushSize" type="HScrollBar" parent="ToolsPanel/BrushSettings"]
|
||||
offset_left = 20.0
|
||||
offset_top = -8.0
|
||||
offset_right = 330.0
|
||||
offset_bottom = 17.0
|
||||
min_value = 2.0
|
||||
step = 1.0
|
||||
value = 32.0
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="LabelBrushShape" type="Label" parent="ToolsPanel/BrushSettings"]
|
||||
offset_left = 20.0
|
||||
offset_top = 29.0
|
||||
offset_right = 330.0
|
||||
offset_bottom = 55.0
|
||||
text = "Brush shape: Circle"
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ButtonShapeBox" type="Button" parent="ToolsPanel/BrushSettings"]
|
||||
offset_left = 100.0
|
||||
offset_top = 59.0
|
||||
offset_right = 155.0
|
||||
offset_bottom = 114.0
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="ToolsPanel/BrushSettings/ButtonShapeBox"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 5.0
|
||||
offset_top = 5.0
|
||||
offset_right = -5.0
|
||||
offset_bottom = -5.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = SubResource( "AtlasTexture_63q87" )
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ButtonShapeCircle" type="Button" parent="ToolsPanel/BrushSettings"]
|
||||
offset_left = 190.0
|
||||
offset_top = 59.0
|
||||
offset_right = 245.0
|
||||
offset_bottom = 114.0
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="ToolsPanel/BrushSettings/ButtonShapeCircle"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 5.0
|
||||
offset_top = 5.0
|
||||
offset_right = -5.0
|
||||
offset_bottom = -5.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
texture = SubResource( "AtlasTexture_t52fe" )
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="LabelBackgroundColor" type="Label" parent="ToolsPanel"]
|
||||
offset_left = 20.0
|
||||
offset_top = 323.0
|
||||
offset_right = 330.0
|
||||
offset_bottom = 349.0
|
||||
text = "Background color"
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ColorPickerBackground" type="ColorPickerButton" parent="ToolsPanel"]
|
||||
offset_left = 20.0
|
||||
offset_top = 351.0
|
||||
offset_right = 330.0
|
||||
offset_bottom = 391.0
|
||||
color = Color(1, 1, 1, 1)
|
||||
edit_alpha = false
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="LabelStats" type="Label" parent="ToolsPanel"]
|
||||
modulate = Color(0.414062, 0.414062, 0.414062, 1)
|
||||
offset_left = 20.0
|
||||
offset_top = 463.0
|
||||
offset_right = 330.0
|
||||
offset_bottom = 489.0
|
||||
text = "Brush objects: 00000"
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ButtonUndo" type="Button" parent="ToolsPanel"]
|
||||
offset_left = 10.0
|
||||
offset_top = 415.0
|
||||
offset_right = 340.0
|
||||
offset_bottom = 450.0
|
||||
text = "Undo last stroke"
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ButtonSave" type="Button" parent="ToolsPanel"]
|
||||
offset_left = 10.0
|
||||
offset_top = 506.0
|
||||
offset_right = 340.0
|
||||
offset_bottom = 541.0
|
||||
text = "Save picture"
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="ButtonClear" type="Button" parent="ToolsPanel"]
|
||||
offset_left = 10.0
|
||||
offset_top = 550.0
|
||||
offset_right = 340.0
|
||||
offset_bottom = 585.0
|
||||
text = "Clear picture"
|
||||
metadata/_edit_layout_mode = 0
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="SaveFileDialog" type="FileDialog" parent="."]
|
||||
size = Vector2i(800, 300)
|
||||
min_size = Vector2i(800, 300)
|
||||
access = 2
|
||||
filters = PackedStringArray("*.png")
|
||||
show_hidden_files = true
|
||||
BIN
gui/gd_paint/paint_tools.png
Normal file
BIN
gui/gd_paint/paint_tools.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 273 B |
34
gui/gd_paint/paint_tools.png.import
Normal file
34
gui/gd_paint/paint_tools.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cdqq0m3rrlbva"
|
||||
path="res://.godot/imported/paint_tools.png-224b64b7ddb26189a369199f6d686b79.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://paint_tools.png"
|
||||
dest_files=["res://.godot/imported/paint_tools.png-224b64b7ddb26189a369199f6d686b79.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/bptc_ldr=0
|
||||
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
|
||||
32
gui/gd_paint/project.godot
Normal file
32
gui/gd_paint/project.godot
Normal file
@@ -0,0 +1,32 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[application]
|
||||
|
||||
config/name="GD Paint"
|
||||
config/description="GD Paint is a simple image editor made using Godot and GDScript.
|
||||
It supports different types of 'brushes': a basic pen/pencil
|
||||
and eraser, as well as a rectangle and a circle brush."
|
||||
run/main_scene="res://paint_root.tscn"
|
||||
config/icon="res://icon.png"
|
||||
config/features=PackedStringArray("4.0")
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/redundant_await=false
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="viewport"
|
||||
window/stretch/aspect="keep_height"
|
||||
|
||||
[rendering]
|
||||
|
||||
vulkan/rendering/back_end=1
|
||||
0
gui/gd_paint/screenshots/.gdignore
Normal file
0
gui/gd_paint/screenshots/.gdignore
Normal file
BIN
gui/gd_paint/screenshots/gdpaint.png
Normal file
BIN
gui/gd_paint/screenshots/gdpaint.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
112
gui/gd_paint/tools_panel.gd
Normal file
112
gui/gd_paint/tools_panel.gd
Normal file
@@ -0,0 +1,112 @@
|
||||
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 _parent = get_parent()
|
||||
@onready var save_dialog = _parent.get_node(^"SaveFileDialog")
|
||||
@onready var paint_control = _parent.get_node(^"PaintControl")
|
||||
|
||||
func _ready():
|
||||
# warning-ignore-all:return_value_discarded
|
||||
# Assign all of the needed signals for the oppersation buttons.
|
||||
$ButtonUndo.connect(&"pressed", self.button_pressed, ["undo_stroke"])
|
||||
$ButtonSave.connect(&"pressed", self.button_pressed, ["save_picture"])
|
||||
$ButtonClear.connect(&"pressed", self.button_pressed, ["clear_picture"])
|
||||
|
||||
# Assign all of the needed signals for the brush buttons.
|
||||
$ButtonToolPencil.connect(&"pressed", self.button_pressed, ["mode_pencil"])
|
||||
$ButtonToolEraser.connect(&"pressed", self.button_pressed, ["mode_eraser"])
|
||||
$ButtonToolRectangle.connect(&"pressed", self.button_pressed, ["mode_rectangle"])
|
||||
$ButtonToolCircle.connect(&"pressed", self.button_pressed, ["mode_circle"])
|
||||
$BrushSettings/ButtonShapeBox.connect(&"pressed", self.button_pressed, ["shape_rectangle"])
|
||||
$BrushSettings/ButtonShapeCircle.connect(&"pressed", self.button_pressed, ["shape_circle"])
|
||||
|
||||
# Assign all of the needed signals for the other brush settings (and ColorPickerBackground).
|
||||
$ColorPickerBrush.connect(&"color_changed", self.brush_color_changed)
|
||||
$ColorPickerBackground.connect(&"color_changed", self.background_color_changed)
|
||||
$BrushSettings/HScrollBarBrushSize.connect(&"value_changed", self.brush_size_changed)
|
||||
|
||||
# Assign the "file_selected" signal in SaveFileDialog.
|
||||
save_dialog.connect(&"file_selected", self.save_file_selected)
|
||||
|
||||
# Set physics process so we can update the status label.
|
||||
set_physics_process(true)
|
||||
|
||||
|
||||
func _physics_process(_delta):
|
||||
# Update the status label with the newest brush element count.
|
||||
label_stats.text = "Brush objects: " + str(paint_control.brush_data_list.size())
|
||||
|
||||
|
||||
func button_pressed(button_name):
|
||||
# If a brush mode button is pressed.
|
||||
var tool_name = null
|
||||
var shape_name = null
|
||||
|
||||
if button_name == "mode_pencil":
|
||||
paint_control.brush_mode = paint_control.BrushModes.PENCIL
|
||||
brush_settings.modulate = Color(1, 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)
|
||||
tool_name = "Eraser"
|
||||
elif button_name == "mode_rectangle":
|
||||
paint_control.brush_mode = paint_control.BrushModes.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
|
||||
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
|
||||
shape_name = "Rectangle"
|
||||
elif button_name == "shape_circle":
|
||||
paint_control.brush_shape = paint_control.BrushShapes.CIRCLE
|
||||
shape_name = "Circle";
|
||||
|
||||
# If a opperation button is pressed
|
||||
elif button_name == "clear_picture":
|
||||
paint_control.brush_data_list = []
|
||||
paint_control.update()
|
||||
elif button_name == "save_picture":
|
||||
save_dialog.popup_centered()
|
||||
elif button_name == "undo_stroke":
|
||||
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
|
||||
|
||||
|
||||
func brush_color_changed(color):
|
||||
# Change the brush color to whatever color the color picker is.
|
||||
paint_control.brush_color = color
|
||||
|
||||
|
||||
func background_color_changed(color):
|
||||
# Change the background color to whatever colorthe background color picker is.
|
||||
get_parent().get_node(^"DrawingAreaBG").modulate = color
|
||||
paint_control.bg_color = color
|
||||
# Because of how the eraser works we also need to redraw the paint control.
|
||||
paint_control.update()
|
||||
|
||||
|
||||
func brush_size_changed(value):
|
||||
# Change the size of the brush, and update the label to reflect the new value.
|
||||
paint_control.brush_size = ceil(value)
|
||||
label_brush_size.text = "Brush size: " + str(ceil(value)) + "px"
|
||||
|
||||
|
||||
func save_file_selected(path):
|
||||
# Call save_picture in paint_control, passing in the path we recieved from SaveFileDialog.
|
||||
paint_control.save_picture(path)
|
||||
@@ -1,78 +1,67 @@
|
||||
extends Node2D
|
||||
extends Control
|
||||
|
||||
func _ready():
|
||||
$HBoxContainer/Pseudolocalization_options/accents.button_pressed = ProjectSettings.get("internationalization/pseudolocalization/replace_with_accents")
|
||||
$HBoxContainer/Pseudolocalization_options/toggle.button_pressed = TranslationServer.pseudolocalization_enabled
|
||||
$HBoxContainer/Pseudolocalization_options/fakebidi.button_pressed = ProjectSettings.get("internationalization/pseudolocalization/fake_bidi")
|
||||
$HBoxContainer/Pseudolocalization_options/doublevowels.button_pressed = ProjectSettings.get("internationalization/pseudolocalization/double_vowels")
|
||||
$HBoxContainer/Pseudolocalization_options/override.button_pressed = ProjectSettings.get("internationalization/pseudolocalization/override")
|
||||
$HBoxContainer/Pseudolocalization_options/skipplaceholders.button_pressed = ProjectSettings.get("internationalization/pseudolocalization/skip_placeholders")
|
||||
$HBoxContainer/Pseudolocalization_options/prefix/TextEdit.text = ProjectSettings.get("internationalization/pseudolocalization/prefix")
|
||||
$HBoxContainer/Pseudolocalization_options/suffix/TextEdit.text = ProjectSettings.get("internationalization/pseudolocalization/suffix")
|
||||
$HBoxContainer/Pseudolocalization_options/exp_ratio/TextEdit.text = str(ProjectSettings.get("internationalization/pseudolocalization/expansion_ratio"))
|
||||
pass
|
||||
$Main/Pseudolocalization_options/accents.button_pressed = ProjectSettings.get("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"))
|
||||
|
||||
|
||||
func _on_accents_toggled(button_pressed):
|
||||
ProjectSettings.set("internationalization/pseudolocalization/replace_with_accents", button_pressed)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
pass
|
||||
|
||||
|
||||
func _on_toggle_toggled(button_pressed):
|
||||
TranslationServer.pseudolocalization_enabled = button_pressed
|
||||
pass
|
||||
|
||||
|
||||
func _on_fakebidi_toggled(button_pressed):
|
||||
ProjectSettings.set("internationalization/pseudolocalization/fake_bidi", button_pressed)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
pass
|
||||
|
||||
|
||||
func _on_prefix_changed():
|
||||
ProjectSettings.set("internationalization/pseudolocalization/prefix", $HBoxContainer/Pseudolocalization_options/prefix/TextEdit.text)
|
||||
ProjectSettings.set("internationalization/pseudolocalization/prefix", $Main/Pseudolocalization_options/prefix/TextEdit.text)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
pass
|
||||
|
||||
|
||||
func _on_suffix_changed():
|
||||
ProjectSettings.set("internationalization/pseudolocalization/suffix", $HBoxContainer/Pseudolocalization_options/suffix/TextEdit.text)
|
||||
ProjectSettings.set("internationalization/pseudolocalization/suffix", $Main/Pseudolocalization_options/suffix/TextEdit.text)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
pass
|
||||
|
||||
|
||||
func _on_Pseudolocalize_pressed():
|
||||
$HBoxContainer/Pseudolocalizer/Result.text = TranslationServer.pseudolocalize($HBoxContainer/Pseudolocalizer/Key.text)
|
||||
pass
|
||||
$Main/Pseudolocalizer/Result.text = TranslationServer.pseudolocalize($Main/Pseudolocalizer/Key.text)
|
||||
|
||||
|
||||
func _on_doublevowels_toggled(button_pressed):
|
||||
ProjectSettings.set("internationalization/pseudolocalization/double_vowels", button_pressed)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
pass
|
||||
|
||||
|
||||
func _on_expansion_ratio_text_changed():
|
||||
float()
|
||||
var ratio = ($HBoxContainer/Pseudolocalization_options/exp_ratio/TextEdit.text).to_float()
|
||||
var ratio = ($Main/Pseudolocalization_options/exp_ratio/TextEdit.text).to_float()
|
||||
if ratio > 1:
|
||||
ratio = 1
|
||||
$HBoxContainer/Pseudolocalization_options/exp_ratio/TextEdit.text = str(ratio)
|
||||
$Main/Pseudolocalization_options/exp_ratio/TextEdit.text = str(ratio)
|
||||
if ratio < 0:
|
||||
ratio = 0
|
||||
$HBoxContainer/Pseudolocalization_options/exp_ratio/TextEdit.text = str(ratio)
|
||||
$Main/Pseudolocalization_options/exp_ratio/TextEdit.text = str(ratio)
|
||||
ProjectSettings.set("internationalization/pseudolocalization/expansion_ratio", ratio)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
pass
|
||||
|
||||
|
||||
func _on_override_toggled(button_pressed):
|
||||
ProjectSettings.set("internationalization/pseudolocalization/override", button_pressed)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
pass
|
||||
|
||||
|
||||
func _on_skipplaceholders_toggled(button_pressed):
|
||||
ProjectSettings.set("internationalization/pseudolocalization/skip_placeholders", button_pressed)
|
||||
TranslationServer.reload_pseudolocalization()
|
||||
pass
|
||||
|
||||
@@ -3,88 +3,110 @@
|
||||
[ext_resource type="Texture2D" uid="uid://ddpix5j1t4swg" path="res://icon.png" id="1"]
|
||||
[ext_resource type="Script" path="res://Pseudolocalization.gd" id="2"]
|
||||
|
||||
[node name="Pseudolocalization" type="Node2D"]
|
||||
[node name="Pseudolocalization" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
script = ExtResource( "2" )
|
||||
|
||||
[node name="Title" type="Label" parent="."]
|
||||
offset_left = 140.0
|
||||
offset_top = 19.0
|
||||
offset_right = 1024.0
|
||||
offset_bottom = 114.0
|
||||
[node name="Title" type="HBoxContainer" parent="."]
|
||||
anchor_right = 1.0
|
||||
offset_left = 20.0
|
||||
offset_top = 30.0
|
||||
offset_right = -20.0
|
||||
offset_bottom = 130.0
|
||||
grow_horizontal = 2
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="Title"]
|
||||
minimum_size = Vector2(110, 0)
|
||||
offset_right = 110.0
|
||||
offset_bottom = 100.0
|
||||
texture = ExtResource( "1" )
|
||||
ignore_texture_size = true
|
||||
stretch_mode = 4
|
||||
|
||||
[node name="Label" type="Label" parent="Title"]
|
||||
offset_left = 114.0
|
||||
offset_top = 27.0
|
||||
offset_right = 984.0
|
||||
offset_bottom = 72.0
|
||||
size_flags_horizontal = 3
|
||||
theme_override_font_sizes/font_size = 30
|
||||
text = "Pseudolocalization Demo"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="icon" type="Sprite2D" parent="Title"]
|
||||
position = Vector2(-66, 47)
|
||||
scale = Vector2(0.78563, 0.78563)
|
||||
texture = ExtResource( "1" )
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||
offset_left = 19.0
|
||||
offset_top = 142.0
|
||||
offset_right = 1031.0
|
||||
offset_bottom = 600.0
|
||||
[node name="Main" type="HBoxContainer" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 20.0
|
||||
offset_top = 150.0
|
||||
offset_right = -20.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 20
|
||||
metadata/_edit_layout_mode = 1
|
||||
metadata/_edit_use_custom_anchors = false
|
||||
|
||||
[node name="Pseudolocalization_options" type="VBoxContainer" parent="HBoxContainer"]
|
||||
[node name="Pseudolocalization_options" type="VBoxContainer" parent="Main"]
|
||||
layout_direction = 2
|
||||
offset_right = 502.0
|
||||
offset_bottom = 458.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 450.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="toggle" type="CheckButton" parent="HBoxContainer/Pseudolocalization_options"]
|
||||
offset_right = 502.0
|
||||
[node name="toggle" type="CheckButton" parent="Main/Pseudolocalization_options"]
|
||||
offset_right = 472.0
|
||||
offset_bottom = 31.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Toggle Pseudolocalization"
|
||||
|
||||
[node name="accents" type="CheckButton" parent="HBoxContainer/Pseudolocalization_options"]
|
||||
[node name="accents" type="CheckButton" parent="Main/Pseudolocalization_options"]
|
||||
offset_top = 35.0
|
||||
offset_right = 502.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 66.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Toggle Accents"
|
||||
|
||||
[node name="doublevowels" type="CheckButton" parent="HBoxContainer/Pseudolocalization_options"]
|
||||
[node name="doublevowels" type="CheckButton" parent="Main/Pseudolocalization_options"]
|
||||
offset_top = 70.0
|
||||
offset_right = 502.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 101.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Toggle Double Vowels"
|
||||
|
||||
[node name="fakebidi" type="CheckButton" parent="HBoxContainer/Pseudolocalization_options"]
|
||||
[node name="fakebidi" type="CheckButton" parent="Main/Pseudolocalization_options"]
|
||||
offset_top = 105.0
|
||||
offset_right = 502.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 136.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Toggle Fake Bidi"
|
||||
|
||||
[node name="override" type="CheckButton" parent="HBoxContainer/Pseudolocalization_options"]
|
||||
[node name="override" type="CheckButton" parent="Main/Pseudolocalization_options"]
|
||||
offset_top = 140.0
|
||||
offset_right = 502.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 171.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Toggle Override"
|
||||
|
||||
[node name="skipplaceholders" type="CheckButton" parent="HBoxContainer/Pseudolocalization_options"]
|
||||
[node name="skipplaceholders" type="CheckButton" parent="Main/Pseudolocalization_options"]
|
||||
offset_top = 175.0
|
||||
offset_right = 502.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 206.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Skip Placeholders"
|
||||
|
||||
[node name="exp_ratio" type="HBoxContainer" parent="HBoxContainer/Pseudolocalization_options"]
|
||||
[node name="exp_ratio" type="HBoxContainer" parent="Main/Pseudolocalization_options"]
|
||||
offset_top = 210.0
|
||||
offset_right = 502.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 241.0
|
||||
size_flags_vertical = 0
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="HBoxContainer/Pseudolocalization_options/exp_ratio"]
|
||||
[node name="MarginContainer" type="MarginContainer" parent="Main/Pseudolocalization_options/exp_ratio"]
|
||||
offset_bottom = 31.0
|
||||
|
||||
[node name="Label" type="Label" parent="HBoxContainer/Pseudolocalization_options/exp_ratio"]
|
||||
[node name="Label" type="Label" parent="Main/Pseudolocalization_options/exp_ratio"]
|
||||
offset_left = 4.0
|
||||
offset_right = 141.0
|
||||
offset_bottom = 31.0
|
||||
@@ -93,128 +115,134 @@ size_flags_vertical = 1
|
||||
size_flags_stretch_ratio = 4.0
|
||||
text = "Expansion Ratio : "
|
||||
|
||||
[node name="TextEdit" type="LineEdit" parent="HBoxContainer/Pseudolocalization_options/exp_ratio"]
|
||||
offset_left = 403.0
|
||||
offset_right = 502.0
|
||||
[node name="TextEdit" type="LineEdit" parent="Main/Pseudolocalization_options/exp_ratio"]
|
||||
offset_left = 379.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 31.0
|
||||
size_flags_horizontal = 3
|
||||
caret_blink = true
|
||||
caret_blink_speed = 0.5
|
||||
|
||||
[node name="prefix" type="Control" parent="HBoxContainer/Pseudolocalization_options"]
|
||||
[node name="prefix" type="Control" parent="Main/Pseudolocalization_options"]
|
||||
offset_top = 245.0
|
||||
offset_right = 502.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 245.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="TextEdit" type="LineEdit" parent="HBoxContainer/Pseudolocalization_options/prefix"]
|
||||
[node name="TextEdit" type="LineEdit" parent="Main/Pseudolocalization_options/prefix"]
|
||||
offset_left = 5.0
|
||||
offset_top = 32.8613
|
||||
offset_right = 385.0
|
||||
offset_bottom = 62.8613
|
||||
size_flags_horizontal = 3
|
||||
caret_blink = true
|
||||
caret_blink_speed = 0.5
|
||||
|
||||
[node name="Label" type="Label" parent="HBoxContainer/Pseudolocalization_options/prefix"]
|
||||
[node name="Label" type="Label" parent="Main/Pseudolocalization_options/prefix"]
|
||||
offset_left = 6.0
|
||||
offset_top = 2.86133
|
||||
offset_right = 297.0
|
||||
offset_bottom = 28.8613
|
||||
text = "Pseudolocalization Prefix :"
|
||||
|
||||
[node name="suffix" type="Control" parent="HBoxContainer/Pseudolocalization_options"]
|
||||
[node name="suffix" type="Control" parent="Main/Pseudolocalization_options"]
|
||||
offset_top = 249.0
|
||||
offset_right = 502.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 249.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="TextEdit" type="LineEdit" parent="HBoxContainer/Pseudolocalization_options/suffix"]
|
||||
[node name="TextEdit" type="LineEdit" parent="Main/Pseudolocalization_options/suffix"]
|
||||
offset_left = 3.811
|
||||
offset_top = 106.592
|
||||
offset_right = 383.811
|
||||
offset_bottom = 136.592
|
||||
size_flags_horizontal = 3
|
||||
caret_blink = true
|
||||
caret_blink_speed = 0.5
|
||||
|
||||
[node name="Label" type="Label" parent="HBoxContainer/Pseudolocalization_options/suffix"]
|
||||
[node name="Label" type="Label" parent="Main/Pseudolocalization_options/suffix"]
|
||||
offset_left = 6.0
|
||||
offset_top = 76.5923
|
||||
offset_right = 297.0
|
||||
offset_bottom = 102.592
|
||||
text = "Pseudolocalization Suffix :"
|
||||
|
||||
[node name="Pseudolocalizer" type="VBoxContainer" parent="HBoxContainer"]
|
||||
offset_left = 506.0
|
||||
offset_right = 1008.0
|
||||
offset_bottom = 458.0
|
||||
[node name="Pseudolocalizer" type="VBoxContainer" parent="Main"]
|
||||
offset_left = 492.0
|
||||
offset_right = 964.0
|
||||
offset_bottom = 450.0
|
||||
grow_horizontal = 0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Label" type="Label" parent="HBoxContainer/Pseudolocalizer"]
|
||||
offset_right = 502.0
|
||||
[node name="Label" type="Label" parent="Main/Pseudolocalizer"]
|
||||
offset_right = 472.0
|
||||
offset_bottom = 26.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 5
|
||||
text = "Pseudolocalization key :"
|
||||
|
||||
[node name="Key" type="TextEdit" parent="HBoxContainer/Pseudolocalizer"]
|
||||
[node name="Key" type="TextEdit" parent="Main/Pseudolocalizer"]
|
||||
offset_top = 30.0
|
||||
offset_right = 502.0
|
||||
offset_bottom = 145.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 143.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "The quick brown fox jumped over the lazy dog."
|
||||
|
||||
[node name="margin" type="MarginContainer" parent="HBoxContainer/Pseudolocalizer"]
|
||||
offset_top = 149.0
|
||||
offset_bottom = 149.0
|
||||
[node name="margin" type="MarginContainer" parent="Main/Pseudolocalizer"]
|
||||
offset_top = 147.0
|
||||
offset_bottom = 147.0
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 0
|
||||
|
||||
[node name="Pseudolocalize" type="Button" parent="HBoxContainer/Pseudolocalizer"]
|
||||
offset_left = 189.0
|
||||
offset_top = 153.0
|
||||
offset_right = 312.0
|
||||
offset_bottom = 184.0
|
||||
[node name="Pseudolocalize" type="Button" parent="Main/Pseudolocalizer"]
|
||||
offset_left = 174.0
|
||||
offset_top = 151.0
|
||||
offset_right = 297.0
|
||||
offset_bottom = 182.0
|
||||
size_flags_horizontal = 6
|
||||
text = "Pseudolocalize"
|
||||
|
||||
[node name="margin2" type="MarginContainer" parent="HBoxContainer/Pseudolocalizer"]
|
||||
offset_top = 188.0
|
||||
offset_bottom = 188.0
|
||||
[node name="margin2" type="MarginContainer" parent="Main/Pseudolocalizer"]
|
||||
offset_top = 186.0
|
||||
offset_bottom = 186.0
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 0
|
||||
|
||||
[node name="Label2" type="Label" parent="HBoxContainer/Pseudolocalizer"]
|
||||
offset_top = 192.0
|
||||
offset_right = 502.0
|
||||
offset_bottom = 218.0
|
||||
[node name="Label2" type="Label" parent="Main/Pseudolocalizer"]
|
||||
offset_top = 190.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 216.0
|
||||
text = "Pseudolocalization result :"
|
||||
|
||||
[node name="Result" type="TextEdit" parent="HBoxContainer/Pseudolocalizer"]
|
||||
offset_top = 222.0
|
||||
offset_right = 502.0
|
||||
offset_bottom = 338.0
|
||||
[node name="Result" type="TextEdit" parent="Main/Pseudolocalizer"]
|
||||
offset_top = 220.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 333.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="A2Z" type="Label" parent="HBoxContainer/Pseudolocalizer"]
|
||||
offset_top = 342.0
|
||||
offset_right = 502.0
|
||||
offset_bottom = 458.0
|
||||
[node name="A2Z" type="Label" parent="Main/Pseudolocalizer"]
|
||||
offset_top = 337.0
|
||||
offset_right = 472.0
|
||||
offset_bottom = 450.0
|
||||
size_flags_vertical = 7
|
||||
text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="HBoxContainer"]
|
||||
offset_left = 1012.0
|
||||
offset_right = 1012.0
|
||||
offset_bottom = 458.0
|
||||
[node name="MarginContainer" type="MarginContainer" parent="Main"]
|
||||
offset_left = 984.0
|
||||
offset_right = 984.0
|
||||
offset_bottom = 450.0
|
||||
|
||||
[connection signal="toggled" from="HBoxContainer/Pseudolocalization_options/toggle" to="." method="_on_toggle_toggled"]
|
||||
[connection signal="toggled" from="HBoxContainer/Pseudolocalization_options/accents" to="." method="_on_accents_toggled"]
|
||||
[connection signal="toggled" from="HBoxContainer/Pseudolocalization_options/doublevowels" to="." method="_on_doublevowels_toggled"]
|
||||
[connection signal="toggled" from="HBoxContainer/Pseudolocalization_options/fakebidi" to="." method="_on_fakebidi_toggled"]
|
||||
[connection signal="toggled" from="HBoxContainer/Pseudolocalization_options/override" to="." method="_on_override_toggled"]
|
||||
[connection signal="toggled" from="HBoxContainer/Pseudolocalization_options/skipplaceholders" to="." method="_on_skipplaceholders_toggled"]
|
||||
[connection signal="text_changed" from="HBoxContainer/Pseudolocalization_options/exp_ratio/TextEdit" to="." method="_on_expansion_ratio_text_changed"]
|
||||
[connection signal="text_changed" from="HBoxContainer/Pseudolocalization_options/prefix/TextEdit" to="." method="_on_prefix_changed"]
|
||||
[connection signal="text_changed" from="HBoxContainer/Pseudolocalization_options/suffix/TextEdit" to="." method="_on_suffix_changed"]
|
||||
[connection signal="pressed" from="HBoxContainer/Pseudolocalizer/Pseudolocalize" to="." method="_on_Pseudolocalize_pressed"]
|
||||
[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/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="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"]
|
||||
|
||||
Reference in New Issue
Block a user