diff --git a/.idea/.idea.your are an ai ceo/.idea/libraries/GdSdk.xml b/.idea/.idea.your are an ai ceo/.idea/libraries/GdSdk.xml index 0059883..04a2e8b 100644 --- a/.idea/.idea.your are an ai ceo/.idea/libraries/GdSdk.xml +++ b/.idea/.idea.your are an ai ceo/.idea/libraries/GdSdk.xml @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/Company.cs b/Company.cs new file mode 100644 index 0000000..36f4c7d --- /dev/null +++ b/Company.cs @@ -0,0 +1,27 @@ +using Godot; + +[GlobalClass] +public partial class Company : Resource +{ + [Export] + public float Hype { get; set; } + + [Export] + public float Money { get; set; } = 10_000; + + [Export] + public float Workers { get; set; } = 1; + + [Export] + public float AverageSalary { get; set; } = 100; + + /// + /// Cost per Quarter + /// + public float Cost => Workers * AverageSalary; + + /// + /// Runway in Quarters + /// + public int Runway => Mathf.FloorToInt(Money / Cost); +} diff --git a/Company.cs.uid b/Company.cs.uid new file mode 100644 index 0000000..1517d2f --- /dev/null +++ b/Company.cs.uid @@ -0,0 +1 @@ +uid://cxr0qf8ut8t4p diff --git a/CurrentTimeLine.cs b/CurrentTimeLine.cs new file mode 100644 index 0000000..dc38f24 --- /dev/null +++ b/CurrentTimeLine.cs @@ -0,0 +1,16 @@ +using Godot; +using yourareanaiceo; + +public partial class CurrentTimeLine : Panel +{ + [Export] + float speed = 2f; + + public override void _Process(double delta) + { + var pos = OffsetTransformPosition; + pos.Y += speed * delta.toFloat(); + + OffsetTransformPosition = pos; + } +} diff --git a/CurrentTimeLine.cs.uid b/CurrentTimeLine.cs.uid new file mode 100644 index 0000000..3e0936e --- /dev/null +++ b/CurrentTimeLine.cs.uid @@ -0,0 +1 @@ +uid://cbbrups0mkp17 diff --git a/DaySchedule.cs b/DaySchedule.cs new file mode 100644 index 0000000..d18c4c8 --- /dev/null +++ b/DaySchedule.cs @@ -0,0 +1,24 @@ +using System.Linq; +using Godot; + +[SceneTree] +public partial class DaySchedule : PanelContainer +{ + [Export] + private Company _company; + + [Export] + private int _hoursInDay = 6; + + public override void _Ready() + { + TimeSlotContainer.GetChildren().ToList().ForEach(child => child.QueueFree()); + + for (var i = 0; i < _hoursInDay; i++) + { + var timeSlot = Instantiator.Instantiate(); + + TimeSlotContainer.AddChild(timeSlot); + } + } +} diff --git a/DaySchedule.cs.uid b/DaySchedule.cs.uid new file mode 100644 index 0000000..4547284 --- /dev/null +++ b/DaySchedule.cs.uid @@ -0,0 +1 @@ +uid://xv51uvc4koyc diff --git a/DaySchedule.tscn b/DaySchedule.tscn new file mode 100644 index 0000000..b2f56a9 --- /dev/null +++ b/DaySchedule.tscn @@ -0,0 +1,93 @@ +[gd_scene format=3 uid="uid://covomnw8s7k1n"] + +[ext_resource type="Script" uid="uid://xv51uvc4koyc" path="res://DaySchedule.cs" id="1_b6clr"] +[ext_resource type="PackedScene" uid="uid://nnr6u0igggve" path="res://TimeSlot.tscn" id="2_ascl5"] +[ext_resource type="Script" uid="uid://cxr0qf8ut8t4p" path="res://Company.cs" id="2_dtij7"] +[ext_resource type="Script" uid="uid://cbbrups0mkp17" path="res://CurrentTimeLine.cs" id="3_dtij7"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_cm0pq"] +bg_color = Color(0, 0, 0, 1) +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(0, 0, 0, 1) +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[sub_resource type="Resource" id="Resource_b6clr"] +script = ExtResource("2_dtij7") +metadata/_custom_type_script = "uid://cxr0qf8ut8t4p" + +[sub_resource type="StyleBoxLine" id="StyleBoxLine_r0du0"] +color = Color(1, 0, 0, 1) +thickness = 5 + +[node name="DaySchedule" type="PanelContainer" unique_id=457829015] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -107.0 +offset_top = -227.0 +offset_right = 107.0 +offset_bottom = 227.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_cm0pq") +script = ExtResource("1_b6clr") +_company = SubResource("Resource_b6clr") + +[node name="TimeSlotContainer" type="VBoxContainer" parent="." unique_id=1932322928] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 0 +mouse_filter = 2 +theme_override_constants/separation = 2 +alignment = 1 + +[node name="TimeSlot" parent="TimeSlotContainer" unique_id=979842204 instance=ExtResource("2_ascl5")] +layout_mode = 2 + +[node name="TimeSlot2" parent="TimeSlotContainer" unique_id=2109237451 instance=ExtResource("2_ascl5")] +layout_mode = 2 + +[node name="TimeSlot3" parent="TimeSlotContainer" unique_id=819921714 instance=ExtResource("2_ascl5")] +layout_mode = 2 + +[node name="TimeSlot4" parent="TimeSlotContainer" unique_id=1554222465 instance=ExtResource("2_ascl5")] +layout_mode = 2 + +[node name="TimeSlot5" parent="TimeSlotContainer" unique_id=1612666058 instance=ExtResource("2_ascl5")] +layout_mode = 2 + +[node name="TimeSlot6" parent="TimeSlotContainer" unique_id=1912431362 instance=ExtResource("2_ascl5")] +layout_mode = 2 + +[node name="TimeSlot7" parent="TimeSlotContainer" unique_id=1182001581 instance=ExtResource("2_ascl5")] +layout_mode = 2 + +[node name="TimeSlot8" parent="TimeSlotContainer" unique_id=193012813 instance=ExtResource("2_ascl5")] +layout_mode = 2 + +[node name="TimeSlot9" parent="TimeSlotContainer" unique_id=886153912 instance=ExtResource("2_ascl5")] +visible = false +layout_mode = 2 + +[node name="TimeSlot10" parent="TimeSlotContainer" unique_id=1760034209 instance=ExtResource("2_ascl5")] +visible = false +layout_mode = 2 + +[node name="CurrentTimeLine" type="Panel" parent="." unique_id=961292687] +custom_minimum_size = Vector2(0, 5) +clip_contents = true +layout_mode = 2 +size_flags_vertical = 0 +offset_transform_enabled = true +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxLine_r0du0") +script = ExtResource("3_dtij7") diff --git a/DoubleExtensions.cs b/DoubleExtensions.cs new file mode 100644 index 0000000..d8322c3 --- /dev/null +++ b/DoubleExtensions.cs @@ -0,0 +1,9 @@ +namespace yourareanaiceo; + +public static class DoubleExtensions +{ + public static float toFloat(this double value) + { + return (float)value; + } +} diff --git a/DoubleExtensions.cs.uid b/DoubleExtensions.cs.uid new file mode 100644 index 0000000..fd843cf --- /dev/null +++ b/DoubleExtensions.cs.uid @@ -0,0 +1 @@ +uid://dtfiuvcat531i diff --git a/DropZone.cs b/DropZone.cs new file mode 100644 index 0000000..3dd1b40 --- /dev/null +++ b/DropZone.cs @@ -0,0 +1,32 @@ +using Godot; + +public partial class DropZone : Control +{ + public override bool _CanDropData(Vector2 atPosition, Variant data) + { + return data.VariantType == Variant.Type.Object + && data.AsGodotObject() is MeetingControlDragData; + } + + public override void _DropData(Vector2 atPosition, Variant data) + { + var meetingControl = ((MeetingControlDragData)data).MeetingControl; + var meetingPhysicsBox = meetingControl.MeetingPhysicsBox; + + var main = (Main)FindParent("Main"); + main.AddChild(meetingPhysicsBox); + meetingPhysicsBox.Position = GetGlobalMousePosition(); + meetingControl.QueueFree(); + + meetingControl.DragIsHandled = true; + } + + public override void _Notification(int what) + { + if (what == NotificationDragBegin) + MouseFilter = MouseFilterEnum.Pass; + + if (what == NotificationDragEnd) + MouseFilter = MouseFilterEnum.Ignore; + } +} diff --git a/DropZone.cs.uid b/DropZone.cs.uid new file mode 100644 index 0000000..f09a86b --- /dev/null +++ b/DropZone.cs.uid @@ -0,0 +1 @@ +uid://bs531c76ivhtf diff --git a/Main.cs b/Main.cs new file mode 100644 index 0000000..d240ec2 --- /dev/null +++ b/Main.cs @@ -0,0 +1,4 @@ +using Godot; + +[SceneTree] +public partial class Main : Node2D { } diff --git a/Main.cs.uid b/Main.cs.uid new file mode 100644 index 0000000..c0a3756 --- /dev/null +++ b/Main.cs.uid @@ -0,0 +1 @@ +uid://d1h0qvskvk1wu diff --git a/Main.tscn b/Main.tscn index bc2d0ee..d440a39 100644 --- a/Main.tscn +++ b/Main.tscn @@ -1,8 +1,12 @@ [gd_scene format=3 uid="uid://b2rl7r8oav3hy"] +[ext_resource type="Script" uid="uid://d1h0qvskvk1wu" path="res://Main.cs" id="1_3dxm6"] [ext_resource type="PackedScene" uid="uid://dciugg77wsy6p" path="res://MeetingPhysicsBox.tscn" id="1_glv2v"] -[ext_resource type="PackedScene" uid="uid://nnr6u0igggve" path="res://TimeSlot.tscn" id="1_uu6xs"] +[ext_resource type="PackedScene" uid="uid://covomnw8s7k1n" path="res://DaySchedule.tscn" id="1_r0du0"] [ext_resource type="Resource" uid="uid://mifwco1yj8kc" path="res://resources/meetings/coffee_meeting.tres" id="3_r0du0"] +[ext_resource type="Resource" uid="uid://du72uxjqr0h4a" path="res://resources/meetings/lockin.tres" id="4_cm0pq"] +[ext_resource type="Resource" uid="uid://bcd4qf4i84pwf" path="res://resources/meetings/work_product_1.tres" id="5_fos0i"] +[ext_resource type="Script" uid="uid://bs531c76ivhtf" path="res://DropZone.cs" id="7_lgr22"] [sub_resource type="LabelSettings" id="LabelSettings_sko1m"] font_size = 64 @@ -12,8 +16,6 @@ stacked_outline_0/size = 9 stacked_shadow_0/offset = Vector2(4, 4) stacked_shadow_0/outline_size = 2 -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_50jir"] - [sub_resource type="RectangleShape2D" id="RectangleShape2D_sko1m"] size = Vector2(727.5, 20) @@ -21,6 +23,12 @@ size = Vector2(727.5, 20) size = Vector2(21.5, 1920) [node name="Main" type="Node2D" unique_id=287617203] +script = ExtResource("1_3dxm6") + +[node name="MeetingSpawn" type="Marker2D" parent="." unique_id=1266113438] +unique_name_in_owner = true +position = Vector2(775, 36) +gizmo_extents = 40.0 [node name="CanvasLayer" type="CanvasLayer" parent="." unique_id=1328071901] @@ -53,57 +61,75 @@ grow_horizontal = 0 text = "Inbox" label_settings = SubResource("LabelSettings_sko1m") -[node name="PanelContainer" type="PanelContainer" parent="." unique_id=1636973054] -anchors_preset = 8 -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -offset_left = 96.0 -offset_top = 114.0 -offset_right = 302.0 -offset_bottom = 574.0 -grow_horizontal = 2 -grow_vertical = 2 -mouse_filter = 2 -theme_override_styles/panel = SubResource("StyleBoxEmpty_50jir") +[node name="PanelContainer" type="FoldableContainer" parent="CanvasLayer/Control" unique_id=1121461524] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -245.0 +offset_right = 4.535034 +offset_bottom = 149.0 +grow_horizontal = 0 +title = "Your Company Inc." +title_alignment = 1 -[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer" unique_id=1658498861] -layout_mode = 2 -mouse_filter = 2 -alignment = 1 - -[node name="TimeSlot" parent="PanelContainer/VBoxContainer" unique_id=979842204 instance=ExtResource("1_uu6xs")] +[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/Control/PanelContainer" unique_id=1331001176] layout_mode = 2 -[node name="TimeSlot2" parent="PanelContainer/VBoxContainer" unique_id=1532657435 instance=ExtResource("1_uu6xs")] +[node name="HBoxContainer4" type="HBoxContainer" parent="CanvasLayer/Control/PanelContainer/VBoxContainer" unique_id=879116080] +modulate = Color(1, 0, 0, 1) layout_mode = 2 -[node name="TimeSlot3" parent="PanelContainer/VBoxContainer" unique_id=1504478834 instance=ExtResource("1_uu6xs")] +[node name="Label" type="Label" parent="CanvasLayer/Control/PanelContainer/VBoxContainer/HBoxContainer4" unique_id=54936711] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Runway" + +[node name="Label2" type="Label" parent="CanvasLayer/Control/PanelContainer/VBoxContainer/HBoxContainer4" unique_id=111473790] +layout_mode = 2 +text = "2" + +[node name="HBoxContainer" type="HBoxContainer" parent="CanvasLayer/Control/PanelContainer/VBoxContainer" unique_id=500602395] layout_mode = 2 -[node name="TimeSlot4" parent="PanelContainer/VBoxContainer" unique_id=1891572413 instance=ExtResource("1_uu6xs")] +[node name="Label" type="Label" parent="CanvasLayer/Control/PanelContainer/VBoxContainer/HBoxContainer" unique_id=1599952499] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Hype" + +[node name="Label2" type="Label" parent="CanvasLayer/Control/PanelContainer/VBoxContainer/HBoxContainer" unique_id=780587971] +layout_mode = 2 +text = "10" + +[node name="HBoxContainer2" type="HBoxContainer" parent="CanvasLayer/Control/PanelContainer/VBoxContainer" unique_id=981225226] layout_mode = 2 -[node name="TimeSlot5" parent="PanelContainer/VBoxContainer" unique_id=464659559 instance=ExtResource("1_uu6xs")] +[node name="Label" type="Label" parent="CanvasLayer/Control/PanelContainer/VBoxContainer/HBoxContainer2" unique_id=1687312201] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Money" + +[node name="Label2" type="Label" parent="CanvasLayer/Control/PanelContainer/VBoxContainer/HBoxContainer2" unique_id=172841693] +layout_mode = 2 +text = "10.000" + +[node name="HBoxContainer3" type="HBoxContainer" parent="CanvasLayer/Control/PanelContainer/VBoxContainer" unique_id=2146415473] layout_mode = 2 -[node name="TimeSlot6" parent="PanelContainer/VBoxContainer" unique_id=1773919778 instance=ExtResource("1_uu6xs")] +[node name="Label" type="Label" parent="CanvasLayer/Control/PanelContainer/VBoxContainer/HBoxContainer3" unique_id=1336632204] layout_mode = 2 +size_flags_horizontal = 3 +text = "Workers" -[node name="TimeSlot7" parent="PanelContainer/VBoxContainer" unique_id=1476334804 instance=ExtResource("1_uu6xs")] +[node name="Label2" type="Label" parent="CanvasLayer/Control/PanelContainer/VBoxContainer/HBoxContainer3" unique_id=617177241] layout_mode = 2 +text = "1" -[node name="TimeSlot8" parent="PanelContainer/VBoxContainer" unique_id=2116243857 instance=ExtResource("1_uu6xs")] -layout_mode = 2 - -[node name="TimeSlot9" parent="PanelContainer/VBoxContainer" unique_id=1672825401 instance=ExtResource("1_uu6xs")] -visible = false -layout_mode = 2 - -[node name="TimeSlot10" parent="PanelContainer/VBoxContainer" unique_id=488121571 instance=ExtResource("1_uu6xs")] -visible = false -layout_mode = 2 +[node name="DaySchedule" parent="." unique_id=457829015 instance=ExtResource("1_r0du0")] +offset_left = 106.0 +offset_top = 117.0 +offset_right = 320.0 +offset_bottom = 571.0 [node name="Box" type="StaticBody2D" parent="." unique_id=56956355] @@ -130,10 +156,12 @@ MeetingResource = ExtResource("3_r0du0") [node name="Meeting4" parent="." unique_id=1960552374 instance=ExtResource("1_glv2v")] position = Vector2(707, -340) rotation = 0.24779713 +MeetingResource = ExtResource("4_cm0pq") [node name="Meeting5" parent="." unique_id=1692042144 instance=ExtResource("1_glv2v")] position = Vector2(851, -500) rotation = 0.24779713 +MeetingResource = ExtResource("5_fos0i") [node name="Meeting6" parent="." unique_id=2120697586 instance=ExtResource("1_glv2v")] position = Vector2(604, -619.99994) @@ -152,6 +180,7 @@ rotation = 0.24779713 [node name="Meeting9" parent="." unique_id=1055632102 instance=ExtResource("1_glv2v")] position = Vector2(614, -732.99994) rotation = 0.24779713 +MeetingResource = ExtResource("5_fos0i") [node name="Meeting2" parent="." unique_id=1691479453 instance=ExtResource("1_glv2v")] position = Vector2(937, -352) @@ -162,3 +191,13 @@ MeetingResource = ExtResource("3_r0du0") position = Vector2(762.9999, -181.00012) rotation = -0.18364333 MeetingResource = ExtResource("3_r0du0") + +[node name="DropZone" type="Control" parent="." unique_id=80494692] +layout_mode = 3 +anchors_preset = 0 +offset_left = 457.0 +offset_top = 9.0 +offset_right = 1080.0 +offset_bottom = 571.0 +mouse_filter = 2 +script = ExtResource("7_lgr22") diff --git a/MeetingControl.cs b/MeetingControl.cs index 8582fa5..7997d56 100644 --- a/MeetingControl.cs +++ b/MeetingControl.cs @@ -11,7 +11,11 @@ public partial class MeetingControl : Control [Export] public MeetingPhysicsBox MeetingPhysicsBox; - public bool InSlot { get; set; } + private MeetingControl otherMeetingControl; + + public bool DragIsHandled { get; set; } + + public bool ForceDragged { get; set; } public override void _Ready() { @@ -25,34 +29,69 @@ public partial class MeetingControl : Control SetDragPreview(preview); Visible = false; - InSlot = false; + DragIsHandled = false; + ForceDragged = false; return Variant.From(new MeetingControlDragData(this)); } + public override bool _CanDropData(Vector2 atPosition, Variant data) + { + return data.VariantType == Variant.Type.Object + && data.AsGodotObject() is MeetingControlDragData; + } + + public override void _DropData(Vector2 atPosition, Variant data) + { + var meetingData = (MeetingControlDragData)data; + + otherMeetingControl = meetingData.MeetingControl; + var otherParent = otherMeetingControl.GetParent(); + + otherMeetingControl.Reparent(GetParent(), false); + Reparent(otherParent, false); + + otherMeetingControl.Visible = true; + otherMeetingControl.DragIsHandled = true; + + if (otherMeetingControl.ForceDragged) + { + RespawnPhysicsBoxFromSpawn(); + otherMeetingControl.ForceDragged = false; + } + } + public void StartDrag() { var preview = CreatePreview(); var data = Variant.From(new MeetingControlDragData(this)); ForceDrag(data, preview); + + DragIsHandled = false; + ForceDragged = true; } public override void _Notification(int what) { + // Notfall respawn if (what == NotificationDragEnd) { - if (InSlot) - { + if (DragIsHandled) return; - } - FindParent("Main").AddChild(MeetingPhysicsBox); - MeetingPhysicsBox.Position = GetGlobalMousePosition(); - QueueFree(); + RespawnPhysicsBoxFromSpawn(); } } + private void RespawnPhysicsBoxFromSpawn() + { + var main = (Main)FindParent("Main"); + main.AddChild(MeetingPhysicsBox); + MeetingPhysicsBox.Position = main.MeetingSpawn.GlobalPosition; + QueueFree(); + } + private Control CreatePreview() { var copy = Duplicate() as MeetingControl; diff --git a/MeetingControl.tscn b/MeetingControl.tscn index dcaf095..41d53f5 100644 --- a/MeetingControl.tscn +++ b/MeetingControl.tscn @@ -5,13 +5,31 @@ [node name="MeetingControl" type="Control" unique_id=778678487] layout_mode = 3 -anchors_preset = 0 -offset_right = 206.0 -offset_bottom = 54.0 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -103.0 +offset_top = -27.0 +offset_right = 103.0 +offset_bottom = 27.0 +grow_horizontal = 2 +grow_vertical = 2 script = ExtResource("1_o5h3n") [node name="MeetingControlGfx" parent="." unique_id=1923695250 instance=ExtResource("1_o8u20")] unique_name_in_owner = true -layout_mode = 0 -offset_right = 206.0 +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -103.0 +offset_top = -27.0 +offset_right = 103.0 +offset_bottom = 27.0 +grow_horizontal = 2 +grow_vertical = 2 mouse_filter = 2 diff --git a/MeetingControlGfx.tscn b/MeetingControlGfx.tscn index ccdc5a9..3874270 100644 --- a/MeetingControlGfx.tscn +++ b/MeetingControlGfx.tscn @@ -3,6 +3,9 @@ [ext_resource type="Script" uid="uid://cxbjuwkso3fro" path="res://MeetingControlGfx.cs" id="1_ad8oc"] [ext_resource type="Texture2D" uid="uid://dyxftkkuf7h7w" path="res://icon.svg" id="1_vkyb6"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ad8oc"] +bg_color = Color(0.20152655, 0.20152661, 0.20152646, 1) + [sub_resource type="LabelSettings" id="LabelSettings_vkyb6"] line_spacing = -4.0 font_size = 12 @@ -11,6 +14,7 @@ font_size = 12 offset_right = 250.0 offset_bottom = 54.0 size_flags_horizontal = 3 +theme_override_styles/panel = SubResource("StyleBoxFlat_ad8oc") script = ExtResource("1_ad8oc") [node name="MarginContainer" type="MarginContainer" parent="." unique_id=2076398338] diff --git a/MeetingPhysicsBox.cs b/MeetingPhysicsBox.cs index db769af..5277245 100644 --- a/MeetingPhysicsBox.cs +++ b/MeetingPhysicsBox.cs @@ -3,12 +3,13 @@ using Godot; [SceneTree] public partial class MeetingPhysicsBox : RigidBody2D { - [Export] - public MeetingResource MeetingResource { get; set; } = new DummyMeetingResource(); + private Vector2 _dragTarget; + private bool _isDragging; private bool _mouseInside; - private bool _isDragging; - private Vector2 _dragTarget; + + [Export] + public MeetingResource MeetingResource { get; set; } = new DummyMeetingResource(); public override void _Ready() { @@ -34,16 +35,12 @@ public partial class MeetingPhysicsBox : RigidBody2D using (@event) { if (@event is InputEventMouse mouseEvent) - { if (_mouseInside) - { if (mouseEvent.IsPressed() && mouseEvent.ButtonMask == MouseButtonMask.Left) { GD.Print("Start Dragging"); StartDragging(); } - } - } } } @@ -80,5 +77,6 @@ public partial class MeetingPhysicsBox : RigidBody2D meetingControl.Position = new Vector2(-5000, -5000); GetParent().RemoveChild(this); + _mouseInside = false; } } diff --git a/TimeSlot.cs b/TimeSlot.cs index f8beec8..499a376 100644 --- a/TimeSlot.cs +++ b/TimeSlot.cs @@ -1,12 +1,12 @@ using Godot; +[SceneTree] public partial class TimeSlot : PanelContainer { public MeetingControl MeetingControl { get; set; } public override bool _CanDropData(Vector2 atPosition, Variant data) { - GD.Print("DRAGGED OVERR!!!"); return data.VariantType == Variant.Type.Object && data.AsGodotObject() is MeetingControlDragData; } @@ -16,21 +16,18 @@ public partial class TimeSlot : PanelContainer var meetingData = (MeetingControlDragData)data; MeetingControl = meetingData.MeetingControl; - meetingData.MeetingControl.InSlot = true; MeetingControl.Reparent(this, false); MeetingControl.Visible = true; + + meetingData.MeetingControl.DragIsHandled = true; } public override void _Notification(int what) { if (what == NotificationDragBegin) - { MouseFilter = MouseFilterEnum.Pass; - } if (what == NotificationDragEnd) - { MouseFilter = MouseFilterEnum.Ignore; - } } } diff --git a/TimeSlot.tscn b/TimeSlot.tscn index 06282ee..45826fa 100644 --- a/TimeSlot.tscn +++ b/TimeSlot.tscn @@ -2,9 +2,14 @@ [ext_resource type="Script" uid="uid://dldaxqajhnnva" path="res://TimeSlot.cs" id="1_50jir"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_cm0pq"] +bg_color = Color(0.39060682, 0.37537947, 0.313594, 1) +border_color = Color(0, 0, 0, 0.16078432) + [node name="TimeSlot" type="PanelContainer" unique_id=979842204] custom_minimum_size = Vector2(206, 54) offset_right = 206.0 offset_bottom = 54.0 mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_cm0pq") script = ExtResource("1_50jir") diff --git a/addons/rider-plugin/CONTRIBUTING.md b/addons/rider-plugin/CONTRIBUTING.md new file mode 100644 index 0000000..45f104b --- /dev/null +++ b/addons/rider-plugin/CONTRIBUTING.md @@ -0,0 +1,33 @@ +# Contribution + +Hello, thanks for taking time and helping out with the addon! + +Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. Please sign the CLA before sending the PR: https://www.jetbrains.com/agreements/cla/. + +#### Local setup + +Open the `godot-editor-addon/CMakeLists.txt` in Rider 2026.1+, select `rider-gdextension` target in the run configuration selector. +There are some more fixes coming in 2026.2, which will allow working on gdscript and cpp files within the same workspace. + +#### Signing the binaries + +Plugin binaries need to be signed to comply with modern operating system security requirements. Unsigned dynamic libraries may fail to load or trigger security warnings: + +- **macOS**: Requires code signing (and often notarization) for `.dylib` files. Unsigned libraries may simply fail to load. +- **Windows**: SmartScreen may block unsigned binaries, and corporate environments often enforce signed code only. +- **Linux**: Generally allows unsigned `.so` files, but some sandboxed environments (Flatpak, Snap) impose restrictions. + +**How signing is implemented:** + +1. **TeamCity Configuration**: [ijplatform_master_Net_Deploy_Plugins_Public_Godot](https://buildserver.labs.intellij.net/buildConfiguration/ijplatform_master_Net_Deploy_Plugins_Public_Godot) (internal JetBrains link) + - Note: The automatic trigger on new tags is currently not working, so manual triggering is required. + +2. **Release Process**: + - First, use your GitHub Action to prepare a **pre-release** with a tag + - Manually trigger the TeamCity configuration on the necessary branch/tag + - The configuration will download assets, sign them, and upload them back (removing the pre-release flag) + - The pre-release flag is required at the start; otherwise, the signing configuration will skip the release (protection against double signing) + +3. **Signing existing releases**: + - You can run signing on already existing old releases/tags + - Mark them as pre-release first, then run the configuration on the necessary tag diff --git a/addons/rider-plugin/LICENCE b/addons/rider-plugin/LICENCE new file mode 100644 index 0000000..f1f8c07 --- /dev/null +++ b/addons/rider-plugin/LICENCE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 JetBrains + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/addons/rider-plugin/README.md b/addons/rider-plugin/README.md new file mode 100644 index 0000000..51b6fb3 --- /dev/null +++ b/addons/rider-plugin/README.md @@ -0,0 +1,51 @@ +# JetBrains Rider Integration – Godot addon + +This addon currently provides two features: +1. Finds all Rider installations in the system and provides a selector on the `Text Editor` -> `External` tab in the settings to select one. +2. Provides the "Use Rider" toggle in the Godot toolbar and, when enabled, applies a set of editor settings recommended for working with JetBrains Rider. The goal is to make it trivial to switch between Rider‑optimized settings and stock Godot settings with a single click. + +## Quick start + +Requirements: +- Godot 4.5+ + +Install: +1. Inside the Godot editor, it can be installed from the AssetLib view or [downloaded](https://godotengine.org/asset-library/asset/4576) +2. [Optional] Change the initial value of `active` in the plugin.cfg +3. [Optional] Change the initial values in the presets.json file. +4. Enable "JetBrains Rider External Editor" plugin in the Project → Project Settings… → Plugins tab. + +Use: +- A toolbar toggle named "Use Rider" will appear. Click it to turn the preset On/Off. + +Screenshot: +![Toolbar toggle](screenshots/Toolbar.png) + +## What the toggle changes + +The preset values live in `presets.json`. + +When ON: +- Write the values from the "on" preset into the Editor Settings. + +When OFF: +- Write the values from the "off" preset into the Editor Settings. + +Note: The plugin does not currently auto‑set Rider’s executable path or flags. See Plans below. + +## Setting Rider to be the external editor + +The plugin automatically detects installed Rider versions on your system and provides a convenient dropdown menu to +select which installation to use as your external editor. + +- The plugin scans common installation locations for Rider on Windows, macOS, and Linux. +- Detected installations appear in the "Select Rider" dropdown in the toolbar. +- When you select a Rider installation, the plugin automatically updates the `dotnet/editor/external_editor_path` editor + setting. + +## License +See `addons/rider-plugin/LICENCE`. + +## Acknowledgements +Created by JetBrains to streamline using Rider with Godot. +Initial idea https://github.com/sszigeti/toggle_external_editor diff --git a/addons/rider-plugin/bin/linux/librider-gdextension.linux.editor.arm64.so b/addons/rider-plugin/bin/linux/librider-gdextension.linux.editor.arm64.so new file mode 100644 index 0000000..17edcec Binary files /dev/null and b/addons/rider-plugin/bin/linux/librider-gdextension.linux.editor.arm64.so differ diff --git a/addons/rider-plugin/bin/linux/librider-gdextension.linux.editor.x86_64.so b/addons/rider-plugin/bin/linux/librider-gdextension.linux.editor.x86_64.so new file mode 100644 index 0000000..7730052 Binary files /dev/null and b/addons/rider-plugin/bin/linux/librider-gdextension.linux.editor.x86_64.so differ diff --git a/addons/rider-plugin/bin/macos/librider-gdextension.macos.editor.dylib b/addons/rider-plugin/bin/macos/librider-gdextension.macos.editor.dylib new file mode 100644 index 0000000..604f726 Binary files /dev/null and b/addons/rider-plugin/bin/macos/librider-gdextension.macos.editor.dylib differ diff --git a/addons/rider-plugin/bin/rider-plugin.gdextension b/addons/rider-plugin/bin/rider-plugin.gdextension new file mode 100644 index 0000000..57755d8 --- /dev/null +++ b/addons/rider-plugin/bin/rider-plugin.gdextension @@ -0,0 +1,16 @@ +[configuration] + +entry_symbol = "rider_library_init" +compatibility_minimum = "4.5.0" + +[libraries] + +macos.single.debug = "./macos/librider-gdextension.macos.editor.dylib" + +windows.arm64.single.debug = "./windows/rider-gdextension.windows.editor.arm64.dll" + +windows.x86_64.single.debug = "./windows/rider-gdextension.windows.editor.x86_64.dll" + +linux.x86_64.single.debug = "./linux/librider-gdextension.linux.editor.x86_64.so" + +linux.arm64.single.debug = "./linux/librider-gdextension.linux.editor.arm64.so" \ No newline at end of file diff --git a/addons/rider-plugin/bin/rider-plugin.gdextension.uid b/addons/rider-plugin/bin/rider-plugin.gdextension.uid new file mode 100644 index 0000000..e69de29 diff --git a/addons/rider-plugin/bin/windows/rider-gdextension.windows.editor.x86_64.dll b/addons/rider-plugin/bin/windows/rider-gdextension.windows.editor.x86_64.dll new file mode 100644 index 0000000..66397c2 Binary files /dev/null and b/addons/rider-plugin/bin/windows/rider-gdextension.windows.editor.x86_64.dll differ diff --git a/addons/rider-plugin/bin/windows/~rider-gdextension.windows.editor.x86_64.dll b/addons/rider-plugin/bin/windows/~rider-gdextension.windows.editor.x86_64.dll new file mode 100644 index 0000000..66397c2 Binary files /dev/null and b/addons/rider-plugin/bin/windows/~rider-gdextension.windows.editor.x86_64.dll differ diff --git a/addons/rider-plugin/icons/icon.svg b/addons/rider-plugin/icons/icon.svg new file mode 100644 index 0000000..04cb843 --- /dev/null +++ b/addons/rider-plugin/icons/icon.svg @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/rider-plugin/icons/icon.svg.import b/addons/rider-plugin/icons/icon.svg.import new file mode 100644 index 0000000..05cbbf5 --- /dev/null +++ b/addons/rider-plugin/icons/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://wrdrj6wednn8" +path="res://.godot/imported/icon.svg-45c914cff7482ba9564963fe65b548e4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/rider-plugin/icons/icon.svg" +dest_files=["res://.godot/imported/icon.svg-45c914cff7482ba9564963fe65b548e4.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/rider-plugin/plugin.cfg b/addons/rider-plugin/plugin.cfg new file mode 100644 index 0000000..5a4ada1 --- /dev/null +++ b/addons/rider-plugin/plugin.cfg @@ -0,0 +1,12 @@ +[plugin] + +name="JetBrains Rider External Editor" +description="Provides a toolbar toggle, to switch a set of settings on and off. Default set of settings helps to enable/disable the following settings recommended by the Rider documentation https://www.jetbrains.com/help/rider/Godot.html#optimize-godot-editor-for-rider" +author="JetBrains" +version="v1.3.0" +script="rider-plugin.gd" + +[presets] + +active="on" +presets="presets.json" diff --git a/addons/rider-plugin/presets.json b/addons/rider-plugin/presets.json new file mode 100644 index 0000000..5e38bf3 --- /dev/null +++ b/addons/rider-plugin/presets.json @@ -0,0 +1,15 @@ +{ + "on": { + "text_editor/external/use_external_editor": true, + "interface/editor/import_resources_when_unfocused": true, + "interface/editor/save_on_focus_loss": true, + "text_editor/behavior/files/auto_reload_scripts_on_external_change": true, + "run/window_placement/game_embed_mode": -1 + }, + "off": { + "text_editor/external/use_external_editor": false, + "interface/editor/import_resources_when_unfocused": false, + "interface/editor/save_on_focus_loss": false, + "text_editor/behavior/files/auto_reload_scripts_on_external_change": false + } +} diff --git a/addons/rider-plugin/rider-plugin.gd b/addons/rider-plugin/rider-plugin.gd new file mode 100644 index 0000000..f2587dd --- /dev/null +++ b/addons/rider-plugin/rider-plugin.gd @@ -0,0 +1,78 @@ +@tool +extends EditorPlugin + +var editor_settings: EditorSettings +var checkbutton: CheckButton +var _preset_applier: PresetApplier +var _locator_service: RiderLocatorService +var _plugin_cfg_path: String +var _presets_json_path: String + +func _enter_tree() -> void: + editor_settings = EditorInterface.get_editor_settings() + var script_path := (get_script() as Script).resource_path + var plugin_dir := script_path.get_base_dir() + _plugin_cfg_path = plugin_dir + "/plugin.cfg" + + _write_godot_editor_cfg() + + var cfg := ConfigFile.new() + var err := cfg.load(_plugin_cfg_path) + if err != OK: + push_warning("Failed to load plugin.cfg: %s" % [err]) + return + var active_str := str(cfg.get_value("presets", "active", "on")) + var is_active := active_str == "on" + var presets_rel_path := str(cfg.get_value("presets", "presets", "presets.json")) + _presets_json_path = plugin_dir + "/" + presets_rel_path + + # Build UI + checkbutton = CheckButton.new() + checkbutton.text = "Use Rider" + checkbutton.tooltip_text = "Shortcut for setting recommended settings" + checkbutton.button_pressed = is_active + checkbutton.pressed.connect(_on_checkbutton_pressed) + add_control_to_container(EditorPlugin.CONTAINER_TOOLBAR, checkbutton) + + # Initialize services and panel + _locator_service = RiderLocatorService.new() + _preset_applier = PresetApplier.new(_presets_json_path) + + _locator_service.start_search() + + # Ensure settings reflect current state on startup + _preset_applier.apply_preset(editor_settings, is_active) + +func _on_checkbutton_pressed() -> void: + var cfg := ConfigFile.new() + if cfg.load(_plugin_cfg_path) != OK: + push_warning("Failed to load plugin.cfg to update state") + return + var is_active := checkbutton.button_pressed + var key := _preset_applier.get_preset_key(is_active) + cfg.set_value("presets", "active", key) + var save_err := cfg.save(_plugin_cfg_path) + if save_err != OK: + push_warning("Failed to save plugin.cfg: %s" % [save_err]) + # Apply selected preset to editor settings + _preset_applier.apply_preset(editor_settings, is_active) + +func _exit_tree() -> void: + EditorSettingsUtil.erase_rider_external_editor_setting() + if checkbutton != null: + remove_control_from_container(EditorPlugin.CONTAINER_TOOLBAR, checkbutton) + checkbutton.queue_free() + + var args := OS.get_cmdline_args() + if "--rider-addon-tests" in args: + print("==== rider-addon-tests finished ====") + +func _write_godot_editor_cfg() -> void: + var settings_dir := EditorInterface.get_editor_paths().get_project_settings_dir() + var cfg_path := settings_dir.path_join("rider_addon_godot_editor.cfg") + var cfg := ConfigFile.new() + cfg.set_value("editor_metadata", "process_id", OS.get_process_id()) + cfg.set_value("editor_metadata", "executable_path", OS.get_executable_path()) + var err := cfg.save(cfg_path) + if err != OK: + push_warning("Failed to save rider_addon_godot_editor.cfg: %s" % [err]) diff --git a/addons/rider-plugin/rider-plugin.gd.uid b/addons/rider-plugin/rider-plugin.gd.uid new file mode 100644 index 0000000..80edc2b --- /dev/null +++ b/addons/rider-plugin/rider-plugin.gd.uid @@ -0,0 +1 @@ +uid://c1x58xm2w1n20 diff --git a/addons/rider-plugin/screenshots/Toolbar.png b/addons/rider-plugin/screenshots/Toolbar.png new file mode 100644 index 0000000..51c2617 Binary files /dev/null and b/addons/rider-plugin/screenshots/Toolbar.png differ diff --git a/addons/rider-plugin/screenshots/Toolbar.png.import b/addons/rider-plugin/screenshots/Toolbar.png.import new file mode 100644 index 0000000..94f74e7 --- /dev/null +++ b/addons/rider-plugin/screenshots/Toolbar.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ci3pvmb68i8lh" +path="res://.godot/imported/Toolbar.png-a521e2493bd3c08a829245b3129bb58f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/rider-plugin/screenshots/Toolbar.png" +dest_files=["res://.godot/imported/Toolbar.png-a521e2493bd3c08a829245b3129bb58f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/rider-plugin/scripts/editor_settings_util.gd b/addons/rider-plugin/scripts/editor_settings_util.gd new file mode 100644 index 0000000..0af18fb --- /dev/null +++ b/addons/rider-plugin/scripts/editor_settings_util.gd @@ -0,0 +1,66 @@ +@tool +class_name EditorSettingsUtil + +# this is rider own setting, not a part of Godot settings +const EXTERNAL_EDITOR_SETTING: String = "text_editor/external/editor" +# this is Godot setting +const EXEC_PATH_SETTING: String = "text_editor/external/exec_path" + + +static func set_external_editor_path(path: String) -> void: + var editor_settings := EditorInterface.get_editor_settings() + editor_settings.set_setting(EXEC_PATH_SETTING, path) + +static func get_external_editor_path() -> String: + var editor_settings := EditorInterface.get_editor_settings() + if editor_settings.has_setting(EXEC_PATH_SETTING): + return editor_settings.get_setting(EXEC_PATH_SETTING) + else: + return "" + +# Returns the current dropdown index, 0 if the setting doesn't exist. +static func get_rider_selector_index() -> int: + var editor_settings := EditorInterface.get_editor_settings() + if not editor_settings.has_setting(EXTERNAL_EDITOR_SETTING): + return 0 + return editor_settings.get_setting(EXTERNAL_EDITOR_SETTING) + +static func erase_rider_external_editor_setting() -> void: + var editor_settings := EditorInterface.get_editor_settings() + if editor_settings.has_setting(EXTERNAL_EDITOR_SETTING): + editor_settings.erase(EXTERNAL_EDITOR_SETTING) + +# Register a single-entry enum so the persisted int doesn't render as a raw +# number while async detection is in progress. register_rider_installations +# replaces this once detection finishes. +static func show_rider_searching_state() -> void: + # Order matters: `set` must come before `add_property_info` — the latter + # errors with `!props.has(pinfo.name)` if the property isn't in `props` yet. + var editor_settings := EditorInterface.get_editor_settings() + editor_settings.set(EXTERNAL_EDITOR_SETTING, 0) + editor_settings.add_property_info({ + "name": EXTERNAL_EDITOR_SETTING, + "type": TYPE_INT, + "hint": PROPERTY_HINT_ENUM, + "hint_string": "Searching — reopen Settings to see the update", + }) + +# Register the dropdown with one entry per detected installation (plus a "-" +# placeholder at index 0) and select the given index. +static func register_rider_installations(installations: Array, selected_index: int) -> void: + var editor_settings := EditorInterface.get_editor_settings() + var entries: Array = ["-"] + for element in installations: + var display_name: String = element.get("display", "") + entries.append(_escape_enum_label(display_name)) + editor_settings.set(EXTERNAL_EDITOR_SETTING, selected_index) + editor_settings.add_property_info({ + "name": EXTERNAL_EDITOR_SETTING, + "type": TYPE_INT, + "hint": PROPERTY_HINT_ENUM, + "hint_string": ",".join(entries), + }) + +# Comma is the enum delimiter, colon introduces explicit value assignment. +static func _escape_enum_label(s: String) -> String: + return s.replace(",", " •").replace(":", " -") \ No newline at end of file diff --git a/addons/rider-plugin/scripts/editor_settings_util.gd.uid b/addons/rider-plugin/scripts/editor_settings_util.gd.uid new file mode 100644 index 0000000..3f50ddc --- /dev/null +++ b/addons/rider-plugin/scripts/editor_settings_util.gd.uid @@ -0,0 +1 @@ +uid://bdiu78ot0rrkc diff --git a/addons/rider-plugin/scripts/json_utils.gd b/addons/rider-plugin/scripts/json_utils.gd new file mode 100644 index 0000000..660086b --- /dev/null +++ b/addons/rider-plugin/scripts/json_utils.gd @@ -0,0 +1,23 @@ +@tool +## Simple JSON helpers for editor/runtime use. +## Keeps file and JSON parsing concerns out of feature code. +class_name JsonUtils + +static func load_from_file(path: String) -> Variant: + # Returns parsed JSON value (Dictionary/Array/etc.) or null on error. + var file := FileAccess.open(path, FileAccess.READ) + if file == null: + push_warning("JsonUtils: Failed to open file: %s" % path) + return null + var text := file.get_as_text() + file.close() + var data: Variant = JSON.parse_string(text) + if data == null: + push_warning("JsonUtils: Invalid JSON in file: %s" % path) + return null + return data + +static func load_dict_from_file(path: String) -> Dictionary: + # Returns Dictionary or empty {} on error. + var data := load_from_file(path) as Dictionary + return data diff --git a/addons/rider-plugin/scripts/json_utils.gd.uid b/addons/rider-plugin/scripts/json_utils.gd.uid new file mode 100644 index 0000000..e780a44 --- /dev/null +++ b/addons/rider-plugin/scripts/json_utils.gd.uid @@ -0,0 +1 @@ +uid://bci4kmk7h4j6a diff --git a/addons/rider-plugin/scripts/locator/rider_locator_service.gd b/addons/rider-plugin/scripts/locator/rider_locator_service.gd new file mode 100644 index 0000000..45c1187 --- /dev/null +++ b/addons/rider-plugin/scripts/locator/rider_locator_service.gd @@ -0,0 +1,68 @@ +@tool +extends RefCounted +class_name RiderLocatorService + +var _installations_found: Array = [] +# we can keep a reference, it will be freed automatically, when the editor is closed +var _rider_locator: RefCounted = null + +# Last value we wrote to / observed for the Rider selector dropdown +var _last_selected_index: int = 0 + +func start_search() -> void: + # use ClassDB to somehow still work without GDExtension part (in older Godot versions) + if not ClassDB.class_exists("RiderLocator"): + return + + EditorSettingsUtil.show_rider_searching_state() + if _rider_locator == null: + _rider_locator = ClassDB.instantiate("RiderLocator") + _rider_locator.connect("installations_loaded", _on_installations_loaded) + _rider_locator.start_search() + +func _on_installations_loaded(array: Array) -> void: + _installations_found = array + _update_selector() + +func _update_selector() -> void: + if _installations_found.is_empty(): + EditorSettingsUtil.erase_rider_external_editor_setting() + return + + var index := _index_for_exec_path(_installations_found) + # Set _last_selected_index BEFORE register_rider_installations so the + # synchronous settings_changed handler sees a match and skips its work. + _last_selected_index = index + EditorSettingsUtil.register_rider_installations(_installations_found, index) + + var settings_changed := EditorInterface.get_editor_settings().settings_changed + if not settings_changed.is_connected(_on_selection_changed): + settings_changed.connect(_on_selection_changed) + +func _index_for_exec_path(installations: Array) -> int: + var current := EditorSettingsUtil.get_external_editor_path() + if current.is_empty(): + return 0 + for i in installations.size(): + if installations[i].get("path", "") == current: + return i + 1 + return 0 + +func _on_selection_changed() -> void: + var selected_index := EditorSettingsUtil.get_rider_selector_index() + + # settings_changed fires for every editor setting, this helps to avoid updating on every other changes + if selected_index == _last_selected_index: + return + _last_selected_index = selected_index + + # Index 0 is the placeholder, so the path is left untouched. + if selected_index == 0: + return + + var installation_index := selected_index - 1 + if installation_index >= 0 and installation_index < _installations_found.size(): + var installation = _installations_found[installation_index] + var new_path: String = installation.get("path", "") + if not new_path.is_empty(): + EditorSettingsUtil.set_external_editor_path(new_path) diff --git a/addons/rider-plugin/scripts/locator/rider_locator_service.gd.uid b/addons/rider-plugin/scripts/locator/rider_locator_service.gd.uid new file mode 100644 index 0000000..f7fcdaf --- /dev/null +++ b/addons/rider-plugin/scripts/locator/rider_locator_service.gd.uid @@ -0,0 +1 @@ +uid://cfsu1rbg0ypem diff --git a/addons/rider-plugin/scripts/presets/preset_applier.gd b/addons/rider-plugin/scripts/presets/preset_applier.gd new file mode 100644 index 0000000..b09d025 --- /dev/null +++ b/addons/rider-plugin/scripts/presets/preset_applier.gd @@ -0,0 +1,35 @@ +@tool +extends RefCounted +class_name PresetApplier + +var presets_path: String + +func _init(p_path: String) -> void: + presets_path = p_path + +func get_preset_key(is_active: bool) -> String: + return "on" if is_active else "off" + +func apply_preset(editor_settings: EditorSettings, is_active: bool) -> void: + var data: Dictionary = JsonUtils.load_dict_from_file(presets_path) + if data.is_empty(): + push_warning("Failed to load presets: %s" % presets_path) + return + + var new_preset_key := get_preset_key(is_active) + var previous_preset_key := get_preset_key(not is_active) + + if not data.has(new_preset_key): + push_warning("Preset '%s' not found in presets.json" % new_preset_key) + return + + var new_preset := data[new_preset_key] as Dictionary + # Reset keys from previous preset that are missing in the new preset + if data.has(previous_preset_key): + var previous_preset := data[previous_preset_key] as Dictionary + for key in previous_preset: + if not new_preset.has(key): + editor_settings.set_setting(str(key), editor_settings.property_get_revert(str(key))) + # Apply the new preset + for key in new_preset: + editor_settings.set_setting(str(key), new_preset[key]) diff --git a/addons/rider-plugin/scripts/presets/preset_applier.gd.uid b/addons/rider-plugin/scripts/presets/preset_applier.gd.uid new file mode 100644 index 0000000..af4fdde --- /dev/null +++ b/addons/rider-plugin/scripts/presets/preset_applier.gd.uid @@ -0,0 +1 @@ +uid://bjiaycxso8h8u diff --git a/project.godot b/project.godot index 2fbb64d..d8692df 100644 --- a/project.godot +++ b/project.godot @@ -24,6 +24,10 @@ window/stretch/aspect="expand" project/assembly_name="your are an ai ceo" +[editor_plugins] + +enabled=PackedStringArray("res://addons/rider-plugin/plugin.cfg") + [physics] 2d/run_on_separate_thread=true diff --git a/resources/meetings/coffee_meeting.tres b/resources/meetings/coffee_meeting.tres index a0015bd..72ad40d 100644 --- a/resources/meetings/coffee_meeting.tres +++ b/resources/meetings/coffee_meeting.tres @@ -5,5 +5,5 @@ [resource] script = ExtResource("1_s1cac") Title = "Coffee Break" -Color = Color(0.2210013, 0.40685424, 0.8183415, 1) +Color = Color(0.31983396, 0.4835437, 0.33250993, 1) metadata/_custom_type_script = "uid://cuq38lbfa2v74" diff --git a/resources/meetings/lockin.tres b/resources/meetings/lockin.tres new file mode 100644 index 0000000..eea9800 --- /dev/null +++ b/resources/meetings/lockin.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="MeetingResource" format=3 uid="uid://du72uxjqr0h4a"] + +[ext_resource type="Script" uid="uid://cuq38lbfa2v74" path="res://resources/MeetingResource.cs" id="1_4yd4m"] + +[resource] +script = ExtResource("1_4yd4m") +Title = "LOCK IN" +Color = Color(0.73206806, 0.22440341, 0.33911285, 1) +metadata/_custom_type_script = "uid://cuq38lbfa2v74" diff --git a/resources/meetings/work_product_1.tres b/resources/meetings/work_product_1.tres new file mode 100644 index 0000000..5950a94 --- /dev/null +++ b/resources/meetings/work_product_1.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="MeetingResource" format=3 uid="uid://bcd4qf4i84pwf"] + +[ext_resource type="Script" uid="uid://cuq38lbfa2v74" path="res://resources/MeetingResource.cs" id="1_qndny"] + +[resource] +script = ExtResource("1_qndny") +Title = "Work on your Product" +Color = Color(0.4354798, 0.3262509, 0.83488727, 1) +metadata/_custom_type_script = "uid://cuq38lbfa2v74" diff --git a/your are an ai ceo.csproj b/your are an ai ceo.csproj index 9898140..c939901 100644 --- a/your are an ai ceo.csproj +++ b/your are an ai ceo.csproj @@ -3,7 +3,7 @@ net8.0 net9.0 true - yourareanaiceo + AiCeo diff --git a/your are an ai ceo.sln.DotSettings.user b/your are an ai ceo.sln.DotSettings.user new file mode 100644 index 0000000..453246d --- /dev/null +++ b/your are an ai ceo.sln.DotSettings.user @@ -0,0 +1,2 @@ + + ForceIncluded \ No newline at end of file