mirror of
https://github.com/litruv/PNGTuber-Plus.git
synced 2026-07-24 02:26:02 +10:00
adding mask options
This commit is contained in:
33
.vscode/launch.json
vendored
Normal file
33
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch PNGTuber Plus (Godot)",
|
||||
"type": "godot",
|
||||
"request": "launch",
|
||||
"port": 6007,
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"name": "Attach to Running Godot",
|
||||
"type": "godot",
|
||||
"request": "attach",
|
||||
"port": 6007,
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"name": "Launch Built Executable",
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"script": "if (Test-Path '${workspaceFolder}\\build\\windows\\PNGTuber-Plus.exe') { Start-Process '${workspaceFolder}\\build\\windows\\PNGTuber-Plus.exe' } else { Write-Host 'Executable not found. Build the project first.' }",
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "Build and Launch",
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"script": ".\\build-windows.bat; if (Test-Path '.\\build\\windows\\PNGTuber-Plus.exe') { Start-Process '.\\build\\windows\\PNGTuber-Plus.exe' }",
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
121
.vscode/tasks.json
vendored
Normal file
121
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Build Windows (Local)",
|
||||
"type": "shell",
|
||||
"command": ".\\build-windows.bat",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"args": [],
|
||||
"isBackground": false,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Build Windows executable using local build script with template management"
|
||||
},
|
||||
{
|
||||
"label": "Build Windows (CI)",
|
||||
"type": "shell",
|
||||
"command": ".\\build-windows-ci.bat",
|
||||
"group": "build",
|
||||
"args": [],
|
||||
"isBackground": false,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Build Windows executable using CI build script (no template download)"
|
||||
},
|
||||
{
|
||||
"label": "Export Windows (Godot Direct)",
|
||||
"type": "shell",
|
||||
"command": "D:\\Godot\\Godot_v4.4.1-stable_win64.exe",
|
||||
"group": "build",
|
||||
"args": [
|
||||
"--headless",
|
||||
"--export-release",
|
||||
"\"Windows Desktop\"",
|
||||
"\"build/windows/PNGTuber-Plus.exe\""
|
||||
],
|
||||
"isBackground": false,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Export Windows build directly using Godot (requires templates already installed)"
|
||||
},
|
||||
{
|
||||
"label": "Clean Build Directory",
|
||||
"type": "shell",
|
||||
"command": "if (Test-Path 'build') { Remove-Item -Recurse -Force 'build' }; Write-Host 'Build directory cleaned'",
|
||||
"group": "build",
|
||||
"args": [],
|
||||
"isBackground": false,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Clean the build output directory"
|
||||
},
|
||||
{
|
||||
"label": "Open Build Directory",
|
||||
"type": "shell",
|
||||
"command": "if (Test-Path 'build\\windows') { explorer 'build\\windows' } else { Write-Host 'Build directory does not exist. Run a build first.' }",
|
||||
"group": "build",
|
||||
"args": [],
|
||||
"isBackground": false,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Open the Windows build output directory in Explorer"
|
||||
},
|
||||
{
|
||||
"label": "Run Built Executable",
|
||||
"type": "shell",
|
||||
"command": "if (Test-Path 'build\\windows\\PNGTuber-Plus.exe') { Start-Process 'build\\windows\\PNGTuber-Plus.exe' } else { Write-Host 'Executable not found. Build the project first.' }",
|
||||
"group": "test",
|
||||
"args": [],
|
||||
"isBackground": true,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Run the built Windows executable for testing"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -47,4 +47,3 @@ if %ERRORLEVEL% EQU 0 (
|
||||
echo.
|
||||
)
|
||||
|
||||
pause
|
||||
|
||||
@@ -30,6 +30,7 @@ var editMode = true
|
||||
@onready var spriteObject = preload("res://ui_scenes/selectedSprite/spriteObject.tscn")
|
||||
|
||||
var saveLoaded = false
|
||||
var isSelectingMask = false
|
||||
|
||||
#Motion
|
||||
var yVel = 0
|
||||
@@ -62,7 +63,9 @@ func _ready():
|
||||
|
||||
Global.connect("startSpeaking",onSpeak)
|
||||
|
||||
ElgatoStreamDeck.on_key_down.connect(changeCostumeStreamDeck)
|
||||
var streamdeck_node = get_node_or_null("/root/ElgatoStreamDeck")
|
||||
if streamdeck_node:
|
||||
streamdeck_node.on_key_down.connect(changeCostumeStreamDeck)
|
||||
|
||||
if Saving.settings["newUser"]:
|
||||
_on_load_dialog_file_selected("default")
|
||||
@@ -153,6 +156,9 @@ func _process(delta):
|
||||
followShadow()
|
||||
|
||||
func followShadow():
|
||||
shadow.visible = false # Disabled drop shadow
|
||||
return
|
||||
|
||||
shadow.visible = is_instance_valid(Global.heldSprite)
|
||||
if !shadow.visible:
|
||||
return
|
||||
@@ -171,6 +177,9 @@ func isFileSystemOpen():
|
||||
if obj.visible:
|
||||
if obj == replaceDialog:
|
||||
return true
|
||||
# Don't clear held sprite when selecting mask
|
||||
if obj == fileDialog and isSelectingMask:
|
||||
return true
|
||||
Global.heldSprite = null
|
||||
return true
|
||||
return false
|
||||
@@ -288,8 +297,21 @@ func _on_add_button_pressed():
|
||||
|
||||
#Runs when selecting image in File Dialog
|
||||
func _on_file_dialog_file_selected(path):
|
||||
if isSelectingMask:
|
||||
# Handle mask selection
|
||||
if Global.heldSprite != null:
|
||||
Global.heldSprite.setMaskTexture(path)
|
||||
Global.spriteEdit.updateMaskDisplay(path)
|
||||
isSelectingMask = false
|
||||
else:
|
||||
# Handle normal sprite addition
|
||||
add_image(path)
|
||||
|
||||
#Opens File Dialog for mask selection
|
||||
func openMaskSelection():
|
||||
isSelectingMask = true
|
||||
fileDialog.visible = true
|
||||
|
||||
func _on_save_button_pressed():
|
||||
$SaveDialog.visible = true
|
||||
|
||||
@@ -363,6 +385,14 @@ func _on_load_dialog_file_selected(path):
|
||||
if data[item].has("toggle"):
|
||||
sprite.toggle = data[item]["toggle"]
|
||||
|
||||
# Load mask properties
|
||||
if data[item].has("mask_texture_path"):
|
||||
sprite.mask_texture_path = data[item]["mask_texture_path"]
|
||||
if data[item].has("use_mask"):
|
||||
sprite.use_mask = data[item]["use_mask"]
|
||||
if data[item].has("mask_opacity"):
|
||||
sprite.mask_opacity = data[item]["mask_opacity"]
|
||||
|
||||
origin.add_child(sprite)
|
||||
sprite.position = str_to_var(data[item]["pos"])
|
||||
|
||||
@@ -424,6 +454,11 @@ func _on_save_dialog_file_selected(path):
|
||||
|
||||
data[id]["toggle"] = child.toggle
|
||||
|
||||
# Save mask properties
|
||||
data[id]["mask_texture_path"] = child.mask_texture_path
|
||||
data[id]["use_mask"] = child.use_mask
|
||||
data[id]["mask_opacity"] = child.mask_opacity
|
||||
|
||||
id += 1
|
||||
|
||||
Saving.settings["lastAvatar"] = path
|
||||
@@ -547,7 +582,7 @@ func moveSpriteMenu(delta):
|
||||
|
||||
var size = get_viewport().get_visible_rect().size
|
||||
|
||||
var windowLength = 1400
|
||||
var windowLength = 1800
|
||||
|
||||
$ViewerArrows/Arrows.position.y = size.y - 25
|
||||
|
||||
@@ -604,7 +639,7 @@ func _on_background_input_capture_bg_key_pressed(node, keys_pressed):
|
||||
var has_ctrl = keys_pressed.has(KEY_CTRL) and keys_pressed[KEY_CTRL]
|
||||
var has_shift = keys_pressed.has(KEY_SHIFT) and keys_pressed[KEY_SHIFT]
|
||||
var has_alt = keys_pressed.has(KEY_ALT) and keys_pressed[KEY_ALT]
|
||||
var has_meta = keys_pressed.has(KEY_META) and keys_pressed[KEY_META] # Command key on macOS
|
||||
var meta_pressed = keys_pressed.has(KEY_META) and keys_pressed[KEY_META] # Command key on macOS
|
||||
|
||||
# Build modifier prefix once
|
||||
if has_ctrl:
|
||||
@@ -613,7 +648,7 @@ func _on_background_input_capture_bg_key_pressed(node, keys_pressed):
|
||||
modifiers.append("Shift")
|
||||
if has_alt:
|
||||
modifiers.append("Alt")
|
||||
if has_meta:
|
||||
if meta_pressed:
|
||||
modifiers.append("Cmd") # Command key on macOS
|
||||
|
||||
var modifier_prefix = ""
|
||||
|
||||
@@ -14744,5 +14744,5 @@ z_index = -4096
|
||||
[connection signal="visibility_changed" from="ReplaceDialog" to="." method="_on_replace_dialog_visibility_changed"]
|
||||
[connection signal="file_selected" from="SaveDialog" to="." method="_on_save_dialog_file_selected"]
|
||||
[connection signal="file_selected" from="LoadDialog" to="." method="_on_load_dialog_file_selected"]
|
||||
[connection signal="bg_key_pressed" from="BackgroundInputCapture" to="." method="bgInputSprite"]
|
||||
[connection signal="bg_key_pressed" from="BackgroundInputCapture" to="." method="_on_background_input_capture_bg_key_pressed"]
|
||||
[connection signal="bg_key_pressed" from="BackgroundInputCapture" to="." method="bgInputSprite"]
|
||||
|
||||
@@ -147,4 +147,6 @@ textures/canvas_textures/default_texture_filter=0
|
||||
textures/canvas_textures/default_texture_repeat=1
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
shading/overrides/force_vertex_shading=true
|
||||
shading/overrides/force_lambert_over_burley=true
|
||||
environment/defaults/default_clear_color=Color(0.376471, 0.376471, 0.376471, 1)
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D noise_texture:repeat_enable;
|
||||
uniform float distortion_strengh: hint_range(0, 0.1) = 1.0;
|
||||
uniform sampler2D noise_texture: source_color, repeat_enable;
|
||||
uniform float distortion_strengh: hint_range(0, 0.1) = 0.01;
|
||||
uniform float speed: hint_range(0.1, 10) = 1.0;
|
||||
uniform bool use_noise_texture: hint_default_true = false;
|
||||
|
||||
void fragment() {
|
||||
vec2 uv_offset = vec2(0.0);
|
||||
|
||||
if (use_noise_texture) {
|
||||
vec4 noise_pixel = texture(noise_texture, UV + floor(TIME * speed) / 3.0);
|
||||
vec2 uv_offset = (noise_pixel.rg * 2.0 - 1.0) * distortion_strengh;
|
||||
uv_offset = (noise_pixel.rg * 2.0 - 1.0) * distortion_strengh;
|
||||
} else {
|
||||
// Fallback procedural noise when no texture is provided
|
||||
float noise = sin(UV.x * 20.0 + TIME * speed) * cos(UV.y * 20.0 + TIME * speed * 0.7);
|
||||
uv_offset = vec2(noise) * distortion_strengh;
|
||||
}
|
||||
|
||||
COLOR = texture(TEXTURE, UV + uv_offset);
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
uid://b342og0l0k1p
|
||||
uid://4a1uhohwy43l
|
||||
|
||||
23
ui_scenes/selectedSprite/mask.gdshader
Normal file
23
ui_scenes/selectedSprite/mask.gdshader
Normal file
@@ -0,0 +1,23 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D mask_texture : source_color;
|
||||
uniform bool use_mask = false;
|
||||
uniform float mask_opacity : hint_range(0.0, 1.0) = 1.0;
|
||||
|
||||
void fragment() {
|
||||
// Get the original sprite color
|
||||
vec4 sprite_color = texture(TEXTURE, UV);
|
||||
|
||||
if (use_mask) {
|
||||
// Sample the mask texture
|
||||
vec4 mask_sample = texture(mask_texture, UV);
|
||||
|
||||
// Use the mask's alpha channel to determine visibility
|
||||
float mask_alpha = mask_sample.a * mask_opacity;
|
||||
|
||||
// Apply the mask by multiplying the sprite's alpha with the mask alpha
|
||||
sprite_color.a *= mask_alpha;
|
||||
}
|
||||
|
||||
COLOR = sprite_color;
|
||||
}
|
||||
1
ui_scenes/selectedSprite/mask.gdshader.uid
Normal file
1
ui_scenes/selectedSprite/mask.gdshader.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://btd72itp0cy6b
|
||||
@@ -1,17 +1,8 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform float speed;
|
||||
|
||||
uniform sampler2D backImg: repeat_enable;
|
||||
|
||||
uniform sampler2D palette;
|
||||
uniform float palette_speed = 0.1;
|
||||
uniform vec4 outline_color : source_color = vec4(1.0, 0.0, 0.0, 0.3);
|
||||
|
||||
void fragment(){
|
||||
|
||||
vec2 scroll = vec2(1.0,0.0) * TIME * speed;
|
||||
vec4 tex = texture(TEXTURE, (UV));
|
||||
float palette_swap = mod(tex.r - TIME * palette_speed, 1.0);
|
||||
COLOR = vec4(texture(palette, vec2(palette_swap, 0)).rgb, tex.a);
|
||||
|
||||
vec4 tex = texture(TEXTURE, UV);
|
||||
COLOR = vec4(outline_color.rgb, tex.a * outline_color.a);
|
||||
}
|
||||
@@ -77,6 +77,12 @@ var ignoreBounce = false
|
||||
var frames = 1
|
||||
var animSpeed = 0
|
||||
|
||||
#Masking
|
||||
var mask_texture_path = ""
|
||||
var mask_texture = null
|
||||
var use_mask = false
|
||||
var mask_opacity = 1.0
|
||||
|
||||
var remadePolygon = false
|
||||
|
||||
var clipped = false
|
||||
@@ -119,6 +125,9 @@ func _ready():
|
||||
|
||||
sprite.texture = tex
|
||||
|
||||
# Initialize masking
|
||||
setupMasking()
|
||||
|
||||
var bitmap = BitMap.new()
|
||||
bitmap.create_from_image_alpha(imageData)
|
||||
|
||||
@@ -409,3 +418,53 @@ func visToggle(keys):
|
||||
|
||||
func makeVis():
|
||||
$WobbleOrigin/DragOrigin.visible = true
|
||||
|
||||
## Setup masking system
|
||||
func setupMasking():
|
||||
if use_mask and mask_texture_path != "":
|
||||
loadMaskTexture()
|
||||
updateMaskShader()
|
||||
|
||||
## Load mask texture from file path
|
||||
func loadMaskTexture():
|
||||
if mask_texture_path == "":
|
||||
return
|
||||
|
||||
var img = Image.new()
|
||||
var err = img.load(mask_texture_path)
|
||||
if err != OK:
|
||||
print_debug("Failed to load mask texture: " + mask_texture_path)
|
||||
return
|
||||
|
||||
mask_texture = ImageTexture.create_from_image(img)
|
||||
|
||||
## Apply or remove mask shader
|
||||
func updateMaskShader():
|
||||
if use_mask and mask_texture != null:
|
||||
# Create mask material with shader
|
||||
var mask_shader = load("res://ui_scenes/selectedSprite/mask.gdshader")
|
||||
var mask_material = ShaderMaterial.new()
|
||||
mask_material.shader = mask_shader
|
||||
mask_material.set_shader_parameter("mask_texture", mask_texture)
|
||||
mask_material.set_shader_parameter("use_mask", true)
|
||||
mask_material.set_shader_parameter("mask_opacity", mask_opacity)
|
||||
|
||||
sprite.material = mask_material
|
||||
else:
|
||||
# Remove mask material
|
||||
sprite.material = null
|
||||
|
||||
## Set mask texture from external source
|
||||
func setMaskTexture(texture_path: String, opacity: float = 1.0):
|
||||
mask_texture_path = texture_path
|
||||
mask_opacity = opacity
|
||||
use_mask = true
|
||||
loadMaskTexture()
|
||||
updateMaskShader()
|
||||
|
||||
## Remove masking
|
||||
func removeMask():
|
||||
use_mask = false
|
||||
mask_texture = null
|
||||
mask_texture_path = ""
|
||||
updateMaskShader()
|
||||
|
||||
@@ -202,8 +202,8 @@ func _on_costume_check_toggled(button_pressed):
|
||||
## @param button_pressed: bool - Whether StreamDeck should be enabled
|
||||
func _on_stream_deck_check_toggled(button_pressed):
|
||||
Saving.settings["useStreamDeck"] = button_pressed
|
||||
if ElgatoStreamDeck:
|
||||
ElgatoStreamDeck.refresh_connection()
|
||||
if get_node_or_null("/root/ElgatoStreamDeck"):
|
||||
get_node("/root/ElgatoStreamDeck").refresh_connection()
|
||||
Global.pushUpdate("StreamDeck integration " + ("enabled" if button_pressed else "disabled") + ".")
|
||||
|
||||
|
||||
|
||||
@@ -75,6 +75,15 @@ func setImage():
|
||||
|
||||
$VisToggle/setToggle/Label.text = "toggle: \"" + Global.heldSprite.toggle + "\""
|
||||
|
||||
# Update masking controls
|
||||
$Masking/useMaskCheckbox.button_pressed = Global.heldSprite.use_mask
|
||||
$Masking/maskOpacityLabel.text = "mask opacity: " + str(Global.heldSprite.mask_opacity)
|
||||
$Masking/maskOpacity.value = Global.heldSprite.mask_opacity
|
||||
if Global.heldSprite.mask_texture_path.is_empty():
|
||||
$Masking/maskPathLabel.text = "mask: (none)"
|
||||
else:
|
||||
$Masking/maskPathLabel.text = "mask: " + Global.heldSprite.mask_texture_path.get_file()
|
||||
|
||||
changeRotLimit()
|
||||
|
||||
setLayerButtons()
|
||||
@@ -365,7 +374,24 @@ func _on_set_toggle_pressed():
|
||||
$VisToggle/setToggle/Label.text = "toggle: AWAITING INPUT"
|
||||
await Global.main.fatfuckingballs
|
||||
|
||||
var keys = await Global.main.spriteVisToggles
|
||||
var key = keys[0]
|
||||
Global.heldSprite.toggle = key
|
||||
$VisToggle/setToggle/Label.text = "toggle: \"" + Global.heldSprite.toggle + "\""
|
||||
## Masking signal handlers
|
||||
func _on_use_mask_checkbox_toggled(button_pressed):
|
||||
Global.heldSprite.use_mask = button_pressed
|
||||
Global.heldSprite.updateMaskShader()
|
||||
|
||||
func _on_mask_opacity_value_changed(value):
|
||||
Global.heldSprite.mask_opacity = value
|
||||
$Masking/maskOpacityLabel.text = "mask opacity: " + str(value)
|
||||
Global.heldSprite.updateMaskShader()
|
||||
|
||||
func _on_select_mask_pressed():
|
||||
Global.main.openMaskSelection()
|
||||
|
||||
func updateMaskDisplay(path: String):
|
||||
$Masking/maskPathLabel.text = "mask: " + path.get_file()
|
||||
$Masking/useMaskCheckbox.button_pressed = true
|
||||
|
||||
func _on_clear_mask_pressed():
|
||||
Global.heldSprite.removeMask()
|
||||
$Masking/maskPathLabel.text = "mask: (none)"
|
||||
$Masking/useMaskCheckbox.button_pressed = false
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
[ext_resource type="Texture2D" uid="uid://gflmeocxfnrq" path="res://ui_scenes/settings/deleteHotkey.png" id="27_fgu6g"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_21kva"]
|
||||
size = Vector2(245, 1341)
|
||||
size = Vector2(245, 1596.5)
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_hxmah"]
|
||||
shader = ExtResource("3_ky0lu")
|
||||
@@ -14285,7 +14285,7 @@ script = ExtResource("1_hp0e3")
|
||||
z_index = -2
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
position = Vector2(122.5, 670.5)
|
||||
position = Vector2(122.5, 725)
|
||||
shape = SubResource("RectangleShape2D_21kva")
|
||||
|
||||
[node name="Border" type="Sprite2D" parent="."]
|
||||
@@ -14910,6 +14910,66 @@ position = Vector2(-2, -2)
|
||||
texture = ExtResource("27_fgu6g")
|
||||
centered = false
|
||||
|
||||
[node name="Masking" type="Node2D" parent="."]
|
||||
position = Vector2(0, 1360.83)
|
||||
|
||||
[node name="animationBox" type="Sprite2D" parent="Masking"]
|
||||
position = Vector2(125, 92.4052)
|
||||
scale = Vector2(1, 0.905768)
|
||||
texture = ExtResource("15_wqi8b")
|
||||
|
||||
[node name="maskingLabel" type="Label" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_right = 120.0
|
||||
offset_bottom = 26.0
|
||||
text = "MASKING"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="useMaskCheckbox" type="CheckBox" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_top = 30.0
|
||||
offset_right = 200.0
|
||||
offset_bottom = 54.0
|
||||
text = "Use Mask"
|
||||
|
||||
[node name="maskOpacityLabel" type="Label" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_top = 60.0
|
||||
offset_right = 200.0
|
||||
offset_bottom = 86.0
|
||||
text = "mask opacity: 1.0"
|
||||
|
||||
[node name="maskOpacity" type="HSlider" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_top = 90.0
|
||||
offset_right = 200.0
|
||||
offset_bottom = 106.0
|
||||
max_value = 1.0
|
||||
step = 0.01
|
||||
value = 1.0
|
||||
|
||||
[node name="maskPathLabel" type="Label" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_top = 120.0
|
||||
offset_right = 400.0
|
||||
offset_bottom = 146.0
|
||||
text = "mask: (none)"
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="selectMask" type="Button" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_top = 150.0
|
||||
offset_right = 120.0
|
||||
offset_bottom = 181.0
|
||||
text = "Select Mask"
|
||||
|
||||
[node name="clearMask" type="Button" parent="Masking"]
|
||||
offset_left = 130.0
|
||||
offset_top = 150.0
|
||||
offset_right = 220.0
|
||||
offset_bottom = 181.0
|
||||
text = "Clear Mask"
|
||||
|
||||
[connection signal="pressed" from="Buttons/Speaking/speaking" to="." method="_on_speaking_pressed"]
|
||||
[connection signal="pressed" from="Buttons/Blinking/blinking" to="." method="_on_blinking_pressed"]
|
||||
[connection signal="pressed" from="Buttons/Trash/trash" to="." method="_on_trash_pressed"]
|
||||
@@ -14941,3 +15001,7 @@ centered = false
|
||||
[connection signal="pressed" from="Layers/Layer10/layerButton10" to="." method="_on_layer_button_10_pressed"]
|
||||
[connection signal="pressed" from="VisToggle/setToggle" to="." method="_on_set_toggle_pressed"]
|
||||
[connection signal="pressed" from="VisToggle/setToggle/delete" to="." method="_on_delete_pressed"]
|
||||
[connection signal="toggled" from="Masking/useMaskCheckbox" to="." method="_on_use_mask_checkbox_toggled"]
|
||||
[connection signal="value_changed" from="Masking/maskOpacity" to="." method="_on_mask_opacity_value_changed"]
|
||||
[connection signal="pressed" from="Masking/selectMask" to="." method="_on_select_mask_pressed"]
|
||||
[connection signal="pressed" from="Masking/clearMask" to="." method="_on_clear_mask_pressed"]
|
||||
|
||||
Reference in New Issue
Block a user