Thanks again, that did the trick!
//Connect Component Out To Panel In
test_panel.AddSource(this.Component.Params.Output[1]);
Graph Space (After Button Press)
Onto the wire drag code!
EDIT:
Success getting the cursor position when the script is “called” and spawning a panel at the cusor location(currently with a button test)
What I am attempting to do now is set the cursor position when a wire is dragged off into blank canvas space. I believe this can be achieved with Mouse Down, Mouse Up but I’m having difficulty getting the event handlers working.
My thought is to leverage mouse down to trigger the event and when the mouse is realeased (mouse up) it will fire the function and spawn the connected panel at the released location in GH canvas space.
Current Code:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows;
using Rhino;
using Rhino.Geometry;
using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
public class Script_Instance : GH_ScriptInstance
{
private void RunScript(bool Test_Toggle, IEnumerable<object> Data, out object D, out object CP)
{
// Get Cursor Position
PointF cursor_pos = new PointF((float)Rhino.UI.MouseCursor.Location.X, (float)Rhino.UI.MouseCursor.Location.Y);
// Use Test_Toggle As Fake Event To Test Logic In Function
if (Test_Toggle)
{
// Get Test Event Location
var bounds = Component.Params.Input[0].Sources[0].Attributes.Bounds;
PointF test_event_location = new PointF(bounds.X + bounds.Width, bounds.Y - bounds.Height / 2);
// Instantiate New Panel
Grasshopper.Kernel.Special.GH_Panel test_panel = new Grasshopper.Kernel.Special.GH_Panel();
test_panel.CreateAttributes(); // sets up default values and makes sure your panel doesn't crash Rhino
// Customize Panel Attributes, etc.
int outputcount = this.Component.Params.Output[0].SourceCount;
// Set Panel Location To Cursor Position
test_panel.Attributes.Pivot = test_event_location;
// Add Panel To Document
GrasshopperDocument.AddObject(test_panel, false);
// Connect Component Out To Panel In
test_panel.AddSource(this.Component.Params.Output[0]);
}
D = Data;
CP = cursor_pos;
}
}
//Customize Panel Attributes, etc.
int outputcount = this.Component.Params.Output[0].SourceCount;
//Set Panel Location To Cursor Position
test_panel.Attributes.Pivot = offsetCursorPos;
//Add Panel To Document
GrasshopperDocument.AddObject(test_panel, false);
//Connect Component Out To Panel In
test_panel.AddSource(this.Component.Params.Output[0]);
}
D = Data;
CP = cursor_pos;
}
}
And my poor attempt at the event handler logic for MouseDown/MouseUp:
public class Script_Instance : GH_ScriptInstance
{
// Define a variable to hold the GH_Canvas
private GH_Canvas canvas;
// Subscribe to the DocumentObjectMouseDown event
protected override void BeforeSolveInstance()
{
// Set the active canvas
canvas = Grasshopper.Instances.ActiveCanvas;
// Check if the canvas is not null before subscribing to the event
if (canvas != null)
{
canvas.DocumentObjectMouseDown += Canvas_DocumentObjectMouseDown;
}
}
// Unsubscribe from the event when done
protected override void AfterSolveInstance()
{
if (canvas != null)
{
canvas.DocumentObjectMouseDown -= Canvas_DocumentObjectMouseDown;
}
}
// Event handler for DocumentObjectMouseDown
private void Canvas_DocumentObjectMouseDown(GH_Canvas sender, GH_Canvas.MouseEvent e)
{
// Check if the left mouse button is clicked
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
// Check if the user clicked on an output parameter
if (e.SourceParameter != null && e.SourceParameter.Attributes.GetTopLevel.DocObject is IGH_Param outputParam)
{
// Your existing code for creating a panel can go here
if (Test_Toggle)
{
// Instantiate New Panel
Grasshopper.Kernel.Special.GH_Panel test_panel = new Grasshopper.Kernel.Special.GH_Panel();
test_panel.CreateAttributes(); // sets up default values and makes sure your panel doesn't crash Rhino
// Customize panel (position, etc)
int outputcount = this.Component.Params.Output[0].SourceCount;
test_panel.Attributes.Pivot = new PointF((float)this.Component.Attributes.DocObject.Attributes.Bounds.Right + 30, (float)this.Component.Params.Output[0].Attributes.Bounds.Y + 50);
// Until now, the panel is a hypothetical object.
// This command makes it 'real' and adds it to the canvas.
GrasshopperDocument.AddObject(test_panel, false);
// Connect Component Out To Panel In
test_panel.AddSource(this.Component.Params.Output[0]);
}
}
}
}
private void RunScript(bool Test_Toggle, System.Collections.Generic.IEnumerable<object> Data, out object D, out object CP)
{
PointF cursor_pos = new PointF((float)Rhino.UI.MouseCursor.Location.X, (float)Rhino.UI.MouseCursor.Location.Y);
D = Data;
CP = cursor_pos;
}
}
Any help is greatly beneficial and once this logic gets worked out theoretically we could use it to spawn any “favorite” panel on wire drag out which could speed up workflows, offering convenience as well.
Graph Space (Pre “Event”):
Graph Space (Post “Event”):
20230823_Add_Panel_On_Wire_Drag_01d.gh (10.3 KB)
This is the kind of functionality I am trying to achieve, spawning a connected panel from a wire drag out (Example from Unreal Engine Blueprint GUI):
In Unreal this action prompts a search field but for this exercise in GH I just am trying to spawn the panel every time only.