├── icon.png
├── Portray
├── pics
│ ├── Portray.kra
│ ├── Portray.kra~
│ ├── PetRectangle.png
│ └── PetRectangle.png.import
├── Cat.tscn
├── Rectangle.gd
└── Rectangle.tscn
├── Pet
├── minigames
│ └── balloonPop
│ │ ├── string.png
│ │ ├── balloon.png
│ │ ├── balloon.tscn
│ │ ├── string.png.import
│ │ ├── balloon.png.import
│ │ ├── balloonPop.tscn
│ │ └── balloonPop.gd
├── popupOpener
│ ├── popupOpener.tscn
│ └── popupOpener.gd
├── windows.gd
├── Notes.gd
├── Pet.gd
├── Calculator.gd
├── Menus.gd
├── Shortcuts.gd
└── Pet.tscn
├── .gitignore
├── default_env.tres
├── Root.tscn
├── icon.png.import
├── project.godot
├── LICENSE
├── README.md
└── Root.gd
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ASecondGuy/DesktopPet/HEAD/icon.png
--------------------------------------------------------------------------------
/Portray/pics/Portray.kra:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ASecondGuy/DesktopPet/HEAD/Portray/pics/Portray.kra
--------------------------------------------------------------------------------
/Portray/pics/Portray.kra~:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ASecondGuy/DesktopPet/HEAD/Portray/pics/Portray.kra~
--------------------------------------------------------------------------------
/Portray/pics/PetRectangle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ASecondGuy/DesktopPet/HEAD/Portray/pics/PetRectangle.png
--------------------------------------------------------------------------------
/Pet/minigames/balloonPop/string.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ASecondGuy/DesktopPet/HEAD/Pet/minigames/balloonPop/string.png
--------------------------------------------------------------------------------
/Pet/minigames/balloonPop/balloon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ASecondGuy/DesktopPet/HEAD/Pet/minigames/balloonPop/balloon.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Godot-specific ignores
3 | .import/
4 | export.cfg
5 | export_presets.cfg
6 |
7 | # Mono-specific ignores
8 | .mono/
9 | data_*/
10 |
--------------------------------------------------------------------------------
/default_env.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Environment" load_steps=2 format=2]
2 |
3 | [sub_resource type="ProceduralSky" id=1]
4 |
5 | [resource]
6 | background_mode = 2
7 | background_sky = SubResource( 1 )
8 |
--------------------------------------------------------------------------------
/Pet/popupOpener/popupOpener.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://Pet/popupOpener/popupOpener.gd" type="Script" id=1]
4 |
5 | [node name="popupOpener" type="Button"]
6 | margin_right = 12.0
7 | margin_bottom = 20.0
8 | size_flags_horizontal = 4
9 | script = ExtResource( 1 )
10 |
11 | [connection signal="pressed" from="." to="." method="_on_popupOpener_pressed"]
12 |
--------------------------------------------------------------------------------
/Pet/windows.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 |
4 | func _ready():
5 |
6 | for popup in get_children():
7 | # Don't do this if it is not a popup
8 | if !popup is WindowDialog: continue
9 |
10 | popup.connect("gui_input", self, "_on_input", [popup])
11 |
12 |
13 | func _on_input(event:InputEvent, window:WindowDialog):
14 | if event is InputEventMouseButton:
15 | move_child(window, get_child_count()-1)
16 |
17 |
--------------------------------------------------------------------------------
/Portray/Cat.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene format=2]
2 |
3 | [node name="Cat" type="Node2D"]
4 |
5 | [node name="poligons" type="Node2D" parent="."]
6 |
7 | [node name="Polygon2D" type="Polygon2D" parent="poligons"]
8 |
9 | [node name="Label" type="Label" parent="."]
10 | margin_left = 12.0
11 | margin_top = 16.0
12 | margin_right = 455.0
13 | margin_bottom = 47.0
14 | text = "You found some unused content that might never see the light of day
15 | have fun with my horrible cat drawing if you have Krita installed"
16 |
--------------------------------------------------------------------------------
/Pet/Notes.gd:
--------------------------------------------------------------------------------
1 | extends TextEdit
2 |
3 | onready var save_timer = $saveTimer
4 |
5 | const NOTES_PATH := "user://notes.txt"
6 |
7 |
8 | func _ready():
9 | #load
10 | var f = File.new()
11 | if f.open(NOTES_PATH, File.READ) != OK: return
12 |
13 | text = f.get_as_text()
14 |
15 | f.close()
16 |
17 |
18 |
19 | func _on_Notes_text_changed():
20 | save_timer.start()
21 |
22 |
23 | func _on_saveTimer_timeout():
24 | var f = File.new()
25 | if f.open(NOTES_PATH, File.WRITE) != OK: return
26 |
27 | f.store_string(text)
28 | print("Notes saved")
29 | f.close()
30 |
--------------------------------------------------------------------------------
/Pet/minigames/balloonPop/balloon.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=2]
2 |
3 | [ext_resource path="res://Pet/minigames/balloonPop/balloon.png" type="Texture" id=1]
4 | [ext_resource path="res://Pet/minigames/balloonPop/string.png" type="Texture" id=2]
5 |
6 | [node name="balloon" type="TextureButton"]
7 | margin_right = 1024.0
8 | margin_bottom = 1024.0
9 | rect_scale = Vector2( 0.1, 0.1 )
10 | texture_normal = ExtResource( 1 )
11 |
12 | [node name="String" type="TextureRect" parent="."]
13 | modulate = Color( 0.423529, 0.423529, 0.423529, 1 )
14 | show_behind_parent = true
15 | texture = ExtResource( 2 )
16 |
--------------------------------------------------------------------------------
/Root.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=2]
2 |
3 | [ext_resource path="res://Root.gd" type="Script" id=1]
4 | [ext_resource path="res://Pet/Pet.tscn" type="PackedScene" id=2]
5 |
6 | [node name="Root" type="Node"]
7 | script = ExtResource( 1 )
8 |
9 | [node name="Pet" parent="." instance=ExtResource( 2 )]
10 |
11 | [node name="debugdraw" type="Node2D" parent="."]
12 | visible = false
13 |
14 | [node name="ColorRect" type="ColorRect" parent="debugdraw"]
15 | margin_left = -1859.0
16 | margin_top = -1503.0
17 | margin_right = 3657.0
18 | margin_bottom = 1841.0
19 | mouse_filter = 2
20 | color = Color( 0.196078, 1, 0, 0.294118 )
21 |
22 | [node name="Line2D" type="Line2D" parent="debugdraw"]
23 | points = PoolVector2Array( 100, 0, 100, 100 )
24 |
--------------------------------------------------------------------------------
/Pet/popupOpener/popupOpener.gd:
--------------------------------------------------------------------------------
1 | extends Button
2 | # This is far from perfect. I need to find a better solution.
3 |
4 | enum OPENMODE {
5 |
6 | }
7 |
8 | export var hide_again := true
9 | export(NodePath) var popup_path : NodePath
10 |
11 | var popup : WindowDialog
12 |
13 | func _ready():
14 | popup = get_node(popup_path)
15 |
16 |
17 | func _on_popupOpener_pressed():
18 | if !popup is WindowDialog:
19 | push_error(str(popup, " is not a WindowDialog"))
20 | return
21 |
22 | if !popup.visible:
23 |
24 | popup.popup()
25 | # warning-ignore:return_value_discarded
26 | popup.connect("popup_hide", popup, "show")
27 | return
28 |
29 |
30 | if hide_again:
31 | popup.disconnect("popup_hide", popup, "show")
32 | popup.hide()
33 |
--------------------------------------------------------------------------------
/Portray/Rectangle.gd:
--------------------------------------------------------------------------------
1 | extends Sprite
2 | # This is a way to do it.
3 | # Continue or don't. I don't care.
4 |
5 |
6 | onready var anim : AnimationPlayer = $AnimationPlayer
7 | var idle_variations := 1
8 |
9 |
10 | func _ready():
11 | randomize()
12 |
13 |
14 | func get_animation_player()->AnimationPlayer:
15 | return anim
16 |
17 | func walk():
18 | anim.play("walk")
19 |
20 | func stop_walk():
21 | if anim.current_animation == "walk":
22 | anim.play("idle")
23 |
24 |
25 | func _on_AnimationPlayer_animation_finished(anim_name):
26 | if anim_name == "walk": return
27 |
28 | if randi() % 10 == 0:
29 | if idle_variations == 1:
30 | anim.play("idle_1")
31 | elif idle_variations > 1:
32 | anim.play("idle_"+str((randi() % idle_variations)+1))
33 | else:
34 | anim.play("idle")
35 | else:
36 | anim.play("idle")
37 |
--------------------------------------------------------------------------------
/icon.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://icon.png"
13 | dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | process/normal_map_invert_y=false
32 | stream=false
33 | size_limit=0
34 | detect_3d=true
35 | svg/scale=1.0
36 |
--------------------------------------------------------------------------------
/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=4
10 |
11 | [application]
12 |
13 | config/name="DesctopPet"
14 | run/main_scene="res://Root.tscn"
15 | config/icon="res://icon.png"
16 |
17 | [display]
18 |
19 | window/size/resizable=false
20 | window/size/borderless=true
21 | window/size/always_on_top=true
22 | window/per_pixel_transparency/allowed=true
23 | window/per_pixel_transparency/enabled=true
24 |
25 | [gui]
26 |
27 | theme/custom="res://Pet/PetTheme.tres"
28 |
29 | [physics]
30 |
31 | common/enable_pause_aware_picking=true
32 |
33 | [rendering]
34 |
35 | environment/default_environment="res://default_env.tres"
36 |
--------------------------------------------------------------------------------
/Pet/minigames/balloonPop/string.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/string.png-496beb930d323ae4670fb762e2e208c0.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Pet/minigames/balloonPop/string.png"
13 | dest_files=[ "res://.import/string.png-496beb930d323ae4670fb762e2e208c0.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | process/normal_map_invert_y=false
32 | stream=false
33 | size_limit=0
34 | detect_3d=true
35 | svg/scale=1.0
36 |
--------------------------------------------------------------------------------
/Pet/minigames/balloonPop/balloon.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/balloon.png-91dfa994b82b58dff886fb82917d9932.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Pet/minigames/balloonPop/balloon.png"
13 | dest_files=[ "res://.import/balloon.png-91dfa994b82b58dff886fb82917d9932.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | process/normal_map_invert_y=false
32 | stream=false
33 | size_limit=0
34 | detect_3d=true
35 | svg/scale=1.0
36 |
--------------------------------------------------------------------------------
/Portray/pics/PetRectangle.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/PetRectangle.png-e09841d2cad11bdd937555a38e6e4a9e.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Portray/pics/PetRectangle.png"
13 | dest_files=[ "res://.import/PetRectangle.png-e09841d2cad11bdd937555a38e6e4a9e.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=false
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | process/normal_map_invert_y=false
32 | stream=false
33 | size_limit=0
34 | detect_3d=false
35 | svg/scale=1.0
36 |
--------------------------------------------------------------------------------
/Pet/Pet.gd:
--------------------------------------------------------------------------------
1 | extends Node2D
2 | # This is the pet itself
3 | # You can make as many as you'd like in theory and this can be anything you like.
4 | # As long as everything you want on screen is in the Cutout group and overwrites
5 | # get_cutout_polygon() or is a Control, Path2D or Sprite. Those 3 have automatic
6 | # polygons assinged if they don't overwrite get_cutout_polygon()
7 |
8 | var goal_position : Vector2
9 |
10 | onready var visual := $PetVisuals
11 | onready var buttons := $Buttons
12 |
13 |
14 | func _ready():
15 | randomize()
16 | choose_pos()
17 |
18 |
19 | func _process(_delta):
20 |
21 | if (goal_position-position).length() > 20:
22 | var dir := ((goal_position-position)/10).clamped(5)
23 | position += dir
24 | visual.flip_h = dir.x > 0
25 | visual.walk()
26 | # get_node("/root/Root").update_pet_area()
27 | else:
28 | visual.stop_walk()
29 |
30 |
31 |
32 | func choose_pos():
33 | var r = buttons.get_rect()
34 | goal_position = Vector2(rand_range(0, OS.window_size.x-r.size.x), rand_range(0, OS.window_size.y-r.size.y))
35 |
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 ASecondGuy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DesktopPet
2 |
3 | You want a pet on your desktop? This might someday be what you are looking for.
4 | For now it is just a proof of concept that it can be done.
5 |
6 | Feel free to insert your own Pet and add or remove features all you want
7 |
8 | ## Features:
9 | - Notes Panel
10 | - configurable shortcuts
11 | - a calculator
12 | - a balloon minigame
13 | - A Rectangle friend who likes to pick some boogers out his nose
14 |
15 | ## Making a pet from scratch
16 | To not block clicks everywhere you need one passthrou polygon.
17 | Combinding polygons is already managed for you by the root node.
18 | You only need to put all your nodes you want to be seen into the Cutout group.
19 | Control, Path2D and Sprite Nodes will work automatically.
20 | To customize theyr behaviour or use other nodes you have to overwrite get_cutout_polygon().
21 | That should return a array of points for the polygon.
22 | (All nodes inheriting from Control will also work, Path2D will result in a polygon not a path)
23 |
24 |
25 |
26 |
27 |
28 | If you like this and want to see development continue consider to
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Pet/Calculator.gd:
--------------------------------------------------------------------------------
1 | extends VBoxContainer
2 |
3 | onready var _line_edit := $LineEdit
4 |
5 |
6 | func _ready():
7 |
8 | for btn in $Grid.get_children():
9 | btn.focus_mode = FOCUS_NONE
10 | if btn.get_signal_connection_list("pressed").size() > 0:
11 | continue
12 | btn.connect("pressed", self, "_eval_btn", [btn.text])
13 | _line_edit.grab_focus()
14 |
15 | func _eval_btn(text:String):
16 | _line_edit.grab_focus()
17 | var car_pos = _line_edit.caret_position
18 | _line_edit.append_at_cursor(text)
19 | if text.ends_with("("):
20 | _line_edit.append_at_cursor(")")
21 | _line_edit.caret_position = car_pos+1
22 |
23 |
24 | func _on_Equals_pressed():
25 | var ex := Expression.new()
26 | # warning-ignore:return_value_discarded
27 | ex.parse(_line_edit.text)
28 | _line_edit.text = str(ex.execute([], null, false))
29 | if ex.has_execute_failed():
30 | _line_edit.text = ex.get_error_text()
31 | _line_edit.caret_position = _line_edit.text.length()
32 |
33 |
34 |
35 |
36 |
37 | func _on_clearbtn_pressed():
38 | _line_edit.text = ""
39 |
40 | func _on_backbtn_pressed():
41 | var text : String = _line_edit.text
42 | text.erase(_line_edit.caret_position-1, 1)
43 | var car_pos = _line_edit.caret_position
44 | _line_edit.text = text
45 | _line_edit.caret_position = car_pos-1
46 |
47 |
48 |
49 |
50 | func _on_Calculator_about_to_show():
51 | _line_edit.call_deferred("grab_focus")
52 |
--------------------------------------------------------------------------------
/Pet/Menus.gd:
--------------------------------------------------------------------------------
1 | extends VBoxContainer
2 | # Mouse position is being weird with passthrough.
3 | # I'm not sure what would be the best way to solve it.
4 |
5 |
6 | onready var ignore_mouse := $ignore_mouse_timer
7 | var mouse_inside := false
8 |
9 | var following := false
10 |
11 |
12 | func _process(delta):
13 | _test_mouse_pos()
14 | var change : float = [-delta, delta][int(mouse_inside)]*5
15 |
16 | if mouse_inside and !ignore_mouse.time_left > 0:
17 | get_parent().goal_position = get_parent().global_position
18 | modulate.a = clamp(modulate.a+change, 0, 1)
19 |
20 | for b in get_children():
21 | if b is BaseButton:
22 | b.disabled = !_can_use_btns()
23 |
24 | func _ready():
25 | for b in get_children():
26 | if b is Control:
27 | b.connect("mouse_entered", self, "set", ["mouse_inside", true])
28 | # b.connect("mouse_exited", self, "set", ["mouse_inside", false])
29 |
30 |
31 |
32 |
33 |
34 | func _on_follow_toggled(button_pressed):
35 | following = button_pressed
36 |
37 | func _can_use_btns()->bool:
38 | if ignore_mouse.time_left > 0: return false
39 | if modulate.a < .8: return false
40 | return true
41 |
42 | func _test_mouse_pos():
43 | mouse_inside = get_global_rect().grow(-10).has_point(get_global_mouse_position())
44 |
45 | func _on_Buttons_mouse_exited():
46 | mouse_inside = false
47 |
48 |
49 | func _on_goAway_pressed():
50 | ignore_mouse.start()
51 | mouse_inside = false
52 | get_parent().choose_pos()
53 |
--------------------------------------------------------------------------------
/Pet/minigames/balloonPop/balloonPop.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://Pet/minigames/balloonPop/balloonPop.gd" type="Script" id=1]
4 |
5 | [sub_resource type="Curve" id=1]
6 | _data = [ Vector2( 0, 0 ), 0.0, 0.0, 0, 0, Vector2( 0.151961, 1 ), 0.0, 0.0, 0, 0, Vector2( 0.857843, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 0 ), 0.0, 0.0, 0, 0 ]
7 |
8 | [sub_resource type="Curve" id=2]
9 | _data = [ Vector2( 0, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 0.238636 ), -2.04976, 0.0, 0, 0 ]
10 |
11 | [node name="balloonPop" type="MarginContainer"]
12 | anchor_right = 1.0
13 | anchor_bottom = 1.0
14 | script = ExtResource( 1 )
15 |
16 | [node name="Timer" type="Timer" parent="."]
17 | autostart = true
18 |
19 | [node name="respawnTimer" type="Timer" parent="."]
20 | one_shot = true
21 |
22 | [node name="VBoxContainer" type="VBoxContainer" parent="."]
23 | margin_left = 5.0
24 | margin_top = 5.0
25 | margin_right = 1019.0
26 | margin_bottom = 595.0
27 |
28 | [node name="Label" type="Label" parent="VBoxContainer"]
29 | margin_right = 1014.0
30 | margin_bottom = 14.0
31 |
32 | [node name="balloonArea" type="Control" parent="VBoxContainer"]
33 | margin_top = 18.0
34 | margin_right = 1014.0
35 | margin_bottom = 590.0
36 | size_flags_horizontal = 3
37 | size_flags_vertical = 3
38 |
39 | [node name="CPUParticles2D" type="CPUParticles2D" parent="VBoxContainer"]
40 | emitting = false
41 | amount = 80
42 | lifetime = 3.0
43 | one_shot = true
44 | explosiveness = 0.64
45 | emission_shape = 1
46 | emission_sphere_radius = 20.97
47 | spread = 180.0
48 | initial_velocity = 100.0
49 | scale_amount = 4.0
50 | scale_amount_random = 0.2
51 | scale_amount_curve = SubResource( 1 )
52 | hue_variation = 1.0
53 | hue_variation_random = 1.0
54 | anim_speed_curve = SubResource( 2 )
55 |
56 | [connection signal="timeout" from="respawnTimer" to="." method="_on_respawnTimer_timeout"]
57 |
--------------------------------------------------------------------------------
/Pet/Shortcuts.gd:
--------------------------------------------------------------------------------
1 | extends VBoxContainer
2 |
3 | onready var conf_btn := $Configs
4 | onready var add_btn := $Configs/add
5 | onready var rem_btn := $Configs/remove
6 | onready var _list := $Scroll/list
7 |
8 |
9 | const SHORTCUT_SAVE_PATH := "user://shortcuts.json"
10 |
11 | var shortcut_paths := []
12 |
13 |
14 | func _ready():
15 | #load
16 | var f = File.new()
17 | if f.open(SHORTCUT_SAVE_PATH, File.READ) != OK: return
18 |
19 | shortcut_paths = parse_json(f.get_as_text())
20 | refresh_list()
21 | f.close()
22 |
23 |
24 | func refresh_list():
25 | for c in _list.get_children():
26 | c.queue_free()
27 |
28 | for path in shortcut_paths:
29 | var btn := Button.new()
30 | btn.clip_text = true
31 | btn.text = path.get_file()
32 | _list.add_child(btn)
33 | # warning-ignore:return_value_discarded
34 | btn.connect("pressed", self, "pressed", [path])
35 |
36 |
37 |
38 |
39 | func save(data=shortcut_paths):
40 | var f = File.new()
41 | if f.open(SHORTCUT_SAVE_PATH, File.WRITE) != OK: return
42 |
43 | f.store_string(to_json(data))
44 | print("Shortcuts saved")
45 | f.close()
46 |
47 |
48 | func pressed(path:String):
49 |
50 | if rem_btn.pressed:
51 | shortcut_paths.erase(path)
52 | save()
53 | refresh_list()
54 | return
55 |
56 |
57 | match (path.get_extension()):
58 | "exe":
59 | var drive = path.split("/")[0]
60 | var command = str(drive, " && cd ", path.get_base_dir().trim_prefix(drive))
61 | command+=" && start "+ path.get_file()+" & exit"
62 |
63 | prints("Started:", OS.execute("cmd.exe", ["/C", command], false))
64 | _:
65 | # warning-ignore:return_value_discarded
66 | OS.shell_open(path)
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | func _on_FileDialog_file_selected(path):
76 | shortcut_paths.push_back(path)
77 | save()
78 | refresh_list()
79 |
80 |
81 |
82 |
83 | #config btns
84 | func _on_Configure_pressed():
85 | add_btn.visible = !add_btn.visible
86 | rem_btn.visible = !rem_btn.visible
87 | rem_btn.pressed = false
88 |
89 | func _on_add_pressed():
90 | $"../../FileDialog".popup(get_global_rect())
91 |
92 |
93 |
--------------------------------------------------------------------------------
/Pet/minigames/balloonPop/balloonPop.gd:
--------------------------------------------------------------------------------
1 | # warning-ignore-all:return_value_discarded
2 | extends MarginContainer
3 |
4 | var balloon_scene := preload("res://Pet/minigames/balloonPop/balloon.tscn")
5 |
6 | var colors := {
7 | "Red": Color.red,
8 | "Green" : Color.green,
9 | "Yellow" : Color.yellow,
10 | "Blue": Color.blue,
11 | "Purple": Color.purple,
12 | "Orange": Color.orange,
13 | }
14 |
15 |
16 | onready var _timer := $Timer
17 | onready var _label := $VBoxContainer/Label
18 | onready var _area := $VBoxContainer/balloonArea
19 | onready var _rng := RandomNumberGenerator.new()
20 | onready var _particles := $VBoxContainer/CPUParticles2D
21 |
22 | var search_color : Color
23 |
24 |
25 | func _ready():
26 | _rng.randomize()
27 |
28 | func start():
29 | var i = _rng.randi_range(0, colors.size()-1)
30 | _label.text = "Pop the %s balloon" % colors.keys()[i]
31 | search_color = colors.values()[i]
32 | call_deferred("_spawn")
33 |
34 | func _process(_delta):
35 | var offset := sin(_timer.time_left * 2 * PI)
36 | for balloon in _area.get_children():
37 | balloon.rect_position.y += offset
38 |
39 |
40 | func _spawn():
41 | var possible := colors.values()
42 | possible.erase(search_color)
43 |
44 | for _i in range(_rng.randi_range(1, 3)):
45 | _spawn_color(search_color)
46 |
47 | for _i in range(_rng.randi_range(3, 7)):
48 | _spawn_color(possible[_rng.randi_range(0, possible.size()-1)])
49 |
50 |
51 | func _spawn_color(color:Color):
52 | var b : TextureButton = balloon_scene.instance()
53 | _area.add_child(b)
54 | # position
55 | var max_pos : Vector2 = _area.rect_size-b.rect_size*b.rect_scale
56 | b.rect_position.x = _rng.randf_range(0, max_pos.x)
57 | b.rect_position.y = _rng.randf_range(0, max_pos.y)
58 |
59 | # signals
60 | b.connect("pressed", self, "_on_destroy", [color, b])
61 | b.connect("pressed", b, "queue_free")
62 | # modulate
63 | b.self_modulate = color
64 |
65 |
66 |
67 | func _on_destroy(color:Color, button=null):
68 | if color.is_equal_approx(search_color):
69 | _delete_all()
70 | if button is TextureButton:
71 | _particles.global_position = button.rect_global_position+button.rect_size/2*button.rect_scale
72 | _particles.restart()
73 | $respawnTimer.start()
74 |
75 |
76 | func _delete_all():
77 | for b in _area.get_children():
78 | b.queue_free()
79 |
80 |
81 |
82 | func _on_respawnTimer_timeout():
83 | _spawn()
84 |
--------------------------------------------------------------------------------
/Portray/Rectangle.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=7 format=2]
2 |
3 | [ext_resource path="res://Portray/pics/PetRectangle.png" type="Texture" id=1]
4 | [ext_resource path="res://Portray/Rectangle.gd" type="Script" id=2]
5 |
6 | [sub_resource type="Animation" id=1]
7 | length = 0.001
8 | tracks/0/type = "value"
9 | tracks/0/path = NodePath(".:frame")
10 | tracks/0/interp = 1
11 | tracks/0/loop_wrap = true
12 | tracks/0/imported = false
13 | tracks/0/enabled = true
14 | tracks/0/keys = {
15 | "times": PoolRealArray( 0 ),
16 | "transitions": PoolRealArray( 1 ),
17 | "update": 0,
18 | "values": [ 0 ]
19 | }
20 |
21 | [sub_resource type="Animation" id=2]
22 | resource_name = "idle"
23 | tracks/0/type = "value"
24 | tracks/0/path = NodePath(".:frame")
25 | tracks/0/interp = 1
26 | tracks/0/loop_wrap = true
27 | tracks/0/imported = false
28 | tracks/0/enabled = true
29 | tracks/0/keys = {
30 | "times": PoolRealArray( 0, 0.5 ),
31 | "transitions": PoolRealArray( 1, 1 ),
32 | "update": 1,
33 | "values": [ 0, 1 ]
34 | }
35 |
36 | [sub_resource type="Animation" id=3]
37 | resource_name = "idle_1"
38 | length = 4.0
39 | tracks/0/type = "value"
40 | tracks/0/path = NodePath(".:frame")
41 | tracks/0/interp = 1
42 | tracks/0/loop_wrap = true
43 | tracks/0/imported = false
44 | tracks/0/enabled = true
45 | tracks/0/keys = {
46 | "times": PoolRealArray( 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5 ),
47 | "transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1 ),
48 | "update": 1,
49 | "values": [ 2, 3, 2, 3, 2, 3, 2, 3 ]
50 | }
51 |
52 | [sub_resource type="Animation" id=4]
53 | resource_name = "walk"
54 | length = 1.4
55 | loop = true
56 | tracks/0/type = "value"
57 | tracks/0/path = NodePath(".:frame")
58 | tracks/0/interp = 0
59 | tracks/0/loop_wrap = true
60 | tracks/0/imported = false
61 | tracks/0/enabled = true
62 | tracks/0/keys = {
63 | "times": PoolRealArray( 0, 0.2, 0.4, 0.7, 0.9, 1.2 ),
64 | "transitions": PoolRealArray( 1, 1, 1, 1, 1, 1 ),
65 | "update": 0,
66 | "values": [ 4, 5, 6, 7, 8, 9 ]
67 | }
68 |
69 | [node name="Pet" type="Sprite" groups=["Cutout"]]
70 | scale = Vector2( 2, 2 )
71 | texture = ExtResource( 1 )
72 | centered = false
73 | hframes = 4
74 | vframes = 3
75 | script = ExtResource( 2 )
76 |
77 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
78 | playback_speed = 2.0
79 | anims/RESET = SubResource( 1 )
80 | anims/idle = SubResource( 2 )
81 | anims/idle_1 = SubResource( 3 )
82 | anims/walk = SubResource( 4 )
83 |
84 | [connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_AnimationPlayer_animation_finished"]
85 |
--------------------------------------------------------------------------------
/Root.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 | ## This script does the basic functions of a desctop pet.
3 |
4 | var window_rect := Rect2()
5 | var full_screen_detection := false
6 |
7 | onready var line := $"debugdraw/Line2D"
8 |
9 |
10 | func _ready():
11 | Engine.target_fps = 30
12 | OS.window_position = Vector2()
13 | OS.window_size = OS.get_screen_size()-Vector2(0, 1)
14 |
15 | # doesn't always work in the Editor. Some inconsistent wierdness of 3.4.4
16 | # should work on export.
17 | OS.set_window_always_on_top(true)
18 | window_rect = Rect2(OS.window_position, OS.window_size)
19 | get_viewport().transparent_bg = true
20 | update_pet_area()
21 |
22 | func _process(_delta):
23 | update_pet_area()
24 |
25 | ## This manages the passthrough
26 | ## Currently called every frame. I'm working on a more performant solution.
27 | func update_pet_area():
28 | if full_screen_detection:
29 | OS.set_window_mouse_passthrough([])
30 | return
31 |
32 | var polygons = []
33 | for node in get_tree().get_nodes_in_group("Cutout"):
34 | if node.has_method("get_cutout_polygon"):
35 | polygons.push_back(node.get_cutout_polygon())
36 | continue
37 |
38 | if Array(ClassDB.get_inheriters_from_class("Control")).has(node.get_class()):
39 | if !node.is_visible_in_tree(): continue
40 | var pol := []
41 | var r : Rect2 = node.get_global_rect()
42 | r = r.grow(5)
43 |
44 | ## handle expand margins
45 | var panel = node.get_stylebox("panel")
46 | if panel.has_method("get_expand_margin"):
47 | for i in range(4):
48 | r = r.grow_margin(i, panel.get_expand_margin(i))
49 | if panel.has_method("get_expand_margin_size"):
50 | for i in range(4):
51 | r = r.grow_margin(i, panel.get_expand_margin_size(i))
52 | ################
53 |
54 | pol.push_back(r.position)
55 | pol.push_back(Vector2(r.position.x+r.size.x, r.position.y))
56 | pol.push_back(r.position+r.size)
57 | pol.push_back(Vector2(r.position.x, r.position.y+r.size.y))
58 | polygons.push_back(pol)
59 | elif node.get_class() == "Path2D":
60 | polygons.push_back(node.curve.get_baked_points())
61 | elif node.get_class() == "Sprite":
62 | var pol := []
63 | var r : Rect2 = node.get_rect()
64 | r.position = node.global_position
65 | r.size *= node.scale
66 | pol.push_back(r.position)
67 | pol.push_back(Vector2(r.position.x+r.size.x, r.position.y))
68 | pol.push_back(r.position+r.size)
69 | pol.push_back(Vector2(r.position.x, r.position.y+r.size.y))
70 | polygons.push_back(pol)
71 |
72 | var points := []
73 |
74 |
75 | # It works. better don't touch it.
76 | points.clear()
77 | while _polygons_overlap(polygons):
78 | for i in range(polygons.size()):
79 | for i2 in range(polygons.size()):
80 | var pol = polygons[i]
81 | var pol2 = polygons[i2]
82 | if i == i2: continue
83 | if pol == null or pol2 == null: continue
84 | if _polygons_intesect(pol, pol2):
85 | polygons[i] = Geometry.merge_polygons_2d(pol, pol2)[0]
86 | polygons[i2] = null
87 |
88 | while polygons.has(null):
89 | polygons.remove(polygons.find_last(null))
90 |
91 | points.push_back(Vector2())
92 | for poly in polygons:
93 | for p in poly:
94 | points.push_back(p)
95 | points.push_back(poly[0])
96 | points.push_back(Vector2())
97 |
98 | # Manage debug draw
99 | line.clear_points()
100 | for p in points:
101 | line.add_point(p)
102 | OS.set_window_mouse_passthrough(PoolVector2Array(points))
103 |
104 |
105 | func _polygons_intesect(p1, p2)->bool:
106 | # prints("Inter:", Geometry.intersect_polygons_2d(p1, p2).size())
107 | return Geometry.intersect_polygons_2d(p1, p2).size() > 0
108 |
109 | func _polygons_overlap(polygons:Array)->bool:
110 | for i in range(polygons.size()):
111 | for i2 in range(polygons.size()):
112 | if i <= i2: continue
113 | if _polygons_intesect(polygons[i], polygons[i2]):
114 | return true
115 | return false
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/Pet/Pet.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=12 format=2]
2 |
3 | [ext_resource path="res://Pet/Pet.gd" type="Script" id=1]
4 | [ext_resource path="res://Portray/Rectangle.tscn" type="PackedScene" id=2]
5 | [ext_resource path="res://Pet/Menus.gd" type="Script" id=3]
6 | [ext_resource path="res://Pet/Notes.gd" type="Script" id=4]
7 | [ext_resource path="res://Pet/Shortcuts.gd" type="Script" id=5]
8 | [ext_resource path="res://Pet/PetTheme.tres" type="Theme" id=6]
9 | [ext_resource path="res://Pet/popupOpener/popupOpener.tscn" type="PackedScene" id=7]
10 | [ext_resource path="res://Pet/Calculator.gd" type="Script" id=8]
11 | [ext_resource path="res://Pet/windows.gd" type="Script" id=9]
12 | [ext_resource path="res://Pet/minigames/balloonPop/balloonPop.tscn" type="PackedScene" id=10]
13 |
14 | [sub_resource type="GDScript" id=1]
15 | script/source = "extends Button
16 |
17 |
18 | func _on_nextScreenbtn_pressed():
19 | OS.current_screen+=1
20 | OS.window_size = OS.get_screen_size(OS.current_screen)
21 | "
22 |
23 | [node name="Pet" type="Node2D"]
24 | script = ExtResource( 1 )
25 |
26 | [node name="PetVisuals" parent="." instance=ExtResource( 2 )]
27 |
28 | [node name="Timer" type="Timer" parent="."]
29 | wait_time = 20.0
30 | autostart = true
31 |
32 | [node name="windows" type="Control" parent="."]
33 | margin_right = 40.0
34 | margin_bottom = 40.0
35 | script = ExtResource( 9 )
36 |
37 | [node name="Notes" type="WindowDialog" parent="windows" groups=["Cutout"]]
38 | margin_left = 152.0
39 | margin_top = 68.0
40 | margin_right = 356.0
41 | margin_bottom = 400.0
42 | window_title = "Notes"
43 | resizable = true
44 |
45 | [node name="Margin" type="MarginContainer" parent="windows/Notes"]
46 | anchor_right = 1.0
47 | anchor_bottom = 1.0
48 |
49 | [node name="Notes" type="TextEdit" parent="windows/Notes/Margin"]
50 | margin_left = 5.0
51 | margin_top = 5.0
52 | margin_right = 199.0
53 | margin_bottom = 327.0
54 | script = ExtResource( 4 )
55 |
56 | [node name="saveTimer" type="Timer" parent="windows/Notes/Margin/Notes"]
57 | wait_time = 0.5
58 | one_shot = true
59 |
60 | [node name="Shortcuts" type="WindowDialog" parent="windows" groups=["Cutout"]]
61 | margin_left = 152.0
62 | margin_top = 52.0
63 | margin_right = 352.0
64 | margin_bottom = 402.0
65 | rect_min_size = Vector2( 200, 140 )
66 | window_title = "Shortcuts"
67 | resizable = true
68 |
69 | [node name="Margin" type="MarginContainer" parent="windows/Shortcuts"]
70 | anchor_right = 1.0
71 | anchor_bottom = 1.0
72 |
73 | [node name="Shortcuts" type="VBoxContainer" parent="windows/Shortcuts/Margin"]
74 | margin_left = 5.0
75 | margin_top = 5.0
76 | margin_right = 195.0
77 | margin_bottom = 345.0
78 | script = ExtResource( 5 )
79 |
80 | [node name="Configs" type="HBoxContainer" parent="windows/Shortcuts/Margin/Shortcuts"]
81 | margin_right = 200.0
82 | margin_bottom = 20.0
83 |
84 | [node name="Configure" type="Button" parent="windows/Shortcuts/Margin/Shortcuts/Configs"]
85 | margin_right = 72.0
86 | margin_bottom = 20.0
87 | size_flags_vertical = 4
88 | text = "Configure"
89 |
90 | [node name="add" type="Button" parent="windows/Shortcuts/Margin/Shortcuts/Configs"]
91 | visible = false
92 | margin_left = 76.0
93 | margin_right = 111.0
94 | margin_bottom = 30.0
95 | size_flags_vertical = 4
96 | text = "add"
97 |
98 | [node name="remove" type="CheckBox" parent="windows/Shortcuts/Margin/Shortcuts/Configs"]
99 | visible = false
100 | margin_left = 76.0
101 | margin_right = 153.0
102 | margin_bottom = 30.0
103 | size_flags_vertical = 4
104 | text = "remove"
105 |
106 | [node name="Scroll" type="ScrollContainer" parent="windows/Shortcuts/Margin/Shortcuts"]
107 | margin_top = 24.0
108 | margin_right = 200.0
109 | margin_bottom = 350.0
110 | size_flags_horizontal = 3
111 | size_flags_vertical = 3
112 | scroll_horizontal_enabled = false
113 |
114 | [node name="list" type="VBoxContainer" parent="windows/Shortcuts/Margin/Shortcuts/Scroll"]
115 | margin_right = 200.0
116 | margin_bottom = 326.0
117 | size_flags_horizontal = 3
118 | size_flags_vertical = 3
119 |
120 | [node name="FileDialog" type="FileDialog" parent="windows/Shortcuts" groups=["Cutout"]]
121 | margin_top = -52.0
122 | margin_right = 300.0
123 | margin_bottom = 348.0
124 | theme = ExtResource( 6 )
125 | window_title = "Open a File"
126 | resizable = true
127 | mode = 0
128 | access = 2
129 | filters = PoolStringArray( "*.exe" )
130 | show_hidden_files = true
131 | current_dir = "/devRepos/DesctopPet"
132 | current_path = "/devRepos/DesctopPet/"
133 |
134 | [node name="Calculator" type="WindowDialog" parent="windows" groups=["Cutout"]]
135 | margin_left = 197.0
136 | margin_top = 3.0
137 | margin_right = 331.0
138 | margin_bottom = 201.0
139 | window_title = "Calculator"
140 | resizable = true
141 |
142 | [node name="Margin" type="MarginContainer" parent="windows/Calculator"]
143 | anchor_right = 1.0
144 | anchor_bottom = 1.0
145 |
146 | [node name="Box" type="VBoxContainer" parent="windows/Calculator/Margin"]
147 | margin_left = 5.0
148 | margin_top = 5.0
149 | margin_right = 129.0
150 | margin_bottom = 193.0
151 | script = ExtResource( 8 )
152 |
153 | [node name="LineEdit" type="LineEdit" parent="windows/Calculator/Margin/Box"]
154 | margin_right = 124.0
155 | margin_bottom = 30.0
156 | rect_min_size = Vector2( 0, 30 )
157 | clear_button_enabled = true
158 | caret_blink = true
159 |
160 | [node name="Grid" type="GridContainer" parent="windows/Calculator/Margin/Box"]
161 | margin_top = 34.0
162 | margin_right = 124.0
163 | margin_bottom = 188.0
164 | size_flags_vertical = 3
165 | columns = 4
166 |
167 | [node name="backbtn" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
168 | margin_right = 28.0
169 | margin_bottom = 27.0
170 | size_flags_horizontal = 3
171 | size_flags_vertical = 3
172 | text = "<"
173 |
174 | [node name="Button2" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
175 | margin_left = 32.0
176 | margin_right = 60.0
177 | margin_bottom = 27.0
178 | size_flags_horizontal = 3
179 | size_flags_vertical = 3
180 | text = "("
181 |
182 | [node name="Button3" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
183 | margin_left = 64.0
184 | margin_right = 92.0
185 | margin_bottom = 27.0
186 | size_flags_horizontal = 3
187 | size_flags_vertical = 3
188 | text = ")"
189 |
190 | [node name="Button4" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
191 | margin_left = 96.0
192 | margin_right = 124.0
193 | margin_bottom = 27.0
194 | size_flags_horizontal = 3
195 | size_flags_vertical = 3
196 | text = "/"
197 |
198 | [node name="Button5" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
199 | margin_top = 31.0
200 | margin_right = 28.0
201 | margin_bottom = 58.0
202 | size_flags_horizontal = 3
203 | size_flags_vertical = 3
204 | text = "7"
205 |
206 | [node name="Button6" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
207 | margin_left = 32.0
208 | margin_top = 31.0
209 | margin_right = 60.0
210 | margin_bottom = 58.0
211 | size_flags_horizontal = 3
212 | size_flags_vertical = 3
213 | text = "8"
214 |
215 | [node name="Button7" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
216 | margin_left = 64.0
217 | margin_top = 31.0
218 | margin_right = 92.0
219 | margin_bottom = 58.0
220 | size_flags_horizontal = 3
221 | size_flags_vertical = 3
222 | text = "9"
223 |
224 | [node name="Button8" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
225 | margin_left = 96.0
226 | margin_top = 31.0
227 | margin_right = 124.0
228 | margin_bottom = 58.0
229 | size_flags_horizontal = 3
230 | size_flags_vertical = 3
231 | text = "*"
232 |
233 | [node name="Button9" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
234 | margin_top = 62.0
235 | margin_right = 28.0
236 | margin_bottom = 89.0
237 | size_flags_horizontal = 3
238 | size_flags_vertical = 3
239 | text = "4"
240 |
241 | [node name="Button10" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
242 | margin_left = 32.0
243 | margin_top = 62.0
244 | margin_right = 60.0
245 | margin_bottom = 89.0
246 | size_flags_horizontal = 3
247 | size_flags_vertical = 3
248 | text = "5"
249 |
250 | [node name="Button11" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
251 | margin_left = 64.0
252 | margin_top = 62.0
253 | margin_right = 92.0
254 | margin_bottom = 89.0
255 | size_flags_horizontal = 3
256 | size_flags_vertical = 3
257 | text = "6"
258 |
259 | [node name="Button12" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
260 | margin_left = 96.0
261 | margin_top = 62.0
262 | margin_right = 124.0
263 | margin_bottom = 89.0
264 | size_flags_horizontal = 3
265 | size_flags_vertical = 3
266 | text = "-"
267 |
268 | [node name="Button13" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
269 | margin_top = 93.0
270 | margin_right = 28.0
271 | margin_bottom = 120.0
272 | size_flags_horizontal = 3
273 | size_flags_vertical = 3
274 | text = "1"
275 |
276 | [node name="Button14" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
277 | margin_left = 32.0
278 | margin_top = 93.0
279 | margin_right = 60.0
280 | margin_bottom = 120.0
281 | size_flags_horizontal = 3
282 | size_flags_vertical = 3
283 | text = "2"
284 |
285 | [node name="Button15" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
286 | margin_left = 64.0
287 | margin_top = 93.0
288 | margin_right = 92.0
289 | margin_bottom = 120.0
290 | size_flags_horizontal = 3
291 | size_flags_vertical = 3
292 | text = "3"
293 |
294 | [node name="Button16" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
295 | margin_left = 96.0
296 | margin_top = 93.0
297 | margin_right = 124.0
298 | margin_bottom = 120.0
299 | size_flags_horizontal = 3
300 | size_flags_vertical = 3
301 | text = "+"
302 |
303 | [node name="clearbtn" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
304 | margin_top = 124.0
305 | margin_right = 28.0
306 | margin_bottom = 151.0
307 | size_flags_horizontal = 3
308 | size_flags_vertical = 3
309 | text = "c"
310 |
311 | [node name="Button18" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
312 | margin_left = 32.0
313 | margin_top = 124.0
314 | margin_right = 60.0
315 | margin_bottom = 151.0
316 | size_flags_horizontal = 3
317 | size_flags_vertical = 3
318 | text = "0"
319 |
320 | [node name="Button19" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
321 | margin_left = 64.0
322 | margin_top = 124.0
323 | margin_right = 92.0
324 | margin_bottom = 151.0
325 | size_flags_horizontal = 3
326 | size_flags_vertical = 3
327 | text = "."
328 |
329 | [node name="Equals" type="Button" parent="windows/Calculator/Margin/Box/Grid"]
330 | margin_left = 96.0
331 | margin_top = 124.0
332 | margin_right = 124.0
333 | margin_bottom = 151.0
334 | size_flags_horizontal = 3
335 | size_flags_vertical = 3
336 | text = "="
337 |
338 | [node name="MinigameList" type="WindowDialog" parent="windows" groups=["Cutout"]]
339 | margin_left = 359.0
340 | margin_top = 118.0
341 | margin_right = 493.0
342 | margin_bottom = 158.0
343 | window_title = "MinigameList"
344 | resizable = true
345 |
346 | [node name="List" type="VBoxContainer" parent="windows/MinigameList"]
347 | anchor_right = 1.0
348 | anchor_bottom = 1.0
349 | size_flags_horizontal = 3
350 |
351 | [node name="BalloonPop" parent="windows/MinigameList/List" instance=ExtResource( 7 )]
352 | margin_left = 23.0
353 | margin_right = 110.0
354 | text = "BalloonPOP"
355 | hide_again = false
356 | popup_path = NodePath("../../../BalloonGame")
357 |
358 | [node name="BalloonGame" type="WindowDialog" parent="windows" groups=["Cutout"]]
359 | margin_right = 438.0
360 | margin_bottom = 400.0
361 | window_title = "BalloonPOP"
362 |
363 | [node name="balloonPop" parent="windows/BalloonGame" instance=ExtResource( 10 )]
364 |
365 | [node name="Buttons" type="VBoxContainer" parent="." groups=["Cutout"]]
366 | margin_right = 128.0
367 | margin_bottom = 128.0
368 | rect_min_size = Vector2( 64, 64 )
369 | mouse_filter = 0
370 | size_flags_horizontal = 0
371 | size_flags_vertical = 0
372 | theme = ExtResource( 6 )
373 | alignment = 1
374 | script = ExtResource( 3 )
375 |
376 | [node name="Notesbtn" parent="Buttons" instance=ExtResource( 7 )]
377 | margin_left = 39.0
378 | margin_right = 89.0
379 | text = "Notes"
380 | popup_path = NodePath("../../windows/Notes")
381 |
382 | [node name="shortcutbtn" parent="Buttons" instance=ExtResource( 7 )]
383 | margin_left = 28.0
384 | margin_top = 24.0
385 | margin_right = 100.0
386 | margin_bottom = 44.0
387 | text = "Shortcuts"
388 | popup_path = NodePath("../../windows/Shortcuts")
389 |
390 | [node name="calculatorbtn" parent="Buttons" instance=ExtResource( 7 )]
391 | margin_left = 26.0
392 | margin_top = 48.0
393 | margin_right = 101.0
394 | margin_bottom = 68.0
395 | text = "Calculator"
396 | popup_path = NodePath("../../windows/Calculator")
397 |
398 | [node name="goAway" type="Button" parent="Buttons"]
399 | margin_left = 30.0
400 | margin_top = 72.0
401 | margin_right = 97.0
402 | margin_bottom = 92.0
403 | size_flags_horizontal = 4
404 | text = "Go Away"
405 |
406 | [node name="follow" type="Button" parent="Buttons"]
407 | visible = false
408 | margin_left = 25.0
409 | margin_top = 96.0
410 | margin_right = 102.0
411 | margin_bottom = 116.0
412 | size_flags_horizontal = 4
413 | toggle_mode = true
414 | text = "Follow Me"
415 |
416 | [node name="minigame" parent="Buttons" instance=ExtResource( 7 )]
417 | margin_left = 23.0
418 | margin_top = 96.0
419 | margin_right = 105.0
420 | margin_bottom = 116.0
421 | text = "Minigames"
422 | popup_path = NodePath("../../windows/MinigameList")
423 |
424 | [node name="nextScreenbtn" type="Button" parent="Buttons"]
425 | margin_left = 19.0
426 | margin_top = 120.0
427 | margin_right = 108.0
428 | margin_bottom = 140.0
429 | size_flags_horizontal = 4
430 | text = "Next Screen"
431 | script = SubResource( 1 )
432 |
433 | [node name="ignore_mouse_timer" type="Timer" parent="Buttons"]
434 | one_shot = true
435 |
436 | [connection signal="timeout" from="Timer" to="." method="choose_pos"]
437 | [connection signal="text_changed" from="windows/Notes/Margin/Notes" to="windows/Notes/Margin/Notes" method="_on_Notes_text_changed"]
438 | [connection signal="timeout" from="windows/Notes/Margin/Notes/saveTimer" to="windows/Notes/Margin/Notes" method="_on_saveTimer_timeout"]
439 | [connection signal="pressed" from="windows/Shortcuts/Margin/Shortcuts/Configs/Configure" to="windows/Shortcuts/Margin/Shortcuts" method="_on_Configure_pressed"]
440 | [connection signal="pressed" from="windows/Shortcuts/Margin/Shortcuts/Configs/add" to="windows/Shortcuts/Margin/Shortcuts" method="_on_add_pressed"]
441 | [connection signal="file_selected" from="windows/Shortcuts/FileDialog" to="windows/Shortcuts/Margin/Shortcuts" method="_on_FileDialog_file_selected"]
442 | [connection signal="about_to_show" from="windows/Calculator" to="windows/Calculator/Margin/Box" method="_on_Calculator_about_to_show"]
443 | [connection signal="pressed" from="windows/Calculator/Margin/Box/Grid/backbtn" to="windows/Calculator/Margin/Box" method="_on_backbtn_pressed"]
444 | [connection signal="pressed" from="windows/Calculator/Margin/Box/Grid/clearbtn" to="windows/Calculator/Margin/Box" method="_on_clearbtn_pressed"]
445 | [connection signal="pressed" from="windows/Calculator/Margin/Box/Grid/Equals" to="windows/Calculator/Margin/Box" method="_on_Equals_pressed"]
446 | [connection signal="about_to_show" from="windows/BalloonGame" to="windows/BalloonGame/balloonPop" method="start"]
447 | [connection signal="popup_hide" from="windows/BalloonGame" to="windows/BalloonGame/balloonPop" method="_delete_all"]
448 | [connection signal="mouse_entered" from="Buttons" to="Buttons" method="set" binds= [ "mouse_inside", true ]]
449 | [connection signal="mouse_exited" from="Buttons" to="Buttons" method="_on_Buttons_mouse_exited"]
450 | [connection signal="pressed" from="Buttons/goAway" to="Buttons" method="_on_goAway_pressed"]
451 | [connection signal="toggled" from="Buttons/follow" to="Buttons" method="_on_follow_toggled"]
452 | [connection signal="pressed" from="Buttons/nextScreenbtn" to="Buttons/nextScreenbtn" method="_on_nextScreenbtn_pressed"]
453 |
--------------------------------------------------------------------------------