22using Grasshopper . GUI ;
33using Grasshopper . GUI . Canvas ;
44using Grasshopper . Kernel . Attributes ;
5+ using System . Drawing ;
6+ using System . Drawing . Drawing2D ;
7+ using System . Windows . Forms ;
58
69namespace 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}
0 commit comments