alter vatter

This commit is contained in:
2026-07-29 18:50:14 +02:00
parent 59a9516d99
commit 9824b30435
53 changed files with 1054 additions and 69 deletions

View File

@@ -3,7 +3,7 @@
<CLASSES /> <CLASSES />
<JAVADOC /> <JAVADOC />
<SOURCES> <SOURCES>
<root url="file://$APPLICATION_PLUGINS_DIR$/GdScript/extracted/Master" /> <root url="file://$APPLICATION_PLUGINS_DIR$/Godot/extracted/4.7" />
</SOURCES> </SOURCES>
</library> </library>
</component> </component>

27
Company.cs Normal file
View File

@@ -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;
/// <summary>
/// Cost per Quarter
/// </summary>
public float Cost => Workers * AverageSalary;
/// <summary>
/// Runway in Quarters
/// </summary>
public int Runway => Mathf.FloorToInt(Money / Cost);
}

1
Company.cs.uid Normal file
View File

@@ -0,0 +1 @@
uid://cxr0qf8ut8t4p

16
CurrentTimeLine.cs Normal file
View File

@@ -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;
}
}

1
CurrentTimeLine.cs.uid Normal file
View File

@@ -0,0 +1 @@
uid://cbbrups0mkp17

24
DaySchedule.cs Normal file
View File

@@ -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<TimeSlot>();
TimeSlotContainer.AddChild(timeSlot);
}
}
}

1
DaySchedule.cs.uid Normal file
View File

@@ -0,0 +1 @@
uid://xv51uvc4koyc

93
DaySchedule.tscn Normal file
View File

@@ -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")

9
DoubleExtensions.cs Normal file
View File

@@ -0,0 +1,9 @@
namespace yourareanaiceo;
public static class DoubleExtensions
{
public static float toFloat(this double value)
{
return (float)value;
}
}

1
DoubleExtensions.cs.uid Normal file
View File

@@ -0,0 +1 @@
uid://dtfiuvcat531i

32
DropZone.cs Normal file
View File

@@ -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;
}
}

1
DropZone.cs.uid Normal file
View File

@@ -0,0 +1 @@
uid://bs531c76ivhtf

4
Main.cs Normal file
View File

@@ -0,0 +1,4 @@
using Godot;
[SceneTree]
public partial class Main : Node2D { }

1
Main.cs.uid Normal file
View File

@@ -0,0 +1 @@
uid://d1h0qvskvk1wu

117
Main.tscn
View File

@@ -1,8 +1,12 @@
[gd_scene format=3 uid="uid://b2rl7r8oav3hy"] [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://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://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"] [sub_resource type="LabelSettings" id="LabelSettings_sko1m"]
font_size = 64 font_size = 64
@@ -12,8 +16,6 @@ stacked_outline_0/size = 9
stacked_shadow_0/offset = Vector2(4, 4) stacked_shadow_0/offset = Vector2(4, 4)
stacked_shadow_0/outline_size = 2 stacked_shadow_0/outline_size = 2
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_50jir"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_sko1m"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_sko1m"]
size = Vector2(727.5, 20) size = Vector2(727.5, 20)
@@ -21,6 +23,12 @@ size = Vector2(727.5, 20)
size = Vector2(21.5, 1920) size = Vector2(21.5, 1920)
[node name="Main" type="Node2D" unique_id=287617203] [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] [node name="CanvasLayer" type="CanvasLayer" parent="." unique_id=1328071901]
@@ -53,57 +61,75 @@ grow_horizontal = 0
text = "Inbox" text = "Inbox"
label_settings = SubResource("LabelSettings_sko1m") label_settings = SubResource("LabelSettings_sko1m")
[node name="PanelContainer" type="PanelContainer" parent="." unique_id=1636973054] [node name="PanelContainer" type="FoldableContainer" parent="CanvasLayer/Control" unique_id=1121461524]
anchors_preset = 8 layout_mode = 1
anchor_left = 0.5 anchors_preset = 1
anchor_top = 0.5 anchor_left = 1.0
anchor_right = 0.5 anchor_right = 1.0
anchor_bottom = 0.5 offset_left = -245.0
offset_left = 96.0 offset_right = 4.535034
offset_top = 114.0 offset_bottom = 149.0
offset_right = 302.0 grow_horizontal = 0
offset_bottom = 574.0 title = "Your Company Inc."
grow_horizontal = 2 title_alignment = 1
grow_vertical = 2
mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_50jir")
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer" unique_id=1658498861] [node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/Control/PanelContainer" unique_id=1331001176]
layout_mode = 2
mouse_filter = 2
alignment = 1
[node name="TimeSlot" parent="PanelContainer/VBoxContainer" unique_id=979842204 instance=ExtResource("1_uu6xs")]
layout_mode = 2 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 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 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 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 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 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 layout_mode = 2
text = "1"
[node name="TimeSlot8" parent="PanelContainer/VBoxContainer" unique_id=2116243857 instance=ExtResource("1_uu6xs")] [node name="DaySchedule" parent="." unique_id=457829015 instance=ExtResource("1_r0du0")]
layout_mode = 2 offset_left = 106.0
offset_top = 117.0
[node name="TimeSlot9" parent="PanelContainer/VBoxContainer" unique_id=1672825401 instance=ExtResource("1_uu6xs")] offset_right = 320.0
visible = false offset_bottom = 571.0
layout_mode = 2
[node name="TimeSlot10" parent="PanelContainer/VBoxContainer" unique_id=488121571 instance=ExtResource("1_uu6xs")]
visible = false
layout_mode = 2
[node name="Box" type="StaticBody2D" parent="." unique_id=56956355] [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")] [node name="Meeting4" parent="." unique_id=1960552374 instance=ExtResource("1_glv2v")]
position = Vector2(707, -340) position = Vector2(707, -340)
rotation = 0.24779713 rotation = 0.24779713
MeetingResource = ExtResource("4_cm0pq")
[node name="Meeting5" parent="." unique_id=1692042144 instance=ExtResource("1_glv2v")] [node name="Meeting5" parent="." unique_id=1692042144 instance=ExtResource("1_glv2v")]
position = Vector2(851, -500) position = Vector2(851, -500)
rotation = 0.24779713 rotation = 0.24779713
MeetingResource = ExtResource("5_fos0i")
[node name="Meeting6" parent="." unique_id=2120697586 instance=ExtResource("1_glv2v")] [node name="Meeting6" parent="." unique_id=2120697586 instance=ExtResource("1_glv2v")]
position = Vector2(604, -619.99994) position = Vector2(604, -619.99994)
@@ -152,6 +180,7 @@ rotation = 0.24779713
[node name="Meeting9" parent="." unique_id=1055632102 instance=ExtResource("1_glv2v")] [node name="Meeting9" parent="." unique_id=1055632102 instance=ExtResource("1_glv2v")]
position = Vector2(614, -732.99994) position = Vector2(614, -732.99994)
rotation = 0.24779713 rotation = 0.24779713
MeetingResource = ExtResource("5_fos0i")
[node name="Meeting2" parent="." unique_id=1691479453 instance=ExtResource("1_glv2v")] [node name="Meeting2" parent="." unique_id=1691479453 instance=ExtResource("1_glv2v")]
position = Vector2(937, -352) position = Vector2(937, -352)
@@ -162,3 +191,13 @@ MeetingResource = ExtResource("3_r0du0")
position = Vector2(762.9999, -181.00012) position = Vector2(762.9999, -181.00012)
rotation = -0.18364333 rotation = -0.18364333
MeetingResource = ExtResource("3_r0du0") 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")

View File

@@ -11,7 +11,11 @@ public partial class MeetingControl : Control
[Export] [Export]
public MeetingPhysicsBox MeetingPhysicsBox; 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() public override void _Ready()
{ {
@@ -25,34 +29,69 @@ public partial class MeetingControl : Control
SetDragPreview(preview); SetDragPreview(preview);
Visible = false; Visible = false;
InSlot = false; DragIsHandled = false;
ForceDragged = false;
return Variant.From(new MeetingControlDragData(this)); 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() public void StartDrag()
{ {
var preview = CreatePreview(); var preview = CreatePreview();
var data = Variant.From(new MeetingControlDragData(this)); var data = Variant.From(new MeetingControlDragData(this));
ForceDrag(data, preview); ForceDrag(data, preview);
DragIsHandled = false;
ForceDragged = true;
} }
public override void _Notification(int what) public override void _Notification(int what)
{ {
// Notfall respawn
if (what == NotificationDragEnd) if (what == NotificationDragEnd)
{ {
if (InSlot) if (DragIsHandled)
{
return; return;
}
FindParent("Main").AddChild(MeetingPhysicsBox); RespawnPhysicsBoxFromSpawn();
MeetingPhysicsBox.Position = GetGlobalMousePosition();
QueueFree();
} }
} }
private void RespawnPhysicsBoxFromSpawn()
{
var main = (Main)FindParent("Main");
main.AddChild(MeetingPhysicsBox);
MeetingPhysicsBox.Position = main.MeetingSpawn.GlobalPosition;
QueueFree();
}
private Control CreatePreview() private Control CreatePreview()
{ {
var copy = Duplicate() as MeetingControl; var copy = Duplicate() as MeetingControl;

View File

@@ -5,13 +5,31 @@
[node name="MeetingControl" type="Control" unique_id=778678487] [node name="MeetingControl" type="Control" unique_id=778678487]
layout_mode = 3 layout_mode = 3
anchors_preset = 0 anchors_preset = 8
offset_right = 206.0 anchor_left = 0.5
offset_bottom = 54.0 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") script = ExtResource("1_o5h3n")
[node name="MeetingControlGfx" parent="." unique_id=1923695250 instance=ExtResource("1_o8u20")] [node name="MeetingControlGfx" parent="." unique_id=1923695250 instance=ExtResource("1_o8u20")]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 0 layout_mode = 1
offset_right = 206.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
mouse_filter = 2 mouse_filter = 2

View File

@@ -3,6 +3,9 @@
[ext_resource type="Script" uid="uid://cxbjuwkso3fro" path="res://MeetingControlGfx.cs" id="1_ad8oc"] [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"] [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"] [sub_resource type="LabelSettings" id="LabelSettings_vkyb6"]
line_spacing = -4.0 line_spacing = -4.0
font_size = 12 font_size = 12
@@ -11,6 +14,7 @@ font_size = 12
offset_right = 250.0 offset_right = 250.0
offset_bottom = 54.0 offset_bottom = 54.0
size_flags_horizontal = 3 size_flags_horizontal = 3
theme_override_styles/panel = SubResource("StyleBoxFlat_ad8oc")
script = ExtResource("1_ad8oc") script = ExtResource("1_ad8oc")
[node name="MarginContainer" type="MarginContainer" parent="." unique_id=2076398338] [node name="MarginContainer" type="MarginContainer" parent="." unique_id=2076398338]

View File

@@ -3,12 +3,13 @@ using Godot;
[SceneTree] [SceneTree]
public partial class MeetingPhysicsBox : RigidBody2D public partial class MeetingPhysicsBox : RigidBody2D
{ {
[Export] private Vector2 _dragTarget;
public MeetingResource MeetingResource { get; set; } = new DummyMeetingResource(); private bool _isDragging;
private bool _mouseInside; private bool _mouseInside;
private bool _isDragging;
private Vector2 _dragTarget; [Export]
public MeetingResource MeetingResource { get; set; } = new DummyMeetingResource();
public override void _Ready() public override void _Ready()
{ {
@@ -34,16 +35,12 @@ public partial class MeetingPhysicsBox : RigidBody2D
using (@event) using (@event)
{ {
if (@event is InputEventMouse mouseEvent) if (@event is InputEventMouse mouseEvent)
{
if (_mouseInside) if (_mouseInside)
{
if (mouseEvent.IsPressed() && mouseEvent.ButtonMask == MouseButtonMask.Left) if (mouseEvent.IsPressed() && mouseEvent.ButtonMask == MouseButtonMask.Left)
{ {
GD.Print("Start Dragging"); GD.Print("Start Dragging");
StartDragging(); StartDragging();
} }
}
}
} }
} }
@@ -80,5 +77,6 @@ public partial class MeetingPhysicsBox : RigidBody2D
meetingControl.Position = new Vector2(-5000, -5000); meetingControl.Position = new Vector2(-5000, -5000);
GetParent().RemoveChild(this); GetParent().RemoveChild(this);
_mouseInside = false;
} }
} }

View File

@@ -1,12 +1,12 @@
using Godot; using Godot;
[SceneTree]
public partial class TimeSlot : PanelContainer public partial class TimeSlot : PanelContainer
{ {
public MeetingControl MeetingControl { get; set; } public MeetingControl MeetingControl { get; set; }
public override bool _CanDropData(Vector2 atPosition, Variant data) public override bool _CanDropData(Vector2 atPosition, Variant data)
{ {
GD.Print("DRAGGED OVERR!!!");
return data.VariantType == Variant.Type.Object return data.VariantType == Variant.Type.Object
&& data.AsGodotObject() is MeetingControlDragData; && data.AsGodotObject() is MeetingControlDragData;
} }
@@ -16,21 +16,18 @@ public partial class TimeSlot : PanelContainer
var meetingData = (MeetingControlDragData)data; var meetingData = (MeetingControlDragData)data;
MeetingControl = meetingData.MeetingControl; MeetingControl = meetingData.MeetingControl;
meetingData.MeetingControl.InSlot = true;
MeetingControl.Reparent(this, false); MeetingControl.Reparent(this, false);
MeetingControl.Visible = true; MeetingControl.Visible = true;
meetingData.MeetingControl.DragIsHandled = true;
} }
public override void _Notification(int what) public override void _Notification(int what)
{ {
if (what == NotificationDragBegin) if (what == NotificationDragBegin)
{
MouseFilter = MouseFilterEnum.Pass; MouseFilter = MouseFilterEnum.Pass;
}
if (what == NotificationDragEnd) if (what == NotificationDragEnd)
{
MouseFilter = MouseFilterEnum.Ignore; MouseFilter = MouseFilterEnum.Ignore;
}
} }
} }

View File

@@ -2,9 +2,14 @@
[ext_resource type="Script" uid="uid://dldaxqajhnnva" path="res://TimeSlot.cs" id="1_50jir"] [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] [node name="TimeSlot" type="PanelContainer" unique_id=979842204]
custom_minimum_size = Vector2(206, 54) custom_minimum_size = Vector2(206, 54)
offset_right = 206.0 offset_right = 206.0
offset_bottom = 54.0 offset_bottom = 54.0
mouse_filter = 2 mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_cm0pq")
script = ExtResource("1_50jir") script = ExtResource("1_50jir")

View File

@@ -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

View File

@@ -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.

View File

@@ -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 Rideroptimized 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 autoset Riders 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

View File

@@ -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"

View File

@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version="1.0"
id="katman_1"
x="0px"
y="0px"
viewBox="0 0 512 512"
xml:space="preserve"
sodipodi:docname="JetBrains Rider Icon.svg"
width="512"
height="512"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs43" /><sodipodi:namedview
id="namedview41"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
showgrid="false"
inkscape:zoom="1.0980553"
inkscape:cx="256.36233"
inkscape:cy="212.19333"
inkscape:window-width="1920"
inkscape:window-height="1027"
inkscape:window-x="-8"
inkscape:window-y="22"
inkscape:window-maximized="1"
inkscape:current-layer="katman_1" />
<style
type="text/css"
id="style2">
.st0{fill:url(#SVGID_1_);}
.st1{fill:url(#SVGID_00000130622934180993703410000017420799098261276343_);}
.st2{fill:url(#SVGID_00000060739771362873723200000017991140373209755022_);}
.st3{fill:#FFFFFF;}
</style>
<symbol
id="rider"
viewBox="-35 -35 70 70">
<linearGradient
id="SVGID_1_"
gradientUnits="userSpaceOnUse"
x1="30.4897"
y1="5.1188998"
x2="-23.4683"
y2="-25.8451">
<stop
offset="0"
style="stop-color:#DD1265"
id="stop4" />
<stop
offset="0.483"
style="stop-color:#DD1265"
id="stop6" />
<stop
offset="0.942"
style="stop-color:#FDB60D"
id="stop8" />
</linearGradient>
<path
class="st0"
d="M 35,-7.7 -14.1,-35 18.8,13.9 25.5,9.5 Z"
id="path11" />
<linearGradient
id="SVGID_00000169517474296634577950000016895268102491994795_"
gradientUnits="userSpaceOnUse"
x1="-1.5839"
y1="-28.888"
x2="19.805099"
y2="30.174999">
<stop
offset="0.139"
style="stop-color:#087CFA"
id="stop13" />
<stop
offset="0.476"
style="stop-color:#DD1265"
id="stop15" />
<stop
offset="0.958"
style="stop-color:#087CFA"
id="stop17" />
</linearGradient>
<path
style="fill:url(#SVGID_00000169517474296634577950000016895268102491994795_)"
d="M 15.5,-18.9 9.3,-33.9 -4.3,-20.5 1.2,28.1 14.4,35 35,23 Z"
id="path20" />
<linearGradient
id="SVGID_00000135668350575375336630000014638141720088491653_"
gradientUnits="userSpaceOnUse"
x1="-17.5865"
y1="-27.071199"
x2="-1.7875"
y2="29.073799">
<stop
offset="0.278"
style="stop-color:#DD1265"
id="stop22" />
<stop
offset="0.968"
style="stop-color:#FDB60D"
id="stop24" />
</linearGradient>
<path
style="fill:url(#SVGID_00000135668350575375336630000014638141720088491653_)"
d="m -14.1,-35 -20.9,14.1 7.8,48.1 20.1,7.7 26,-21 z"
id="path27" />
<path
d="M 21,-21 H -21 V 21 H 21 Z"
id="path29" />
<path
class="st3"
d="m -0.6,13.6 h -15.8 v 2.7 h 15.8 z"
id="path31" />
<path
class="st3"
d="m 0.5,-15.8 h 6.2 c 5,0 8.4,3.4 8.4,7.7 0,4.4 -3.4,7.9 -8.4,7.9 L 0.5,0 Z m 3.5,3.2 v 9.5 h 2.7 c 2.8,0 4.8,-1.9 4.8,-4.6 0,-2.8 -1.9,-4.7 -4.8,-4.7 z"
id="path33" />
<path
class="st3"
d="m -15.7,-15.8 h 7.2 c 2,0 3.5,0.6 4.6,1.6 0.9,0.9 1.3,2.1 1.3,3.6 v 0.1 c 0,1.3 -0.3,2.3 -0.9,3.1 -0.6,0.8 -1.4,1.4 -2.4,1.8 L -2,0 h -4.1 l -3.3,-4.8 h -2.9 V 0 h -3.5 z m 7,7.7 c 0.8,0 1.5,-0.2 2,-0.6 0.5,-0.4 0.7,-1 0.7,-1.6 v -0.1 c 0,-0.8 -0.2,-1.3 -0.7,-1.7 -0.5,-0.3 -1.1,-0.6 -2,-0.6 h -3.4 v 4.5 h 3.4 z"
id="path35" />
</symbol>
<use
xlink:href="#rider"
width="70"
height="70"
x="-35"
y="-35"
transform="matrix(7.0682519,0,0,7.2481031,256,256)"
style="overflow:visible"
id="use38" />
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -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

View File

@@ -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"

View File

@@ -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
}
}

View File

@@ -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])

View File

@@ -0,0 +1 @@
uid://c1x58xm2w1n20

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@@ -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

View File

@@ -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(":", " -")

View File

@@ -0,0 +1 @@
uid://bdiu78ot0rrkc

View File

@@ -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

View File

@@ -0,0 +1 @@
uid://bci4kmk7h4j6a

View File

@@ -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)

View File

@@ -0,0 +1 @@
uid://cfsu1rbg0ypem

View File

@@ -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])

View File

@@ -0,0 +1 @@
uid://bjiaycxso8h8u

View File

@@ -24,6 +24,10 @@ window/stretch/aspect="expand"
project/assembly_name="your are an ai ceo" project/assembly_name="your are an ai ceo"
[editor_plugins]
enabled=PackedStringArray("res://addons/rider-plugin/plugin.cfg")
[physics] [physics]
2d/run_on_separate_thread=true 2d/run_on_separate_thread=true

View File

@@ -5,5 +5,5 @@
[resource] [resource]
script = ExtResource("1_s1cac") script = ExtResource("1_s1cac")
Title = "Coffee Break" 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" metadata/_custom_type_script = "uid://cuq38lbfa2v74"

View File

@@ -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"

View File

@@ -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"

View File

@@ -3,7 +3,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net9.0</TargetFramework> <TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net9.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading> <EnableDynamicLoading>true</EnableDynamicLoading>
<RootNamespace>yourareanaiceo</RootNamespace> <RootNamespace>AiCeo</RootNamespace>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="GodotSharp.SourceGenerators" Version="2.7.0" /> <PackageReference Include="GodotSharp.SourceGenerators" Version="2.7.0" />

View File

@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMeetingControl_005FScriptMethods_002Egenerated_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2026_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fa98bda93fd7579c499aad3e06cc2ee8644bbc7cb2a1e815e2ccb9f19c3d8_003FMeetingControl_005FScriptMethods_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>