├── 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 | Buy Me A Coffee 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 | --------------------------------------------------------------------------------