Skip to content
This repository was archived by the owner on Jan 6, 2021. It is now read-only.

Commit b3e3303

Browse files
committed
Added hint to the location where Editor is linked to
Only add Grasshopper if it is not already there
1 parent 89f41a2 commit b3e3303

5 files changed

Lines changed: 231 additions & 53 deletions

File tree

Component/PythonComponentAttributes.cs

Lines changed: 159 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
using Grasshopper.GUI;
33
using Grasshopper.GUI.Canvas;
44
using Grasshopper.Kernel.Attributes;
5+
using System.Drawing;
6+
using System.Drawing.Drawing2D;
7+
using System.Windows.Forms;
58

69
namespace GhPython.Component
710
{
@@ -31,19 +34,38 @@ public void OpenEditor()
3134
m_form = new PythonScriptForm(attachedComp);
3235

3336
if (!m_form.Visible)
37+
{
3438
m_form.Show(Grasshopper.Instances.DocumentEditor);
39+
attachedComp.OnDisplayExpired(true);
40+
}
41+
else
42+
{
43+
m_form.Focus();
44+
}
3545
}
3646
}
3747

38-
public void DisableLinkedForm(bool close)
48+
public bool TryGetEditor(out Form editor)
49+
{
50+
if (m_form == null || m_form.IsDisposed)
51+
{
52+
editor = null;
53+
return false;
54+
}
55+
56+
editor = m_form;
57+
return true;
58+
}
59+
60+
public void DisableLinkedEditor(bool close)
3961
{
4062
if (close && m_form != null && !m_form.IsDisposed)
4163
m_form.Disable();
4264

4365
m_form = null;
4466
}
4567

46-
public bool TrySetLinkedFormHelpText(string text)
68+
public bool TrySetLinkedEditorHelpText(string text)
4769
{
4870
if (m_form != null && !m_form.IsDisposed)
4971
{
@@ -52,5 +74,140 @@ public bool TrySetLinkedFormHelpText(string text)
5274
}
5375
return false;
5476
}
77+
78+
protected override void Render(GH_Canvas canvas, System.Drawing.Graphics graphics, GH_CanvasChannel channel)
79+
{
80+
base.Render(canvas, graphics, channel);
81+
82+
if (m_form == null || m_form.IsDisposed) return;
83+
84+
if (channel == GH_CanvasChannel.Overlay &&
85+
(canvas.DrawingMode == GH_CanvasMode.Export ||
86+
canvas.DrawingMode == GH_CanvasMode.Control)
87+
)
88+
{
89+
Rectangle targetRectangle;
90+
if (canvas.DrawingMode == GH_CanvasMode.Export)
91+
{
92+
System.Windows.Forms.Control editorControl = m_form.m_texteditor;
93+
if (editorControl == null) return;
94+
targetRectangle = editorControl.ClientRectangle;
95+
targetRectangle = m_form.RectangleToScreen(targetRectangle);
96+
}
97+
else
98+
{
99+
targetRectangle = m_form.DesktopBounds;
100+
}
101+
102+
RectangleF windowOnCanvas;
103+
{
104+
targetRectangle.Inflate(-1, -1);
105+
106+
var desktopForm = canvas.RectangleToClient(targetRectangle);
107+
windowOnCanvas = canvas.Viewport.UnprojectRectangle(desktopForm);
108+
}
109+
110+
var transparent = Color.Transparent;
111+
112+
var desk_tl = new PointF(windowOnCanvas.Left, windowOnCanvas.Top);
113+
var desk_tr = new PointF(windowOnCanvas.Right, windowOnCanvas.Top);
114+
var desk_bl = new PointF(windowOnCanvas.Left, windowOnCanvas.Bottom);
115+
var desk_br = new PointF(windowOnCanvas.Right, windowOnCanvas.Bottom);
116+
117+
var comp_tl = new PointF(Bounds.Left, Bounds.Top);
118+
var comp_tr = new PointF(Bounds.Right, Bounds.Top);
119+
var comp_bl = new PointF(Bounds.Left, Bounds.Bottom);
120+
var comp_br = new PointF(Bounds.Right, Bounds.Bottom);
121+
122+
if (Bounds.Top < windowOnCanvas.Top)
123+
BoxSide(graphics, Color.FromArgb(155,255,255,255), transparent, desk_tl, desk_tr, comp_tl, comp_tr);
124+
if (Bounds.Right > windowOnCanvas.Right)
125+
BoxSide(graphics, Color.FromArgb(155, 240, 240, 240), transparent, desk_tr, desk_br, comp_tr, comp_br);
126+
if (Bounds.Bottom > windowOnCanvas.Bottom)
127+
BoxSide(graphics, Color.FromArgb(155, 120, 120, 120), transparent, desk_bl, desk_br, comp_bl, comp_br);
128+
if (Bounds.Left < windowOnCanvas.Left)
129+
BoxSide(graphics, Color.FromArgb(155, 240, 240, 240), transparent, desk_tl, desk_bl, comp_tl, comp_bl);
130+
131+
BoxEdge(graphics, Color.Black, Color.Transparent, 1, desk_tl, comp_tl, AnchorStyles.Top | AnchorStyles.Left);
132+
BoxEdge(graphics, Color.Black, Color.Transparent, 1, desk_tr, comp_tr, AnchorStyles.Top | AnchorStyles.Right);
133+
BoxEdge(graphics, Color.Black, Color.Transparent, 1, desk_br, comp_br, AnchorStyles.Bottom | AnchorStyles.Right);
134+
BoxEdge(graphics, Color.Black, Color.Transparent, 1, desk_bl, comp_bl, AnchorStyles.Bottom | AnchorStyles.Left);
135+
136+
if (canvas.DrawingMode == GH_CanvasMode.Export)
137+
{
138+
System.Windows.Forms.Control editorControl = m_form.m_texteditor;
139+
if (editorControl == null) return;
140+
141+
using (var bitmap = new Bitmap(editorControl.Width, editorControl.Height))
142+
{
143+
editorControl.DrawToBitmap(bitmap, editorControl.Bounds);
144+
145+
var ot = graphics.Transform;
146+
var loc = canvas.Viewport.ProjectPoint(windowOnCanvas.Location);
147+
148+
graphics.ResetTransform();
149+
150+
graphics.DrawImage(bitmap,
151+
(int)loc.X, (int)loc.Y,
152+
editorControl.Width, editorControl.Height);
153+
154+
graphics.Transform = ot;
155+
}
156+
}
157+
}
158+
}
159+
160+
private static void BoxSide(Graphics graphics, Color from, Color to,
161+
PointF A, PointF B, PointF C, PointF D)
162+
{
163+
using (var gradientA = new LinearGradientBrush(
164+
new PointF(A.X != B.X ? 0 : (A.X + B.X) * 0.5f, A.X == B.X ? 0 : (A.Y + B.Y) * 0.5f),
165+
new PointF(A.X != B.X ? 0 : (C.X + D.X) * 0.5f, A.X == B.X ? 0 : (C.Y + D.Y) * 0.5f),
166+
from, to))
167+
using (var path = new GraphicsPath())
168+
{
169+
gradientA.WrapMode = WrapMode.TileFlipXY;
170+
path.AddLine(A, B);
171+
path.AddLine(B, D);
172+
path.AddLine(D, C);
173+
path.CloseFigure();
174+
175+
graphics.FillPath(gradientA, path);
176+
}
177+
}
178+
179+
private static void BoxEdge(Graphics graphics, Color from, Color to,
180+
float size, PointF A, PointF B, AnchorStyles side)
181+
{
182+
using (var gradientA = new LinearGradientBrush(A, B, from, to))
183+
using (var penA = new Pen(gradientA, size))
184+
{
185+
bool visible = IsVisibleExtrusionEdge(B, A, side);
186+
if (!visible)
187+
{
188+
penA.DashStyle = DashStyle.Dash;
189+
penA.DashPattern = new float[] { 5, 5 };
190+
penA.DashCap = DashCap.Triangle;
191+
}
192+
graphics.DrawLine(penA, A, B);
193+
}
194+
}
195+
196+
private static bool IsVisibleExtrusionEdge(PointF back, PointF front, AnchorStyles sides)
197+
{
198+
bool toReturn = false;
199+
200+
if ((sides & AnchorStyles.Top) == AnchorStyles.Top)
201+
toReturn |= back.Y < front.Y;
202+
else if ((sides & AnchorStyles.Bottom) == AnchorStyles.Bottom)
203+
toReturn |= back.Y > front.Y;
204+
205+
if ((sides & AnchorStyles.Right) == AnchorStyles.Right)
206+
toReturn |= back.X > front.X;
207+
else if ((sides & AnchorStyles.Left) == AnchorStyles.Left)
208+
toReturn |= back.X < front.X;
209+
210+
return toReturn;
211+
}
55212
}
56213
}

Component/PythonEnvironment.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ internal PythonEnvironment(Grasshopper.Kernel.GH_Component component, PythonScri
8282

8383
public object Runtime { get; internal set; }
8484

85+
public Version Version { get { return Assembly.GetExecutingAssembly().GetName().Version; } }
86+
8587
public void LoadAssembly(System.Reflection.Assembly assembly)
8688
{
8789
FunctionalityLoad(assembly);
@@ -105,7 +107,8 @@ public void LoadAssembly(System.Reflection.Assembly assembly)
105107
if (list == null) return;
106108
foreach (var namesp in GetToplevelNamespacesForAssembly(assembly))
107109
{
108-
list.Add(namesp);
110+
if (!list.Contains(namesp))
111+
list.Add(namesp);
109112
}
110113
}
111114

Component/ScriptingAncestorComponent.cs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ protected override void Initialize()
6464
m_py.ContextId = 2; // 2 is Grasshopper
6565

6666
m_env.LoadAssembly(typeof(GH_Component).Assembly); //add Grasshopper.dll reference
67-
68-
6967
}
7068
}
7169
#endregion
@@ -389,17 +387,17 @@ private void AddErrorNicely(StringList sw, Exception ex)
389387

390388
private void SetFormErrorOrClearIt(IGH_DataAccess DA, StringList sl)
391389
{
392-
var attr = (PythonComponentAttributes)Attributes;
390+
var attr = Attributes;
393391

394392
if (sl.Result.Count > 0)
395393
{
396394
if (!HiddenOutOutput)
397395
DA.SetDataList(0, sl.Result);
398-
attr.TrySetLinkedFormHelpText(sl.ToString());
396+
attr.TrySetLinkedEditorHelpText(sl.ToString());
399397
}
400398
else
401399
{
402-
attr.TrySetLinkedFormHelpText("Execution completed successfully.");
400+
attr.TrySetLinkedEditorHelpText("Execution completed successfully.");
403401
}
404402
}
405403

@@ -465,7 +463,13 @@ private void OnDocSolutionEnd(object sender, GH_SolutionEventArgs e)
465463

466464
public override void CreateAttributes()
467465
{
468-
this.Attributes = new PythonComponentAttributes(this);
466+
base.Attributes = new PythonComponentAttributes(this);
467+
}
468+
469+
internal new PythonComponentAttributes Attributes
470+
{
471+
get
472+
{ return (PythonComponentAttributes)base.Attributes; }
469473
}
470474

471475
public Control CreateEditorControl(Action<string> helpCallback)
@@ -536,7 +540,7 @@ public override bool AppendMenuItems(ToolStripDropDown iMenu)
536540
{
537541
var tsi = new ToolStripMenuItem("&Open editor...", null, (sender, e) =>
538542
{
539-
var attr = Attributes as PythonComponentAttributes;
543+
var attr = Attributes;
540544
if (attr != null)
541545
attr.OpenEditor();
542546
});
@@ -612,6 +616,16 @@ public override bool Write(GH_IO.Serialization.GH_IWriter writer)
612616

613617
writer.SetBoolean(ID_HideOutput, HiddenOutOutput);
614618

619+
620+
//update if possible and save editor location
621+
{
622+
Form editor;
623+
if (Attributes.TryGetEditor(out editor))
624+
{
625+
DefaultEditorLocation = editor.Location;
626+
DefaultEditorSize = editor.Visible ? editor.Size : editor.RestoreBounds.Size;
627+
}
628+
}
615629
if (DefaultEditorLocation != null)
616630
{
617631
writer.SetDrawingPoint(ID_EditorLocation, DefaultEditorLocation.Value);
@@ -712,9 +726,9 @@ protected override void Dispose(bool disposing)
712726
if (Doc != null)
713727
Doc.SolutionEnd -= OnDocSolutionEnd;
714728

715-
var attr = Attributes as PythonComponentAttributes;
729+
var attr = Attributes;
716730
if (attr != null)
717-
attr.DisableLinkedForm(true);
731+
attr.DisableLinkedEditor(true);
718732
}
719733
}
720734
#endregion

Forms/PythonScriptForm.Designer.cs

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)