3 using System
.Reflection
;
10 private readonly int num
;
12 private readonly Block parent
;
13 private readonly T type
;
35 get { return parent.X + x; }
40 get { return parent.Y + y; }
45 get { return parent; }
63 public Socket(int x
, int y
, Block parent
, T type
, int num
)
74 public void Draw(Context c
)
76 int xc
= parent
.X
+ x
;
77 int yc
= parent
.Y
+ y
+ 5;
83 c
.Arc(xc
+6.5, yc
, 4, 0, 2*Math
.PI
);
84 c
.Color
= new Color(0.2, 0.2, 1, 0.6);
97 c
.Arc(xc
, yc
, r
, 0, 2*Math
.PI
);
98 c
.Color
= new Color(1, 0, 0);
101 c
.Color
= new Color(0.3, 0, 0);
103 c
.MoveTo(xc
-0.707*r
, yc
-0.707*r
);
104 c
.LineTo(xc
+0.707*r
, yc
+0.707*r
);
106 c
.MoveTo(xc
-0.707*r
, yc
+0.707*r
);
107 c
.LineTo(xc
+0.707*6, yc
-0.707*6);
112 public void Disconnect()
119 other
.parent
.Invalidate();
126 public void Connect(Socket to
)
138 private readonly IPlugin plugin
;
139 private readonly Schematic schematic
;
141 private int h
= 0, w
= 0, th
= 0;
142 private int tx
= 0, ty
= 0;
143 private int sx
= 0, sy
= 0;
144 private int cx
= 0, cy
= 0;
145 private Socket
[] socketin
= null;
146 private Socket
[] socketout
= null;
147 private bool working
= false;
148 private bool showerror
= false;
149 private float progressTimer
= 0;
151 private static ImageSurface StateBad
= new ImageSurface(System
.IO
.Path
.Combine(AppDomain
.CurrentDomain
.BaseDirectory
, "data/state-bad.png"));
152 private static ImageSurface StateGood
= new ImageSurface(System
.IO
.Path
.Combine(AppDomain
.CurrentDomain
.BaseDirectory
, "data/state-good.png"));
153 private static ImageSurface StateNotReady
= new ImageSurface(System
.IO
.Path
.Combine(AppDomain
.CurrentDomain
.BaseDirectory
, "data/state-not-ready.png"));
154 private static ImageSurface StateReady
= new ImageSurface(System
.IO
.Path
.Combine(AppDomain
.CurrentDomain
.BaseDirectory
, "data/state-ready.png"));
155 private static ImageSurface Clock
= new ImageSurface(System
.IO
.Path
.Combine(AppDomain
.CurrentDomain
.BaseDirectory
, "data/clock.png"));
157 private static bool ConfigGradient
= Config
.Get("block/gradient", true);
158 private static bool ConfigInner
= Config
.Get("block/innerpath", true);
159 private static bool ConfigRound
= Config
.Get("block/round", true);
160 private static bool ConfigSmoothConnections
= Config
.Get("block/smoothconnections", true);
170 public bool ShowError
172 set { showerror = value; }
175 public IPlugin Plugin
177 get { return plugin; }
190 public Socket
[] SocketIn
192 get { return socketin; }
195 public Socket
[] SocketOut
197 get { return socketout; }
202 get { return working; }
203 set { working = value; }
206 public Block(Schematic s
, Context c
, IPlugin plugin
, int x
, int y
)
209 this.plugin
= plugin
;
215 UpdateCoordinates(c
);
217 socketin
= new Socket
[plugin
.NumIn
];
218 socketout
= new Socket
[plugin
.NumOut
];
220 int curpos
= 10+(h
-20-CalcHeight(plugin
.NumIn
))/2;
221 for(int i
=0; i
<plugin
.NumIn
; i
++)
223 socketin
[i
] = new Socket(0, curpos
, this, Socket
.T
.In
, i
);
227 curpos
= 10+(h
-20-CalcHeight(plugin
.NumOut
))/2;
228 for(int i
=0; i
<plugin
.NumOut
; i
++)
230 socketout
[i
] = new Socket(w
-10, curpos
, this, Socket
.T
.Out
, i
);
235 public static void CheckGConf()
237 bool NewConfigGradient
= Config
.Get("block/gradient", true);
238 bool NewConfigInner
= Config
.Get("block/innerpath", true);
239 bool NewConfigRound
= Config
.Get("block/round", true);
240 bool NewConfigSmoothConnections
= Config
.Get("block/smoothconnections", true);
243 ConfigGradient
!= NewConfigGradient
||
244 ConfigInner
!= NewConfigInner
||
245 ConfigRound
!= NewConfigRound
||
246 ConfigSmoothConnections
!= NewConfigSmoothConnections
;
248 ConfigGradient
= NewConfigGradient
;
249 ConfigInner
= NewConfigInner
;
250 ConfigRound
= NewConfigRound
;
251 ConfigSmoothConnections
= NewConfigSmoothConnections
;
254 MainWindow
.RedrawSchematic();
257 public object Overlap(int x
, int y
)
259 if(x
< this.x
|| x
> this.x
+ w
|| y
< this.y
|| y
> this.y
+ h
)
265 int curpos
= this.y
+10+(h
-20-CalcHeight(socketin
.Length
))/2;
267 for(int i
=0; i
<socketin
.Length
; i
++)
269 if(y
> curpos
&& y
< curpos
+ 10)
275 else if(x
> this.x
+ w
- 10)
278 int curpos
= this.y
+10+(h
-20-CalcHeight(socketout
.Length
))/2;
280 for(int i
=0; i
<socketout
.Length
; i
++)
282 if(y
> curpos
&& y
< curpos
+ 10)
292 // FIXME wpisany na sztywno rozmiar obszaru roboczego
293 public void Move(int dx
, int dy
)
309 // usuwa wszystkie połączenia
310 public void Disconnect()
312 for(int i
=0; i
<socketin
.Length
; i
++)
313 socketin
[i
].Disconnect();
315 for(int i
=0; i
<socketout
.Length
; i
++)
316 socketout
[i
].Disconnect();
319 // wykonywane po zmianie liczby slotów we wtyczce
320 private void UpdateCoordinates()
322 int h1
= CalcHeight(plugin
.NumIn
);
323 int h2
= CalcHeight(plugin
.NumOut
);
326 h
= Math
.Max(Math
.Max(th
, h1
), h2
) + 20;
335 if(plugin
is ConnectorPlugin
)
344 // wykonywane tylko raz, przez konstruktor
345 private void UpdateCoordinates(Context c
)
347 TextExtents t
= c
.TextExtents(plugin
.Info
.ShortName
);
352 w
= (int)t
.Width
+ 30;
358 if(plugin
is ConnectorPlugin
)
369 public void Draw(Context c
, object selected
)
373 if(this == selected
|| (selected
is Socket
&& (selected
as Socket
).Parent
== this))
382 DrawClockProgress(c
, plugin
.Progress
);
385 if(selected
is Socket
)
387 for(int i
=0; i
<socketin
.Length
; i
++)
388 if(socketin
[i
] == selected
)
394 for(int i
=0; i
<socketout
.Length
; i
++)
395 if(socketout
[i
] == selected
)
397 socketout
[i
].Draw(c
);
404 c
.Color
= new Color(1, 0, 0, 0.5);
410 public State
CheckState()
412 for(int i
=0; i
<socketin
.Length
; i
++)
413 if(SocketIn
[i
].Other
== null)
414 return State
.NotReady
;
425 public bool WorkPossible()
427 for(int i
=0; i
<socketin
.Length
; i
++)
428 if(socketin
[i
].Other
.Parent
.CheckState() != State
.Good
)
434 private void DrawClock(Context c
)
437 c
.Translate(x
+ cx
, y
+ cy
);
443 private void DrawClockProgress(Context c
, float progress
)
445 // FIXME infinite progress not supported now
450 c
.Color
= new Color(0.5, 0.5, 1, 0.75);
451 c
.Translate(x
+ w
/2, y
+ h
/2);
455 progressTimer
+= 0.01f
;
456 c
.Arc(0, 0, 8, progressTimer
, progressTimer
+ 1.5);
460 c
.ArcNegative(0, 0, 8, -90 * Math
.PI
/180, (-89 + 356 * progress
) * Math
.PI
/180);
466 schematic
.QueueDraw();
469 private void DrawState(Context c
)
471 State s
= CheckState();
473 c
.Color
= new Color(1, 1, 1);
475 c
.Translate(x
+ sx
, y
+ sy
);
477 if(s
== State
.NotReady
)
478 StateNotReady
.Show(c
, 0, 0);
479 else if(s
== State
.Bad
)
480 StateBad
.Show(c
, 0, 0);
481 else if(s
== State
.Good
)
482 StateGood
.Show(c
, 0, 0);
484 StateReady
.Show(c
, 0, 0);
490 private void DrawBlockGradient(Context c
)
492 LinearGradient g
= new LinearGradient(0, y
, 0, y
+h
);
493 if(plugin
is IInPlugin
)
495 g
.AddColorStop(0, new Color(0.65, 0.85, 1.00, 0.85));
496 g
.AddColorStop(0.33, new Color(0.45, 0.65, 1.00, 0.85));
497 g
.AddColorStop(1, new Color(0.20, 0.50, 0.80, 0.85));
499 else if(plugin
is IOutPlugin
)
501 g
.AddColorStop(0, new Color(1.00, 0.85, 1.00, 0.85));
502 g
.AddColorStop(0.33, new Color(1.00, 0.65, 1.00, 0.85));
503 g
.AddColorStop(1, new Color(0.80, 0.40, 0.80, 0.85));
505 else if(plugin
is IImgProcPlugin
)
507 g
.AddColorStop(0, new Color(0.75, 1.00, 0.75, 0.85));
508 g
.AddColorStop(0.33, new Color(0.55, 1.00, 0.55, 0.85));
509 g
.AddColorStop(1, new Color(0.30, 0.80, 0.30, 0.85));
511 else if(plugin
is IResProcPlugin
)
513 g
.AddColorStop(0, new Color(1.00, 0.75, 0.75, 0.85));
514 g
.AddColorStop(0.33, new Color(1.00, 0.55, 0.55, 0.85));
515 g
.AddColorStop(1, new Color(0.80, 0.30, 0.30, 0.85));
517 else if(plugin
is IComparatorPlugin
)
519 g
.AddColorStop(0, new Color(1.00, 1.00, 0.75, 0.85));
520 g
.AddColorStop(0.33, new Color(1.00, 1.00, 0.55, 0.85));
521 g
.AddColorStop(1, new Color(0.80, 0.80, 0.30, 0.85));
523 else if(plugin
is IOtherPlugin
)
525 g
.AddColorStop(0, new Color(0.7, 0.7, 0.7, 0.85));
526 g
.AddColorStop(0.33, new Color(0.5, 0.5, 0.5, 0.85));
527 g
.AddColorStop(1, new Color(0.35, 0.35, 0.35, 0.85));
535 private void DrawBlockNoGradient(Context c
)
537 if(plugin
is IInPlugin
)
538 c
.Color
= new Color(0.35, 0.55, 0.95, 0.85);
539 else if(plugin
is IOutPlugin
)
540 c
.Color
= new Color(0.95, 0.55, 0.95, 0.85);
541 else if(plugin
is IImgProcPlugin
)
542 c
.Color
= new Color(0.45, 0.95, 0.45, 0.85);
543 else if(plugin
is IResProcPlugin
)
544 c
.Color
= new Color(0.95, 0.45, 0.45, 0.85);
545 else if(plugin
is IComparatorPlugin
)
546 c
.Color
= new Color(0.95, 0.95, 0.45, 0.85);
547 else if(plugin
is IOtherPlugin
)
548 c
.Color
= new Color(0.5, 0.5, 0.5, 0.85);
554 private void DrawBlock(Context c
, bool IsSelected
)
557 DrawBlockGradient(c
);
559 DrawBlockNoGradient(c
);
562 c
.Color
= new Color(1, 0, 0);
564 c
.Color
= new Color(0.2, 0.2, 1);
566 c
.Color
= new Color(0, 0, 0);
574 c
.Color
= new Color(1, 1, 1, 0.5);
580 c
.Color
= new Color(0, 0, 0);
583 c
.Translate(x
+ tx
, y
+ ty
);
584 c
.ShowText(plugin
.Info
.ShortName
);
589 private void DrawSockets(Context c
)
591 int curpos
= y
+10+(h
-20-CalcHeight(socketout
.Length
))/2;
593 for(int i
=0; i
<socketout
.Length
; i
++)
595 if(socketout
[i
].Other
== null)
598 c
.Arc(x
+w
-3, curpos
+5, 4, 0, 2*Math
.PI
);
599 c
.Color
= new Color(1, 1, 1, 0.8);
601 c
.Color
= new Color(0, 0, 0);
607 c
.MoveTo(x
+w
, curpos
);
610 c
.CurveTo(x
+w
-10, curpos
, x
+w
-10, curpos
+10, x
+w
, curpos
+10);
613 c
.LineTo(x
+w
-8, curpos
);
614 c
.LineTo(x
+w
-8, curpos
+10);
615 c
.LineTo(x
+w
, curpos
+10);
618 c
.LineTo(x
+w
, curpos
);
619 c
.Color
= new Color(1, 1, 1, 0.8);
621 c
.MoveTo(x
+w
, curpos
);
622 c
.LineTo(x
+w
, curpos
+10);
623 c
.Color
= new Color(0, 0, 0);
630 curpos
= y
+10+(h
-20-CalcHeight(socketin
.Length
))/2;
632 for(int i
=0; i
<socketin
.Length
; i
++)
634 if(socketin
[i
].Other
!= null)
640 c
.CurveTo(x
+10, curpos
, x
+10, curpos
+10, x
, curpos
+10);
643 c
.LineTo(x
+8, curpos
);
644 c
.LineTo(x
+8, curpos
+10);
645 c
.LineTo(x
, curpos
+10);
649 c
.Color
= new Color(1, 1, 1, 0.8);
652 c
.LineTo(x
, curpos
+10);
653 c
.Color
= new Color(0, 0, 0);
661 public void DrawConnections(Context c
)
663 int curpos
= y
+15+(h
-20-CalcHeight(socketout
.Length
))/2;
666 c
.Color
= new Color(0, 0, 0);
667 for(int i
=0; i
<socketout
.Length
; i
++)
669 if(socketout
[i
].Other
!= null)
671 c
.MoveTo(x
+w
, curpos
);
673 if(ConfigSmoothConnections
)
674 c
.CurveTo(x
+w
+10, curpos
, socketout
[i
].Other
.PX
-10, socketout
[i
].Other
.PY
+5, socketout
[i
].Other
.PX
, socketout
[i
].Other
.PY
+5);
676 c
.LineTo(socketout
[i
].Other
.PX
, socketout
[i
].Other
.PY
+5);
685 private int CalcHeight(int sockets
)
687 return Math
.Max(sockets
*10 + (sockets
-1)*5, 0);
690 private void DrawPath(Context c
)
698 private void DrawPathRound(Context c
)
709 c
.CurveTo(x
+w
, y
, x
+w
, y
, x
+w
, y
+10);
712 if(socketout
.Length
== 0)
713 c
.LineTo(x
+w
, y
+h
-10);
716 int curpos
= y
+10+(h
-20-CalcHeight(socketout
.Length
))/2;
718 c
.LineTo(x
+w
, curpos
);
720 for(int i
=0; i
<socketout
.Length
; i
++)
725 c
.LineTo(x
+w
, curpos
);
728 c
.CurveTo(x
+w
-10, curpos
, x
+w
-10, curpos
+10, x
+w
, curpos
+10);
732 c
.LineTo(x
+w
,y
+h
-10);
736 c
.CurveTo(x
+w
, y
+h
, x
+w
, y
+h
, x
+w
-10, y
+h
);
739 c
.CurveTo(x
, y
+h
, x
, y
+h
, x
, y
+h
-10);
742 if(socketin
.Length
== 0)
746 int curpos
= y
+h
-10-(h
-20-CalcHeight(socketin
.Length
))/2;
750 for(int i
=0; i
<socketin
.Length
; i
++)
758 c
.CurveTo(x
+10, curpos
, x
+10, curpos
-10, x
, curpos
-10);
766 c
.CurveTo(x
, y
, x
, y
, x
+10, y
);
769 private void DrawPathSquare(Context c
)
782 if(socketout
.Length
== 0)
786 int curpos
= y
+10+(h
-20-CalcHeight(socketout
.Length
))/2;
788 c
.LineTo(x
+w
, curpos
);
790 for(int i
=0; i
<socketout
.Length
; i
++)
795 c
.LineTo(x
+w
, curpos
);
798 c
.LineTo(x
+w
-8, curpos
);
799 c
.LineTo(x
+w
-8, curpos
+10);
800 c
.LineTo(x
+w
, curpos
+10);
813 if(socketin
.Length
== 0)
817 int curpos
= y
+h
-10-(h
-20-CalcHeight(socketin
.Length
))/2;
821 for(int i
=0; i
<socketin
.Length
; i
++)
829 c
.LineTo(x
+8, curpos
);
830 c
.LineTo(x
+8, curpos
-10);
831 c
.LineTo(x
, curpos
-10);
844 private void DrawPathInner(Context c
)
847 DrawPathInnerRound(c
);
850 // DrawPathInnerSquare(c);
854 private void DrawPathInnerRound(Context c
)
862 c
.MoveTo(x
+11.5, y
+1.5);
863 c
.LineTo(x
+w
-11.5, y
+1.5);
865 c
.CurveTo(x
+w
-1.5, y
+1.5, x
+w
-1.5, y
+1.5, x
+w
-1.5, y
+8.5);
868 if(socketout
.Length
== 0)
869 c
.LineTo(x
+w
-1.5, y
+h
-11.5);
872 int curpos
= y
+10+(h
-20-CalcHeight(socketout
.Length
))/2;
874 c
.LineTo(x
+w
-1.5, curpos
-1.5);
876 for(int i
=0; i
<socketout
.Length
; i
++)
881 c
.LineTo(x
+w
-1.5, curpos
-1.5);
884 c
.CurveTo(x
+w
-11.5, curpos
-1.5, x
+w
-11.5, curpos
+11.5, x
+w
-1.5, curpos
+11.5);
888 c
.LineTo(x
+w
-1.5, y
+h
-8.5);
892 c
.CurveTo(x
+w
-1.5, y
+h
-1.5, x
+w
-1.5, y
+h
-1.5, x
+w
-11.5, y
+h
-1.5);
893 c
.LineTo(x
+11.5, y
+h
-1.5);
895 c
.CurveTo(x
+1.5, y
+h
-1.5, x
+1.5, y
+h
-1.5, x
+1.5, y
+h
-8.5);
898 if(socketin
.Length
== 0)
899 c
.LineTo(x
+1.5, y
+11.5);
902 int curpos
= y
+h
-10-(h
-20-CalcHeight(socketin
.Length
))/2;
904 c
.LineTo(x
+1.5, curpos
+1.5);
906 for(int i
=0; i
<socketin
.Length
; i
++)
911 c
.LineTo(x
+1.5, curpos
+1.5);
914 c
.CurveTo(x
+11.5, curpos
+1.5, x
+11.5, curpos
-11.5, x
+1.5, curpos
-11.5);
918 c
.LineTo(x
+1.5, y
+8.5);
922 c
.CurveTo(x
+1.5, y
+1.5, x
+1.5, y
+1.5, x
+11.5, y
+1.5);
925 private void Invalidate(bool x
)
927 Plugin
.WorkDone
= false;
930 for(int i
=0; i
<socketout
.Length
; i
++)
932 Socket o
= socketout
[i
].Other
;
934 if(o
!= null && o
.Parent
.CheckState() == State
.Good
)
935 o
.Parent
.Invalidate(true);
939 public void Invalidate()
942 schematic
.QueueDraw();
945 public void SlotsChanged()
949 if(socketin
.Length
!= plugin
.NumIn
)
951 Socket
[] newsocketin
= new Socket
[plugin
.NumIn
];
952 int curpos
= 10+(h
-20-CalcHeight(plugin
.NumIn
))/2;
954 for(int i
=0; i
<plugin
.NumIn
; i
++)
956 if(i
< socketin
.Length
)
957 newsocketin
[i
] = socketin
[i
];
959 newsocketin
[i
] = new Socket(0, curpos
, this, Socket
.T
.In
, i
);
962 for(int i
=plugin
.NumIn
; i
<socketout
.Length
; i
++)
963 socketout
[i
].Disconnect();
965 socketin
= newsocketin
;
969 int curpos
= 10+(h
-20-CalcHeight(socketin
.Length
))/2;
971 for(int i
=0; i
<socketin
.Length
; i
++)
973 socketin
[i
].Y
= curpos
;
978 if(socketout
.Length
!= plugin
.NumOut
)
980 Socket
[] newsocketout
= new Socket
[plugin
.NumOut
];
981 int curpos
= 10+(h
-20-CalcHeight(plugin
.NumOut
))/2;
983 for(int i
=0; i
<plugin
.NumOut
; i
++)
985 if(i
< socketout
.Length
)
986 newsocketout
[i
] = socketout
[i
];
988 newsocketout
[i
] = new Socket(w
-10, curpos
, this, Socket
.T
.Out
, i
);
991 for(int i
=plugin
.NumOut
; i
<socketout
.Length
; i
++)
992 socketout
[i
].Disconnect();
994 socketout
= newsocketout
;
998 int curpos
= 10+(h
-20-CalcHeight(socketout
.Length
))/2;
1000 for(int i
=0; i
<socketout
.Length
; i
++)
1002 socketout
[i
].Y
= curpos
;
1007 schematic
.QueueDraw();