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);
161 private static bool ConfigProgress
= Config
.Get("block/progress", true);
171 public bool ShowError
173 set { showerror = value; }
176 public IPlugin Plugin
178 get { return plugin; }
191 public Socket
[] SocketIn
193 get { return socketin; }
196 public Socket
[] SocketOut
198 get { return socketout; }
203 get { return working; }
204 set { working = value; }
207 public Block(Schematic s
, Context c
, IPlugin plugin
, int x
, int y
)
210 this.plugin
= plugin
;
216 UpdateCoordinates(c
);
218 socketin
= new Socket
[plugin
.NumIn
];
219 socketout
= new Socket
[plugin
.NumOut
];
221 int curpos
= 10+(h
-20-CalcHeight(plugin
.NumIn
))/2;
222 for(int i
=0; i
<plugin
.NumIn
; i
++)
224 socketin
[i
] = new Socket(0, curpos
, this, Socket
.T
.In
, i
);
228 curpos
= 10+(h
-20-CalcHeight(plugin
.NumOut
))/2;
229 for(int i
=0; i
<plugin
.NumOut
; i
++)
231 socketout
[i
] = new Socket(w
-10, curpos
, this, Socket
.T
.Out
, i
);
236 public static void CheckGConf()
238 bool NewConfigGradient
= Config
.Get("block/gradient", true);
239 bool NewConfigInner
= Config
.Get("block/innerpath", true);
240 bool NewConfigRound
= Config
.Get("block/round", true);
241 bool NewConfigSmoothConnections
= Config
.Get("block/smoothconnections", true);
242 bool NewConfigProgress
= Config
.Get("block/progress", true);
245 ConfigGradient
!= NewConfigGradient
||
246 ConfigInner
!= NewConfigInner
||
247 ConfigRound
!= NewConfigRound
||
248 ConfigSmoothConnections
!= NewConfigSmoothConnections
||
249 ConfigProgress
!= NewConfigProgress
;
251 ConfigGradient
= NewConfigGradient
;
252 ConfigInner
= NewConfigInner
;
253 ConfigRound
= NewConfigRound
;
254 ConfigSmoothConnections
= NewConfigSmoothConnections
;
255 ConfigProgress
= NewConfigProgress
;
258 MainWindow
.RedrawSchematic();
261 public object Overlap(int x
, int y
)
263 if(x
< this.x
|| x
> this.x
+ w
|| y
< this.y
|| y
> this.y
+ h
)
269 int curpos
= this.y
+10+(h
-20-CalcHeight(socketin
.Length
))/2;
271 for(int i
=0; i
<socketin
.Length
; i
++)
273 if(y
> curpos
&& y
< curpos
+ 10)
279 else if(x
> this.x
+ w
- 10)
282 int curpos
= this.y
+10+(h
-20-CalcHeight(socketout
.Length
))/2;
284 for(int i
=0; i
<socketout
.Length
; i
++)
286 if(y
> curpos
&& y
< curpos
+ 10)
296 // FIXME hardcoded working area size
297 public void Move(int dx
, int dy
)
313 // removes all connections
314 public void Disconnect()
316 for(int i
=0; i
<socketin
.Length
; i
++)
317 socketin
[i
].Disconnect();
319 for(int i
=0; i
<socketout
.Length
; i
++)
320 socketout
[i
].Disconnect();
323 // called after slot number is changed
324 private void UpdateCoordinates()
326 int h1
= CalcHeight(plugin
.NumIn
);
327 int h2
= CalcHeight(plugin
.NumOut
);
330 h
= Math
.Max(Math
.Max(th
, h1
), h2
) + 20;
339 if(plugin
is ConnectorPlugin
)
348 // called only once, by constructor
349 private void UpdateCoordinates(Context c
)
351 TextExtents t
= c
.TextExtents(plugin
.Info
.ShortName
);
356 w
= (int)t
.Width
+ 30;
362 if(plugin
is ConnectorPlugin
)
373 public void Draw(Context c
, object selected
)
377 if(this == selected
|| (selected
is Socket
&& (selected
as Socket
).Parent
== this))
387 DrawClockProgress(c
, plugin
.Progress
);
390 if(selected
is Socket
)
392 for(int i
=0; i
<socketin
.Length
; i
++)
393 if(socketin
[i
] == selected
)
399 for(int i
=0; i
<socketout
.Length
; i
++)
400 if(socketout
[i
] == selected
)
402 socketout
[i
].Draw(c
);
409 c
.Color
= new Color(1, 0, 0, 0.5);
415 public State
CheckState()
417 for(int i
=0; i
<socketin
.Length
; i
++)
418 if(SocketIn
[i
].Other
== null)
419 return State
.NotReady
;
430 public bool WorkPossible()
432 for(int i
=0; i
<socketin
.Length
; i
++)
433 if(socketin
[i
].Other
.Parent
.CheckState() != State
.Good
)
439 private void DrawClock(Context c
)
442 c
.Translate(x
+ cx
, y
+ cy
);
448 private void DrawClockProgress(Context c
, float progress
)
451 c
.Color
= new Color(0.5, 0.5, 1, 0.75);
452 c
.Translate(x
+ w
/2, y
+ h
/2);
456 progressTimer
+= 0.2f
;
457 c
.Arc(0, 0, 8, progressTimer
, progressTimer
+ 1.5);
461 c
.ArcNegative(0, 0, 8, -90 * Math
.PI
/180, (-89 + 356 * progress
) * Math
.PI
/180);
468 private void DrawState(Context c
)
470 State s
= CheckState();
472 c
.Color
= new Color(1, 1, 1);
474 c
.Translate(x
+ sx
, y
+ sy
);
476 if(s
== State
.NotReady
)
477 StateNotReady
.Show(c
, 0, 0);
478 else if(s
== State
.Bad
)
479 StateBad
.Show(c
, 0, 0);
480 else if(s
== State
.Good
)
481 StateGood
.Show(c
, 0, 0);
483 StateReady
.Show(c
, 0, 0);
489 private void DrawBlockGradient(Context c
)
491 LinearGradient g
= new LinearGradient(0, y
, 0, y
+h
);
492 if(plugin
is IInPlugin
)
494 g
.AddColorStop(0, new Color(0.65, 0.85, 1.00, 0.85));
495 g
.AddColorStop(0.33, new Color(0.45, 0.65, 1.00, 0.85));
496 g
.AddColorStop(1, new Color(0.20, 0.50, 0.80, 0.85));
498 else if(plugin
is IOutPlugin
)
500 g
.AddColorStop(0, new Color(1.00, 0.85, 1.00, 0.85));
501 g
.AddColorStop(0.33, new Color(1.00, 0.65, 1.00, 0.85));
502 g
.AddColorStop(1, new Color(0.80, 0.40, 0.80, 0.85));
504 else if(plugin
is IImgProcPlugin
)
506 g
.AddColorStop(0, new Color(0.75, 1.00, 0.75, 0.85));
507 g
.AddColorStop(0.33, new Color(0.55, 1.00, 0.55, 0.85));
508 g
.AddColorStop(1, new Color(0.30, 0.80, 0.30, 0.85));
510 else if(plugin
is IResProcPlugin
)
512 g
.AddColorStop(0, new Color(1.00, 0.75, 0.75, 0.85));
513 g
.AddColorStop(0.33, new Color(1.00, 0.55, 0.55, 0.85));
514 g
.AddColorStop(1, new Color(0.80, 0.30, 0.30, 0.85));
516 else if(plugin
is IComparatorPlugin
)
518 g
.AddColorStop(0, new Color(1.00, 1.00, 0.75, 0.85));
519 g
.AddColorStop(0.33, new Color(1.00, 1.00, 0.55, 0.85));
520 g
.AddColorStop(1, new Color(0.80, 0.80, 0.30, 0.85));
522 else if(plugin
is IOtherPlugin
)
524 g
.AddColorStop(0, new Color(0.7, 0.7, 0.7, 0.85));
525 g
.AddColorStop(0.33, new Color(0.5, 0.5, 0.5, 0.85));
526 g
.AddColorStop(1, new Color(0.35, 0.35, 0.35, 0.85));
534 private void DrawBlockNoGradient(Context c
)
536 if(plugin
is IInPlugin
)
537 c
.Color
= new Color(0.35, 0.55, 0.95, 0.85);
538 else if(plugin
is IOutPlugin
)
539 c
.Color
= new Color(0.95, 0.55, 0.95, 0.85);
540 else if(plugin
is IImgProcPlugin
)
541 c
.Color
= new Color(0.45, 0.95, 0.45, 0.85);
542 else if(plugin
is IResProcPlugin
)
543 c
.Color
= new Color(0.95, 0.45, 0.45, 0.85);
544 else if(plugin
is IComparatorPlugin
)
545 c
.Color
= new Color(0.95, 0.95, 0.45, 0.85);
546 else if(plugin
is IOtherPlugin
)
547 c
.Color
= new Color(0.5, 0.5, 0.5, 0.85);
553 private void DrawBlock(Context c
, bool IsSelected
)
556 DrawBlockGradient(c
);
558 DrawBlockNoGradient(c
);
561 c
.Color
= new Color(1, 0, 0);
563 c
.Color
= new Color(0.2, 0.2, 1);
565 c
.Color
= new Color(0, 0, 0);
573 c
.Color
= new Color(1, 1, 1, 0.5);
579 c
.Color
= new Color(0, 0, 0);
582 c
.Translate(x
+ tx
, y
+ ty
);
583 c
.ShowText(plugin
.Info
.ShortName
);
588 private void DrawSockets(Context c
)
590 int curpos
= y
+10+(h
-20-CalcHeight(socketout
.Length
))/2;
592 for(int i
=0; i
<socketout
.Length
; i
++)
594 if(socketout
[i
].Other
== null)
597 c
.Arc(x
+w
-3, curpos
+5, 4, 0, 2*Math
.PI
);
598 c
.Color
= new Color(1, 1, 1, 0.8);
600 c
.Color
= new Color(0, 0, 0);
606 c
.MoveTo(x
+w
, curpos
);
609 c
.CurveTo(x
+w
-10, curpos
, x
+w
-10, curpos
+10, x
+w
, curpos
+10);
612 c
.LineTo(x
+w
-8, curpos
);
613 c
.LineTo(x
+w
-8, curpos
+10);
614 c
.LineTo(x
+w
, curpos
+10);
617 c
.LineTo(x
+w
, curpos
);
618 c
.Color
= new Color(1, 1, 1, 0.8);
620 c
.MoveTo(x
+w
, curpos
);
621 c
.LineTo(x
+w
, curpos
+10);
622 c
.Color
= new Color(0, 0, 0);
629 curpos
= y
+10+(h
-20-CalcHeight(socketin
.Length
))/2;
631 for(int i
=0; i
<socketin
.Length
; i
++)
633 if(socketin
[i
].Other
!= null)
639 c
.CurveTo(x
+10, curpos
, x
+10, curpos
+10, x
, curpos
+10);
642 c
.LineTo(x
+8, curpos
);
643 c
.LineTo(x
+8, curpos
+10);
644 c
.LineTo(x
, curpos
+10);
648 c
.Color
= new Color(1, 1, 1, 0.8);
651 c
.LineTo(x
, curpos
+10);
652 c
.Color
= new Color(0, 0, 0);
660 public void DrawConnections(Context c
)
662 int curpos
= y
+15+(h
-20-CalcHeight(socketout
.Length
))/2;
665 c
.Color
= new Color(0, 0, 0);
666 for(int i
=0; i
<socketout
.Length
; i
++)
668 if(socketout
[i
].Other
!= null)
670 c
.MoveTo(x
+w
, curpos
);
672 if(ConfigSmoothConnections
)
673 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);
675 c
.LineTo(socketout
[i
].Other
.PX
, socketout
[i
].Other
.PY
+5);
684 private int CalcHeight(int sockets
)
686 return Math
.Max(sockets
*10 + (sockets
-1)*5, 0);
689 private void DrawPath(Context c
)
697 private void DrawPathRound(Context c
)
708 c
.CurveTo(x
+w
, y
, x
+w
, y
, x
+w
, y
+10);
711 if(socketout
.Length
== 0)
712 c
.LineTo(x
+w
, y
+h
-10);
715 int curpos
= y
+10+(h
-20-CalcHeight(socketout
.Length
))/2;
717 c
.LineTo(x
+w
, curpos
);
719 for(int i
=0; i
<socketout
.Length
; i
++)
724 c
.LineTo(x
+w
, curpos
);
727 c
.CurveTo(x
+w
-10, curpos
, x
+w
-10, curpos
+10, x
+w
, curpos
+10);
731 c
.LineTo(x
+w
,y
+h
-10);
735 c
.CurveTo(x
+w
, y
+h
, x
+w
, y
+h
, x
+w
-10, y
+h
);
738 c
.CurveTo(x
, y
+h
, x
, y
+h
, x
, y
+h
-10);
741 if(socketin
.Length
== 0)
745 int curpos
= y
+h
-10-(h
-20-CalcHeight(socketin
.Length
))/2;
749 for(int i
=0; i
<socketin
.Length
; i
++)
757 c
.CurveTo(x
+10, curpos
, x
+10, curpos
-10, x
, curpos
-10);
765 c
.CurveTo(x
, y
, x
, y
, x
+10, y
);
768 private void DrawPathSquare(Context c
)
781 if(socketout
.Length
== 0)
785 int curpos
= y
+10+(h
-20-CalcHeight(socketout
.Length
))/2;
787 c
.LineTo(x
+w
, curpos
);
789 for(int i
=0; i
<socketout
.Length
; i
++)
794 c
.LineTo(x
+w
, curpos
);
797 c
.LineTo(x
+w
-8, curpos
);
798 c
.LineTo(x
+w
-8, curpos
+10);
799 c
.LineTo(x
+w
, curpos
+10);
812 if(socketin
.Length
== 0)
816 int curpos
= y
+h
-10-(h
-20-CalcHeight(socketin
.Length
))/2;
820 for(int i
=0; i
<socketin
.Length
; i
++)
828 c
.LineTo(x
+8, curpos
);
829 c
.LineTo(x
+8, curpos
-10);
830 c
.LineTo(x
, curpos
-10);
843 private void DrawPathInner(Context c
)
846 DrawPathInnerRound(c
);
849 // DrawPathInnerSquare(c);
853 private void DrawPathInnerRound(Context c
)
861 c
.MoveTo(x
+11.5, y
+1.5);
862 c
.LineTo(x
+w
-11.5, y
+1.5);
864 c
.CurveTo(x
+w
-1.5, y
+1.5, x
+w
-1.5, y
+1.5, x
+w
-1.5, y
+8.5);
867 if(socketout
.Length
== 0)
868 c
.LineTo(x
+w
-1.5, y
+h
-11.5);
871 int curpos
= y
+10+(h
-20-CalcHeight(socketout
.Length
))/2;
873 c
.LineTo(x
+w
-1.5, curpos
-1.5);
875 for(int i
=0; i
<socketout
.Length
; i
++)
880 c
.LineTo(x
+w
-1.5, curpos
-1.5);
883 c
.CurveTo(x
+w
-11.5, curpos
-1.5, x
+w
-11.5, curpos
+11.5, x
+w
-1.5, curpos
+11.5);
887 c
.LineTo(x
+w
-1.5, y
+h
-8.5);
891 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);
892 c
.LineTo(x
+11.5, y
+h
-1.5);
894 c
.CurveTo(x
+1.5, y
+h
-1.5, x
+1.5, y
+h
-1.5, x
+1.5, y
+h
-8.5);
897 if(socketin
.Length
== 0)
898 c
.LineTo(x
+1.5, y
+11.5);
901 int curpos
= y
+h
-10-(h
-20-CalcHeight(socketin
.Length
))/2;
903 c
.LineTo(x
+1.5, curpos
+1.5);
905 for(int i
=0; i
<socketin
.Length
; i
++)
910 c
.LineTo(x
+1.5, curpos
+1.5);
913 c
.CurveTo(x
+11.5, curpos
+1.5, x
+11.5, curpos
-11.5, x
+1.5, curpos
-11.5);
917 c
.LineTo(x
+1.5, y
+8.5);
921 c
.CurveTo(x
+1.5, y
+1.5, x
+1.5, y
+1.5, x
+11.5, y
+1.5);
924 private void Invalidate(bool x
)
926 Plugin
.WorkDone
= false;
929 for(int i
=0; i
<socketout
.Length
; i
++)
931 Socket o
= socketout
[i
].Other
;
933 if(o
!= null && o
.Parent
.CheckState() == State
.Good
)
934 o
.Parent
.Invalidate(true);
938 public void Invalidate()
941 schematic
.QueueDraw();
944 public void SlotsChanged()
948 if(socketin
.Length
!= plugin
.NumIn
)
950 Socket
[] newsocketin
= new Socket
[plugin
.NumIn
];
951 int curpos
= 10+(h
-20-CalcHeight(plugin
.NumIn
))/2;
953 for(int i
=0; i
<plugin
.NumIn
; i
++)
955 if(i
< socketin
.Length
)
956 newsocketin
[i
] = socketin
[i
];
958 newsocketin
[i
] = new Socket(0, curpos
, this, Socket
.T
.In
, i
);
961 for(int i
=plugin
.NumIn
; i
<socketout
.Length
; i
++)
962 socketout
[i
].Disconnect();
964 socketin
= newsocketin
;
968 int curpos
= 10+(h
-20-CalcHeight(socketin
.Length
))/2;
970 for(int i
=0; i
<socketin
.Length
; i
++)
972 socketin
[i
].Y
= curpos
;
977 if(socketout
.Length
!= plugin
.NumOut
)
979 Socket
[] newsocketout
= new Socket
[plugin
.NumOut
];
980 int curpos
= 10+(h
-20-CalcHeight(plugin
.NumOut
))/2;
982 for(int i
=0; i
<plugin
.NumOut
; i
++)
984 if(i
< socketout
.Length
)
985 newsocketout
[i
] = socketout
[i
];
987 newsocketout
[i
] = new Socket(w
-10, curpos
, this, Socket
.T
.Out
, i
);
990 for(int i
=plugin
.NumOut
; i
<socketout
.Length
; i
++)
991 socketout
[i
].Disconnect();
993 socketout
= newsocketout
;
997 int curpos
= 10+(h
-20-CalcHeight(socketout
.Length
))/2;
999 for(int i
=0; i
<socketout
.Length
; i
++)
1001 socketout
[i
].Y
= curpos
;
1006 schematic
.QueueDraw();