- add progress to Euclid
[FaRetSys.git] / Block.cs
bloba0244d967a238c1ce4e1c14882dc9db34dd25661
1 using System;
2 using System.IO;
3 using System.Reflection;
4 using Cairo;
6 namespace Eithne
8 class Socket
10 private readonly int num;
11 private int x, y;
12 private readonly Block parent;
13 private readonly T type;
14 private Socket other;
16 public enum T
18 In,
19 Out
22 public int X
24 get { return x; }
27 public int Y
29 get { return y; }
30 set { y = value; }
33 public int PX
35 get { return parent.X + x; }
38 public int PY
40 get { return parent.Y + y; }
43 public Block Parent
45 get { return parent; }
48 public T Type
50 get { return type; }
53 public Socket Other
55 get { return other; }
58 public int Num
60 get { return num; }
63 public Socket(int x, int y, Block parent, T type, int num)
65 this.x = x;
66 this.y = y;
67 this.parent = parent;
68 this.type = type;
69 this.num = num;
71 other = null;
74 public void Draw(Context c)
76 int xc = parent.X + x;
77 int yc = parent.Y + y + 5;
79 if(other == null)
81 if(type == T.Out)
83 c.Arc(xc+6.5, yc, 4, 0, 2*Math.PI);
84 c.Color = new Color(0.2, 0.2, 1, 0.6);
85 c.Fill();
88 else
90 int r = 6;
92 if(type == T.Out)
93 xc += 7;
94 else
95 xc += 3;
97 c.Arc(xc, yc, r, 0, 2*Math.PI);
98 c.Color = new Color(1, 0, 0);
99 c.LineWidth = 2.5;
100 c.FillPreserve();
101 c.Color = new Color(0.3, 0, 0);
102 c.Stroke();
103 c.MoveTo(xc-0.707*r, yc-0.707*r);
104 c.LineTo(xc+0.707*r, yc+0.707*r);
105 c.Stroke();
106 c.MoveTo(xc-0.707*r, yc+0.707*r);
107 c.LineTo(xc+0.707*6, yc-0.707*6);
108 c.Stroke();
112 public void Disconnect()
114 if(other != null)
116 if(type == T.In)
117 parent.Invalidate();
118 else
119 other.parent.Invalidate();
121 other.other = null;
122 other = null;
126 public void Connect(Socket to)
128 Disconnect();
129 to.Disconnect();
131 other = to;
132 to.other = this;
136 class Block : IBlock
138 private readonly IPlugin plugin;
139 private readonly Schematic schematic;
140 private int x, y;
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);
163 public enum State
165 Good,
166 Bad,
167 NotReady,
168 Ready
171 public bool ShowError
173 set { showerror = value; }
176 public IPlugin Plugin
178 get { return plugin; }
181 public int X
183 get { return x; }
186 public int Y
188 get { return y; }
191 public Socket[] SocketIn
193 get { return socketin; }
196 public Socket[] SocketOut
198 get { return socketout; }
201 public bool Working
203 get { return working; }
204 set { working = value; }
207 public Block(Schematic s, Context c, IPlugin plugin, int x, int y)
209 this.schematic = s;
210 this.plugin = plugin;
211 this.x = x;
212 this.y = y;
214 plugin.Block = this;
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);
225 curpos += 15;
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);
232 curpos += 15;
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);
244 bool redraw =
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;
257 if(redraw)
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)
264 return null;
266 if(x < this.x + 10)
267 // porty wejściowe
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)
274 return socketin[i];
276 curpos += 15;
279 else if(x > this.x + w - 10)
281 // porty wyjściowe
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)
287 return socketout[i];
289 curpos += 15;
293 return this;
296 // FIXME wpisany na sztywno rozmiar obszaru roboczego
297 public void Move(int dx, int dy)
299 x += dx;
300 y += dy;
302 if(x < 0)
303 x = 0;
304 else if(x+w >= 2048)
305 x = 2048-w;
307 if(y < 0)
308 y = 0;
309 else if(y+h >= 2048)
310 y = 2048-h;
313 // usuwa wszystkie połączenia
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 // wykonywane po zmianie liczby slotów we wtyczce
324 private void UpdateCoordinates()
326 int h1 = CalcHeight(plugin.NumIn);
327 int h2 = CalcHeight(plugin.NumOut);
329 // rozmiar bloku
330 h = Math.Max(Math.Max(th, h1), h2) + 20;
332 // położenie tekstu
333 ty = h/2 + th/2;
335 if(ty > h-15)
336 ty = h-15;
338 // położenie stanu
339 if(plugin is ConnectorPlugin)
340 sy = h/2 - 4;
341 else
342 sy = h - 11;
344 // położenie zegarka
345 cy = h/2 - 16;
348 // wykonywane tylko raz, przez konstruktor
349 private void UpdateCoordinates(Context c)
351 TextExtents t = c.TextExtents(plugin.Info.ShortName);
353 th = (int)t.Height;
355 // rozmiar bloku
356 w = (int)t.Width + 30;
358 // położenie tekstu
359 tx = 15;
361 // położenie stanu
362 if(plugin is ConnectorPlugin)
363 sx = w/2 - 4;
364 else
365 sx = w/2 - 3;
367 // położenie zegarka
368 cx = w/2 - 16;
370 UpdateCoordinates();
373 public void Draw(Context c, object selected)
375 DrawSockets(c);
377 if(this == selected || (selected is Socket && (selected as Socket).Parent == this))
378 DrawBlock(c, true);
379 else
380 DrawBlock(c, false);
382 DrawState(c);
383 if(working)
385 DrawClock(c);
386 if(ConfigProgress)
387 DrawClockProgress(c, plugin.Progress);
390 if(selected is Socket)
392 for(int i=0; i<socketin.Length; i++)
393 if(socketin[i] == selected)
395 socketin[i].Draw(c);
396 return;
399 for(int i=0; i<socketout.Length; i++)
400 if(socketout[i] == selected)
402 socketout[i].Draw(c);
403 return;
407 if(showerror)
409 c.Color = new Color(1, 0, 0, 0.5);
410 DrawPath(c);
411 c.Fill();
415 public State CheckState()
417 for(int i=0; i<socketin.Length; i++)
418 if(SocketIn[i].Other == null)
419 return State.NotReady;
421 if(Plugin.WorkDone)
422 return State.Good;
424 if(WorkPossible())
425 return State.Ready;
426 else
427 return State.Bad;
430 public bool WorkPossible()
432 for(int i=0; i<socketin.Length; i++)
433 if(socketin[i].Other.Parent.CheckState() != State.Good)
434 return false;
436 return true;
439 private void DrawClock(Context c)
441 c.Save();
442 c.Translate(x + cx, y + cy);
443 Clock.Show(c, 0, 0);
444 c.Stroke();
445 c.Restore();
448 private void DrawClockProgress(Context c, float progress)
450 c.Save();
451 c.Color = new Color(0.5, 0.5, 1, 0.75);
452 c.Translate(x + w/2, y + h/2);
453 c.MoveTo(0, 0);
454 if(progress == -1)
456 progressTimer += 0.2f;
457 c.Arc(0, 0, 8, progressTimer, progressTimer + 1.5);
459 else
461 c.ArcNegative(0, 0, 8, -90 * Math.PI/180, (-89 + 356 * progress ) * Math.PI/180);
463 c.ClosePath();
464 c.Fill();
465 c.Restore();
468 private void DrawState(Context c)
470 State s = CheckState();
472 c.Color = new Color(1, 1, 1);
473 c.Save();
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);
482 else
483 StateReady.Show(c, 0, 0);
485 c.Stroke();
486 c.Restore();
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));
529 DrawPath(c);
530 c.Pattern = g;
531 c.FillPreserve();
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);
549 DrawPath(c);
550 c.FillPreserve();
553 private void DrawBlock(Context c, bool IsSelected)
555 if(ConfigGradient)
556 DrawBlockGradient(c);
557 else
558 DrawBlockNoGradient(c);
560 if(showerror)
561 c.Color = new Color(1, 0, 0);
562 else if(IsSelected)
563 c.Color = new Color(0.2, 0.2, 1);
564 else
565 c.Color = new Color(0, 0, 0);
567 c.LineWidth = 2.0;
569 c.Stroke();
571 if(ConfigInner)
573 c.Color = new Color(1, 1, 1, 0.5);
574 c.LineWidth = 1;
575 DrawPathInner(c);
576 c.Stroke();
579 c.Color = new Color(0, 0, 0);
581 c.Save();
582 c.Translate(x + tx, y + ty);
583 c.ShowText(plugin.Info.ShortName);
584 c.Stroke();
585 c.Restore();
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)
596 c.LineWidth = 1.5;
597 c.Arc(x+w-3, curpos+5, 4, 0, 2*Math.PI);
598 c.Color = new Color(1, 1, 1, 0.8);
599 c.FillPreserve();
600 c.Color = new Color(0, 0, 0);
601 c.Stroke();
603 else
605 c.LineWidth = 2.0;
606 c.MoveTo(x+w, curpos);
608 if(ConfigRound)
609 c.CurveTo(x+w-10, curpos, x+w-10, curpos+10, x+w, curpos+10);
610 else
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);
619 c.Fill();
620 c.MoveTo(x+w, curpos);
621 c.LineTo(x+w, curpos+10);
622 c.Color = new Color(0, 0, 0);
623 c.Stroke();
626 curpos += 15;
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)
635 c.LineWidth = 2.0;
636 c.MoveTo(x, curpos);
638 if(ConfigRound)
639 c.CurveTo(x+10, curpos, x+10, curpos+10, x, curpos+10);
640 else
642 c.LineTo(x+8, curpos);
643 c.LineTo(x+8, curpos+10);
644 c.LineTo(x, curpos+10);
647 c.LineTo(x, curpos);
648 c.Color = new Color(1, 1, 1, 0.8);
649 c.Fill();
650 c.MoveTo(x, curpos);
651 c.LineTo(x, curpos+10);
652 c.Color = new Color(0, 0, 0);
653 c.Stroke();
656 curpos += 15;
660 public void DrawConnections(Context c)
662 int curpos = y+15+(h-20-CalcHeight(socketout.Length))/2;
664 c.LineWidth = 1.0;
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);
674 else
675 c.LineTo(socketout[i].Other.PX, socketout[i].Other.PY+5);
677 c.Stroke();
680 curpos += 15;
684 private int CalcHeight(int sockets)
686 return Math.Max(sockets*10 + (sockets-1)*5, 0);
689 private void DrawPath(Context c)
691 if(ConfigRound)
692 DrawPathRound(c);
693 else
694 DrawPathSquare(c);
697 private void DrawPathRound(Context c)
699 // 1-------2
700 // | |
701 // | |
702 // 4-------3
704 // 1
705 c.MoveTo(x+10, y);
706 c.LineTo(x+w-10, y);
707 // 2
708 c.CurveTo(x+w, y, x+w, y, x+w, y+10);
710 // gniazda wyjściowe
711 if(socketout.Length == 0)
712 c.LineTo(x+w, y+h-10);
713 else
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++)
721 if(i!=0)
723 curpos += 5;
724 c.LineTo(x+w, curpos);
727 c.CurveTo(x+w-10, curpos, x+w-10, curpos+10, x+w, curpos+10);
728 curpos += 10;
731 c.LineTo(x+w,y+h-10);
734 // 3
735 c.CurveTo(x+w, y+h, x+w, y+h, x+w-10, y+h);
736 c.LineTo(x+10, y+h);
737 // 4
738 c.CurveTo(x, y+h, x, y+h, x, y+h-10);
740 // gniazda wejściowe
741 if(socketin.Length == 0)
742 c.LineTo(x, y+10);
743 else
745 int curpos = y+h-10-(h-20-CalcHeight(socketin.Length))/2;
747 c.LineTo(x, curpos);
749 for(int i=0; i<socketin.Length; i++)
751 if(i!=0)
753 curpos -= 5;
754 c.LineTo(x, curpos);
757 c.CurveTo(x+10, curpos, x+10, curpos-10, x, curpos-10);
758 curpos -= 10;
761 c.LineTo(x,y+10);
764 // 1
765 c.CurveTo(x, y, x, y, x+10, y);
768 private void DrawPathSquare(Context c)
770 // 1-------2
771 // | |
772 // | |
773 // 4-------3
775 // 1
776 c.MoveTo(x, y);
777 c.LineTo(x+w, y);
779 // 2
780 // gniazda wyjściowe
781 if(socketout.Length == 0)
782 c.LineTo(x+w, y+h);
783 else
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++)
791 if(i!=0)
793 curpos += 5;
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);
801 curpos += 10;
804 c.LineTo(x+w,y+h);
807 // 3
808 c.LineTo(x, y+h);
810 // 4
811 // gniazda wejściowe
812 if(socketin.Length == 0)
813 c.LineTo(x, y);
814 else
816 int curpos = y+h-10-(h-20-CalcHeight(socketin.Length))/2;
818 c.LineTo(x, curpos);
820 for(int i=0; i<socketin.Length; i++)
822 if(i!=0)
824 curpos -= 5;
825 c.LineTo(x, curpos);
828 c.LineTo(x+8, curpos);
829 c.LineTo(x+8, curpos-10);
830 c.LineTo(x, curpos-10);
832 curpos -= 10;
835 c.LineTo(x,y+10);
839 c.LineTo(x, y);
840 c.LineTo(x+1, y);
843 private void DrawPathInner(Context c)
845 if(ConfigRound)
846 DrawPathInnerRound(c);
847 // TODO
848 // else
849 // DrawPathInnerSquare(c);
853 private void DrawPathInnerRound(Context c)
855 // 1-------2
856 // | |
857 // | |
858 // 4-------3
860 // 1
861 c.MoveTo(x+11.5, y+1.5);
862 c.LineTo(x+w-11.5, y+1.5);
863 // 2
864 c.CurveTo(x+w-1.5, y+1.5, x+w-1.5, y+1.5, x+w-1.5, y+8.5);
866 // gniazda wyjściowe
867 if(socketout.Length == 0)
868 c.LineTo(x+w-1.5, y+h-11.5);
869 else
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++)
877 if(i!=0)
879 curpos += 5;
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);
884 curpos += 10;
887 c.LineTo(x+w-1.5, y+h-8.5);
890 // 3
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);
893 // 4
894 c.CurveTo(x+1.5, y+h-1.5, x+1.5, y+h-1.5, x+1.5, y+h-8.5);
896 // gniazda wejściowe
897 if(socketin.Length == 0)
898 c.LineTo(x+1.5, y+11.5);
899 else
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++)
907 if(i!=0)
909 curpos -= 5;
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);
914 curpos -= 10;
917 c.LineTo(x+1.5, y+8.5);
920 // 1
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;
927 Plugin.Invalidate();
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()
940 Invalidate(true);
941 schematic.QueueDraw();
944 public void SlotsChanged()
946 UpdateCoordinates();
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];
957 else
958 newsocketin[i] = new Socket(0, curpos, this, Socket.T.In, i);
959 curpos += 15;
961 for(int i=plugin.NumIn; i<socketout.Length; i++)
962 socketout[i].Disconnect();
964 socketin = newsocketin;
966 else
968 int curpos = 10+(h-20-CalcHeight(socketin.Length))/2;
970 for(int i=0; i<socketin.Length; i++)
972 socketin[i].Y = curpos;
973 curpos += 15;
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];
986 else
987 newsocketout[i] = new Socket(w-10, curpos, this, Socket.T.Out, i);
988 curpos += 15;
990 for(int i=plugin.NumOut; i<socketout.Length; i++)
991 socketout[i].Disconnect();
993 socketout = newsocketout;
995 else
997 int curpos = 10+(h-20-CalcHeight(socketout.Length))/2;
999 for(int i=0; i<socketout.Length; i++)
1001 socketout[i].Y = curpos;
1002 curpos += 15;
1006 schematic.QueueDraw();
1007 Invalidate();