replaces message by messagebox
[scilab.git] / scilab / modules / scicos / macros / scicos_scicos / getlink_qd.sci
1 //  Scicos
2 //
3 //  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
4 //                      - Alan Layec <alan.layec@inria.fr>
5 //                      - Simone Mannori <simone.mannori@scilab.org>
6 // //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // See the file ../license.txt
22 //
23
24 function [scs_m, needcompile] = getlink_qd(%pt, scs_m, needcompile)
25 //** Edition of a link from an output block to an input  block
26 //** using "Simulink like" orthogonal links only 
27 //** oblique links are not accepted ! 
28
29 //** 28/11/08: Preparation of the "SL" operation
30 //** 24/07/07: Al@n's patch for rotation of blocks
31
32 //** N.B : Please set %scicos_debug_gr="%t" to activate the debug mode 
33   %scicos_debug_gr = %f; 
34
35   outin = ['out','in']
36   //----------- get link origin --------------------------------------
37   //------------------------------------------------------------------
38   win = %win;
39   xc1 = %pt(1);
40   yc1 = %pt(2);
41
42   [kfrom, wh] = getblocklink(scs_m,[xc1;yc1]); //** recover information 
43                                                //** about the starting point
44   //** kfrom is the id of the selected block or link 
45
46   if kfrom<>[] then //** check for the presence of a valid output 
47     o1 = scs_m.objs(kfrom) ; //** acquire the object 
48   else
49     return ; //** EXIT if no valid output is found 
50   end
51
52   scs_m_save = scs_m;
53   nc_save    = needcompile; 
54
55   //** new graphics
56   gh_curwin = scf(%win) ;
57   gh_axes = gca();        //** acquire the current window handler
58
59
60   if typeof(o1)=="Link" then  //** add a split block
61     //** ------------------- start from a LINK ------------------------------
62
63     pt = [xc1;yc1] ; 
64     [xx,yy,ct,from,to] = (o1.xx,o1.yy,o1.ct,o1.from,o1.to);
65     if (-wh==size(xx,'*')) then
66       wh = -(wh+1) //** avoid with clicking at the end-point of link
67     end
68
69     //** get split type
70     [xout,yout,typout] = getoutputports(scs_m.objs(from(1))); 
71     clr = ct(1); 
72     [m,kp1] = mini((yc1-yout)^2+(xc1-xout)^2); 
73     k = kp1 ; 
74     typo = ct(2) ; 
75
76     if typo==-1 then //** old link comes from an event output port
77       typp = "evtout"
78     else //** old link comes from an regular output or input (implicit) port
79       typp = outin(from(3)+1)
80     end
81
82     //** get port size
83     szout = getportsiz(scs_m.objs(from(1)),from(2),typp)
84     //** get port data type
85     if typp=='out'|typp=='in' then
86      szouttyp = getporttyp(scs_m.objs(from(1)),from(2),typp)
87     end
88
89     //** get initial split position
90     wh = wh(1)
91     if wh>0 then
92       //** this function is used to compute the projection of the point
93       //** on the link segment 
94       d = projaff(xx(wh:wh+1), yy(wh:wh+1),pt); //** module/graphics/macro/
95       
96       //** orthogonal link logic 
97       if xx(wh)==xx(wh+1) //** this is a vertical link  
98         link_dir = "h" ; //** go horizontal from the split
99       elseif yy(wh)==yy(wh+1) //** this is an horizontal link 
100         link_dir = "v" ; //** go vertical from the split
101       else //** this is an oblique link 
102         if typo==-1 then //** old link comes from an event output port
103           link_dir = "v" ; //** go vertical for event link 
104         else //** old link comes from an regular output or input (implicit) port
105           link_dir = "h"; //** go horizontal for "normal" link 
106         end
107       end 
108
109     else //** the split is on a corner
110       wh = -wh ;
111       d  = [xx(wh);yy(wh)] ;
112         //** ortogonal link logic    
113         if typo==-1 then //** old link comes from an event output port
114           link_dir = "v" ; //** go vertical for event link 
115         else //** old link comes from an regular output or input (implicit) port
116          link_dir = "h"; //** go horizontal for "normal" link 
117         end
118     end
119
120     // Note : creation of the split block and modifications of links are
121     //        done later, the sequel assumes that the split block is added
122     //        at the end of scs_m
123     ks = kfrom; // selected link number
124     kfrom = size(scs_m.objs)+1;
125     port_number = 2; // to be created split block number
126
127     fromsplit = %t; 
128     // to be created link from origin
129
130     from = [kfrom,port_number,0] 
131     xo = d(1);yo=d(2)
132     xl = d(1);yl=d(2)
133     //** --------------------- "Link" case end here -------------------------- 
134   else // connection comes from a block
135     //** ------------------- start from a BLOCK ------------------------------
136     graphics1 = o1.graphics
137     orig  = graphics1.orig
138     sz    = graphics1.sz
139     theta = graphics1.theta
140     io    = graphics1.flip
141     op    = graphics1.pout
142     impi  = graphics1.pin
143     cop   = graphics1.peout
144     [xout,yout,typout] = getoutputports(o1)
145
146     i_ImplIndx = find(graphics1.in_implicit=='I');
147
148     if xout==[] then
149         hilite_obj(kfrom);
150         messagebox("This block has no output port",'modal'); 
151         unhilite_obj(kfrom);
152       return ; //** EXIT 
153     end
154
155     //** geometrical conversion for rotated block 
156     xxx = rotate([xout;yout],...
157                  theta*%pi/180,...
158                  [orig(1)+sz(1)/2; orig(2)+sz(2)/2]);
159     xout= xxx(1,:);
160     yout= xxx(2,:);
161
162     [m,kp1] = mini((yc1-yout)^2+(xc1-xout)^2) ; 
163     k = kp1 ; 
164     xo = xout(k); yo = yout(k); 
165     typo = typout(k) ; 
166
167     //** ---------------------- Checking ------------------------------------------- 
168     //** Check if the new requested link creation is compatible with the diagram 
169     // Check if selected port is already connected and get port type ('in' or 'out')
170
171     if typo==1  then //** Regular output port
172       port_number = k ;
173       link_dir = "h" ; //** output port starts horizontal link
174       if op(port_number)<>0 then
175           hilite_obj(kfrom)
176            messagebox(["Selected port is already connected.";..
177                     "To start a link off another link, place the cursor";..
178                     "on the split point and double click, or type l."],'modal')
179           unhilite_obj(kfrom); 
180         return
181       end
182       typpfrom='out'
183     elseif (typo==2 & k<=size(op,'*')) then //** Implicit output port (Modelica)
184       port_number = k ;
185       //** TODO : in case of Modelica port the choice is not yet clear :(  
186       link_dir = "h" ; //** use the default 
187       if op(port_number)<>0 then
188           hilite_obj(kfrom);
189           messagebox(["Selected port is already connected.";..
190                    "To start a link off another link, place the cursor";..
191                    "on the split point and double click, or type l."],'modal')
192           unhilite_obj(kfrom); 
193         return
194       end
195       typpfrom='out'
196     elseif (typo==2 & k>size(op,'*')+size(cop,'*')) then //** Implicit  input port
197       typpfrom = 'in' ; 
198       k = k-size(op,'*')-size(cop,'*'); 
199       port_number = i_ImplIndx(k)
200       //** TODO : in case of Modelica port the choice is not yet clear :(  
201       link_dir = "h" ; //** use the default
202       if impi(port_number)<>0 then
203           hilite_obj(kfrom) ; 
204           messagebox(["Selected port is already connected.";..
205                    "To start a link off another link, place the cursor";..
206                    "on the split point and double click, or type l."],"modal")
207           unhilite_obj(kfrom) ;
208         return
209       end
210       typpfrom='in'
211     else //** Event output port
212       port_number = k - size(op,'*') ;
213       //** In case of Event port the direction is strictly vertical  
214       link_dir = "v" ; //** 
215
216       if cop(port_number)<>0 then
217           hilite_obj(kfrom);
218           messagebox(["Selected port is already connected.";..
219                    "To start a link off another link, place the cursor";..
220                    "on the split point and double click, or type l."],"modal")
221           unhilite_obj(kfrom);
222         return ; 
223       end
224       typpfrom = 'evtout' ;
225     end
226     fromsplit = %f ; 
227     clr = default_color(typo) ;
228
229     //** get port size
230     szout = getportsiz(o1,port_number,typpfrom)
231     //** get port data type
232     if typpfrom=='out'|typpfrom=='in' then
233       szouttyp = getporttyp(o1,port_number,typpfrom); 
234     end
235
236     // to be created link from origin 
237     from = [kfrom,port_number, bool2s(typpfrom=='in'|typpfrom=='evtin')] ;
238     xl = xo ;
239     yl = yo ; 
240
241   end
242   //** ---------------------- Checking Ends ----------------------------------------
243   
244   //----------- get link path ----------------------------------------
245   //------------------------------------------------------------------
246
247   drawlater(); //** draw later mode
248   
249   //** These indexes will be used to destroy the intermediate objects created below
250   //** during the "interactive" section 
251
252   o_size = size(gh_axes.children) ; //** o_size(1) is the number of compound object
253   p_size = o_size ;
254
255   //** there are two nested infinite while(%t) loops:
256   //** the outher loop control the sequence of segment 
257   //**   the inner loop handle the interactive operation on the single link segment
258
259   //**------------------- OUTHER LOOP -----------------------------------------------------------
260   while %t do // loop on link segments
261     xe = xo; ye = yo ; //** o > origin ---- e > end
262     //** the first step is the the creation of a dummy graphic object (a link of ZERO leght)
263     //** and store this handler to modify it later 
264     xpoly([xo;xe] , [yo;ye], 'lines') ; //** create the first 'dummy' object
265     gh_link = gh_axes.children(1) ; //** the last object is the above link :)
266
267     //**----------------------------- INNER LOOP -------------------------------------------
268     rep(3) = -1; //** initialization (as Claudio Macchiavelli has teached me :) )
269     while %t do //** infinite loop
270       drawlater() ;
271       //** for positive event exit from the loop
272       //** Any event on the [right] button OR a window closing => END the inner loop
273       if or(rep(3)==[0,2,3,5,-5,-1000]) then
274          break; //** EXIT
275       end
276
277       //** otherwise ... get a new point
278
279       //** mouse event queque is cleared (15 Mar 2007 bugfix)
280       rep = xgetmouse([%t, %t]) ; //** looks better :)
281
282       gh_figure = gcf();
283       //** focus has changed OR active window has been closed
284       if gh_figure.figure_id<>curwin | rep(3)==-1000 then
285         [%win, Cmenu] = resume(curwin,'Quit'); 
286       end
287
288       //** any rigth mouse event OR [Esc] OR [d] key : I want to disengage the current Link action
289       if or(rep(3)==[2 5 12 27 100]) then
290           p_size = size(gh_axes.children); 
291           d_size = p_size(1)-o_size(1);
292           if d_size > 0 then
293             gh_compound_delete = glue(gh_axes.children(1:d_size) );
294             delete (gh_compound_delete); //** delete the object
295             drawnow(); //** update the screen
296           end
297
298           if %scicos_debug_gr then
299             disp("d1"); //** Debug
300           end
301           return; //** -----> Exit from the function
302       end //**
303
304       //** plot new link polyline 
305       xe = rep(1); ye = rep(2) ;
306
307       //** Now there are two cases (at least); split link and Modelica are not handled ....
308       if link_dir=="h" then
309         //** horizontal orthogonal link 
310         hdx = xo + (xe-xo)/2 ;
311         gh_link.data =  [xo yo ; hdx yo ; hdx ye ; xe ye ]; 
312       elseif link_dir=="v" then
313         //** vertical orthogonal link 
314         vdy = yo + (ye-yo)/2 ; 
315         gh_link.data =  [xo yo ; xo vdy ; xe vdy ; xe ye ];
316       end
317
318       gh_link.foreground = clr;   //** put the color here ( 5 = red )
319       drawnow(); //** update the buffer
320     end
321     //** ------------------------------- INNER LOOP END  ------------------------------
322
323     if %scicos_debug_gr then
324       disp("-->"); //** debug only
325     end
326
327     //** ---------- YOU ARE STILL IN THE "Link" Block-to-Block MAIN LOOP ----------------
328     //** The last segment end with [xe ye] coordinate:
329     //**
330     //** look for a block with a valid (good) input
331
332     kto = getblock(scs_m,[xe;ye]) ;
333     if kto<>[] then // new point designs the "to block"
334       o2 = scs_m.objs(kto);
335       graphics2 = o2.graphics;
336       orig  = graphics2.orig
337       sz    = graphics2.sz
338       theta = graphics2.theta
339       ip    = graphics2.pin
340       impo  = graphics2.pout
341       cip   = graphics2.pein
342       [xin,yin,typin] = getinputports(o2)
343
344       o_ImplIndx = find(graphics2.out_implicit=='I'); 
345
346       //** check connection
347       if xin==[] then
348          hilite_obj(kto)
349          messagebox("This block has no input port.","modal");
350          p_size = size(gh_axes.children);
351          d_size = p_size(1) - o_size(1);
352          if d_size > 0 then
353             gh_compound_delete = glue(gh_axes.children(1:d_size));
354              delete (gh_compound_delete); //** delete the object
355          end
356          if %scicos_debug_gr then
357            disp("d2");   //** Debug
358          end
359          unhilite_obj(kto);
360          drawnow(); //** update the diagram 
361          return;      //** EXIT point : link failed ! 
362       end
363
364       //** Connection is OK : compensate for block's rotation 
365
366       xxx = rotate([xin;yin],...
367                    theta*%pi/180,...
368                    [orig(1)+sz(1)/2;orig(2)+sz(2)/2]);
369       xin = xxx(1,:); yin = xxx(2,:);
370       [m,kp2] = mini((ye-yin)^2+(xe-xin)^2);
371       k = kp2 ;
372       xc2 = xin(k); yc2 = yin(k); 
373       typi = typin(k);
374
375       //** check connection for "type"
376       if typo<>typi
377         hilite_obj(kto)
378         messagebox(["Selected ports don''t have the same type"
379                  "The port at the origin of the link has type "+string(typo);
380                  "the port at the end has type "+string(typin(k))+'.'],"modal")
381           p_size = size(gh_axes.children)
382           d_size = p_size(1)-o_size(1);
383           if d_size > 0 then
384              gh_compound_delete = glue(gh_axes.children(1:d_size));
385              delete (gh_compound_delete); //** delete the object
386           end
387           if %scicos_debug_gr then
388              disp("d3"); //** Debug
389           end
390           unhilite_obj(kto)
391           drawnow(); 
392           return; //** EXIT point from the function
393       end
394
395       //** check if is a normal regular input port (not an event input port)
396       if typi==1  then // regular input port
397         port_number = k ;
398         if ip(port_number)<>0 then
399              hilite_obj(kto)
400              messagebox(["Selected port is already connected.";..
401                       "To start a link off another link, place the cursor";..
402                       "on the split point and double click, or type l."],'modal'),
403              p_size = size(gh_axes.children); 
404              d_size = p_size(1)-o_size(1);
405              if d_size > 0 then
406                gh_compound_delete = glue(gh_axes.children(1:d_size) );
407                delete (gh_compound_delete); //** delete the object
408              end
409              if %scicos_debug_gr then
410                disp("d4");//** Debug
411              end
412              unhilite_obj(kto);
413              drawnow();
414            return
415         end
416
417         typpto = 'in' ; 
418         szin = getportsiz(o2,port_number,'in')
419         
420         //** further check for warning message about "size" 
421         need_warning = %f ; //** flag initialization 
422         if (szin(1)<>szout(1)) & mini([szin(1) szout(1)])>0 then
423           need_warning = %t ; 
424         end
425
426         // check for different number of dimension
427         szout2 = []; szin2 = [];
428         if size(szout,'*')==1 then
429            szout2 = 1;
430         else
431            szout2 = szout(2);
432         end
433
434         if size(szin,'*')==1 then
435            szin2 = 1;
436         else
437            szin2 = szin(2);
438         end
439
440         if (szin2<>szout2) & mini([szin2 szout2])>0 then
441           need_warning = %t
442         end
443
444         if need_warning then
445             hilite_obj(kto)
446             messagebox(["Warning :";
447                      "Selected ports don''t have the same size";
448                      "The port at the origin of the link has size " + sci2exp(szout);
449                      "the port at the end has size " + sci2exp(szin)+"."],"modal")
450             unhilite_obj(kto)
451         end
452
453         // get port data type
454         // and say warning if doesn't match with szouttyp
455         szintyp = getporttyp(o2,port_number,'in')
456         if (szintyp>0 & szouttyp>0) then // if-then-else, event-select blocks case and all the -1 intyp/outtyp
457           if szintyp<>szouttyp then
458             tt_typ=['double';'complex';'int32';'int16';
459                     'int8';'uint32';'uint16';'uint8']
460
461             hilite_obj(kto)
462             messagebox(["Warning :";
463                      "Selected ports don''t have the same data type";
464                      "The port at the origin of the link has datatype "+...
465                       tt_typ(szouttyp)+' ('+sci2exp(szouttyp)+')';
466                      "the port at the end has datatype "+...
467                       tt_typ(szintyp)+' ('+sci2exp(szintyp)+')'+'.'],"modal")
468             unhilite_obj(kto);
469           end
470         end
471
472       elseif typi==2 & k<=size(ip,'*') then // implicit "input" port
473         port_number = k
474         if ip(port_number)<>0 then
475            messagebox(["Selected port is already connected.";..
476                     "To start a link off another link, place the cursor";..
477                     "on the split point and double click."],"modal"),
478            p_size = size(gh_axes.children)
479            d_size = p_size(1)-o_size(1);
480            if d_size > 0 then
481                gh_compound_delete = glue(gh_axes.children(1:d_size) );
482                delete (gh_compound_delete); //** delete the object
483            end
484            if %scicos_debug_gr then
485              disp("d5");//** Debug
486            end
487            drawnow();
488            return ; //** Exit point
489         end
490         typpto='in'
491         szin = getportsiz(o2,port_number,'in')
492
493         if szin<>szout & mini([szin szout])>0 then
494           messagebox(["Warning :';
495                    "Selected ports don''t have the same size";
496                    "The port at the origin of the link has size "+string(szout);
497                    "the port at the end has size "+string(szin)],"modal")
498         end
499
500       elseif (typi==2 & k>size(ip,'*')+size(cip,'*')) then // implicit "output" port
501         k = k-size(ip,'*')-size(cip,'*')
502         typpto='out'; 
503         port_number = o_ImplIndx(k)  //RN: explicit outputs are excluded
504                                      //    in the computation of k
505         if impo(port_number)<>0 then
506            messagebox(["Selected port is already connected.";..
507                     "To start a link off another link, place the cursor";..
508                     "on the split point and double click"],"modal"),
509            p_size = size(gh_axes.children);
510            d_size = p_size(1)-o_size(1);
511            if d_size > 0 then
512              gh_compound_delete = glue(gh_axes.children(1:d_size) );
513              delete (gh_compound_delete); //** delete the object
514            end
515            if %scicos_debug_gr then
516              disp("d6");//** Debug
517            end
518            drawnow();
519            return; //** Exit point
520         end
521         typpto='out'
522         szin=getportsiz(o2,port_number,'out')
523
524         if szin<>szout & mini([szin szout])>0 then
525           messagebox(["Warning :";
526                    "Selected ports don''t have the same  size";
527                    "The port at the origin of the link has size " + string(szout);
528                    "the port at the end has size " + string(szin)+'.'],"modal")
529         end
530
531       //** otherwise is an event input port
532       else // event input port
533
534         port_number = k-size(ip,'*');
535
536         if cip(port_number)<>0 then
537             hilite_obj(kto)
538             messagebox(["Selected port is already connected.";..
539                      "To start a link off another link, place the cursor";..
540                      "on the split point and double click."],"modal"),
541             p_size = size(gh_axes.children); 
542             d_size = p_size(1)-o_size(1);
543             if d_size > 0 then
544               gh_compound_delete = glue(gh_axes.children(1:d_size) );
545               delete (gh_compound_delete); //** delete the object
546             end
547             if %scicos_debug_gr then
548               disp("d7");//** Debug
549             end
550             unhilite_obj(kto)
551             drawnow();
552             return; //** Exit point
553         end
554
555         typpto = 'evtin'; 
556         szin = getportsiz(o2,port_number,'evtin'); 
557         if szin<>szout & mini([szin szout])>0 then
558           messagebox(["Warning :";
559                    "Selected ports don''t have the same  size"
560                    "The port at the origin of the link has size " + string(szout);
561                    "the port at the end has size " + string(szin)+'.'],"modal")
562         end
563
564       end
565       //** "fin" : this end a very long list of check on the final destination of the link *****
566    
567       if %scicos_debug_gr then
568         disp("|->>")
569       end
570   
571       //** update the link data vector for the phinal phase       
572         cmx = gh_link.data; //** recover the coordinates
573         //** add the coordinate at the vectors for the final link 
574         xl = [xl; cmx(2:4,1) ]; //** "x" colum, excluding the first element 
575         yl = [yl; cmx(2:4,2) ]; //** "y" colum,     "      "    "     " 
576       
577       break; //** this BREAK the outher loop and go at the final phase 
578
579     else // (kto==[]) new point ends current line segment: you remain in the outher loop 
580
581       if %scicos_debug_gr then
582           disp("d8"); //** Debug
583       end
584
585       if xe<>xo|ye<>yo then // to avoid null length segments
586
587         cmx = gh_link.data; //** recover the coordinates
588         //** add the coordinate at the vectors for the final link 
589         xl = [xl; cmx(2:4,1) ]; //** "x" colum, excluding the first element 
590         yl = [yl; cmx(2:4,2) ]; //** "y" colum,     "      "    "     " 
591
592         //** new "zero" coordinate for the next "poly"
593         xo = cmx(4,1) ; //** "xe" the final point is the new starting point 
594         yo = cmx(4,2) ; //** "ye"  "    "      "   "  "   "      "      "
595       end
596
597     end
598
599   end // This is the end of the outher loop (loop on link segments)
600   //**---------------------------------------------------------------------------------------------
601
602   gh_figure = gcf();
603   if gh_figure.figure_id<>curwin | rep(3)==-1000 then
604       //active window has been closed
605       [%win,Cmenu] = resume(curwin,'Quit')
606   end
607
608   typ = typo
609   to = [kto,port_number,bool2s(typpto=='in'|typpto=='evtin')]
610   nx = prod(size(xl))
611
612   if from==to then
613       messagebox(["Selected port is already connected.";..
614                "To start a link off another link, place the cursor";..
615                "on the split point and double click"],"modal"),
616       p_size = size(gh_axes.children)
617       d_size = p_size(1)-o_size(1);
618       if d_size > 0 then
619         gh_compound_delete = glue(gh_axes.children(1:d_size) );
620         delete (gh_compound_delete); //** delete the object
621         drawnow();
622       end
623       if %scicos_debug_gr then
624         disp("d9");//** Debug
625       end
626       drawnow();
627       return //** EXIT point
628   end
629
630   //**-----------------------------------------------------------------------------------
631   //** the link is a valid link
632
633   //** from here the data strucures are update BUT not draw !  
634   drawlater(); //** DO NOT UPDATE THE CANVAS ! 
635  
636 //   if nx==1 then // 1 segment link
637 // 
638 //     if fromsplit&(xl<>xc2|yl<>yc2) then
639 //       // try to move split point
640 //       if xx(wh)==xx(wh+1) then // split is on a vertical link
641 //         if (yy(wh)-yc2)*(yy(wh+1)-yc2)<0 then
642 //           yl = yc2 ;
643 //           gh_link.data =  [xl yl ; xc2 yc2] ; //** put the coordinate here
644 //         end
645 //       elseif yy(wh)==yy(wh+1) then //split is on a horizontal link
646 //         if (xx(wh)-xc2)*(xx(wh+1)-xc2)<0 then
647 //           xl = xc2 ;
648 //           gh_link.data = [xl yl ; xc2 yc2 ] ; //** put the coordinate here
649 //         end
650 //       end
651 //       d = [xl,yl]
652 //       //** Alan's fix, 17/10/07
653 //       //** create a point in the middle of the link
654 //       //** in the case of a direct link between two port
655 //       //** of the same block
656 //     elseif kto==kfrom then
657 //       xl = [xl;(xl+xc2)/2]
658 //       yl = [yl;(yl+yc2)/2]
659 //     end
660 //     //form link datas
661 //     xl = [xl;xc2];yl=[yl;yc2]
662 //   else
663 //     if xl(nx)==xl(nx-1) then
664 //       // previous segment is vertical
665 //       nx = prod(size(xl)) ;
666 //       gh_link_del = gh_axes.children(1) ;
667 //       delete( gh_link_del );
668 //       gh_link_del = gh_axes.children(1) ;
669 //       delete( gh_link_del );
670 //       xpoly([xl(nx-1) ; xl(nx) ; xc2] , [yl(nx-1) ; yc2 ; yc2] ,'lines');
671 //       gh_link = gh_axes.children(1) ;
672 //       gh_link.foreground = clr
673 //       // form link datas
674 //       xl = [xl;xc2]; yl = [yl(1:nx-1);yc2;yc2]
675 // 
676 //     //** ---- Previous segment is horizontal
677 //     elseif yl(nx)==yl(nx-1) then
678 //       // previous segment is horizontal
679 //       nx = prod(size(xl)) ;
680 //       gh_link_del = gh_axes.children(1) ;
681 //       delete( gh_link_del );
682 //       gh_link_del = gh_axes.children(1) ;
683 //       delete( gh_link_del );
684 //       xpoly([xl(nx-1);xc2;xc2],[yl(nx-1);yl(nx);yc2],'lines')
685 //       gh_link = gh_axes.children(1) ;
686 //       gh_link.foreground = clr
687 // 
688 //       // form link datas
689 //       xl = [xl(1:nx-1);xc2;xc2]; yl = [yl;yc2]
690 //     else 
691 //       // previous segment is oblique
692 //       // nothing particular is done
693 //       xl = [xl;xc2]; yl = [yl;yc2]
694 //     end
695 //   end
696
697   lk = scicos_link(xx=xl, yy=yl, ct=[clr,typ], from=from, to=to) ; 
698
699   //**---- Mr. Clean :) -----------------------------------------------------------------------
700   p_size = size(gh_axes.children) ; //** p_size(1) is the number of compound object
701   d_size = p_size(1) - o_size(1) ;  //** at the and of this "Link" operation
702   if d_size > 0 then
703     gh_compound_delete = glue(gh_axes.children(1:d_size) );
704     delete (gh_compound_delete); //** delete the object
705   end
706   //**------------------------------------------------------------------------------------------
707
708   //----------- update objects structure -----------------------------
709   //------------------------------------------------------------------
710
711   if fromsplit then // link comes from a split
712     nx=size(scs_m.objs)+1
713     //split old link
714     from1=o1.from
715     to1=o1.to
716     link1=o1;
717     link1.xx   = [xx(1:wh);d(1)];
718     link1.yy   = [yy(1:wh);d(2)];
719     link1.to   = [nx,1,1]
720
721     link2=o1;
722     link2.xx   = [d(1);xx(wh+1:size(xx,1))];
723     link2.yy   = [d(2);yy(wh+1:size(yy,1))];
724     link2.from = [nx,1,0];
725
726
727     // create split block
728     if typo==1 then
729       sp=SPLIT_f('define')
730       sp.graphics.orig = d;
731       sp.graphics.pin  = ks;
732       sp.graphics.pout = [nx+1;nx+2];
733
734       SPLIT_f('plot',sp)
735     elseif typo==2 then
736       sp=IMPSPLIT_f('define')
737       sp.graphics.orig = d;
738       sp.graphics.pin  = ks;
739       sp.graphics.pout = [nx+1;nx+2];
740       inoutfrom='out' 
741       IMPSPLIT_f('plot',sp)
742     else
743       sp=CLKSPLIT_f('define')
744       sp.graphics.orig  = d;
745       sp.graphics.pein  = ks;
746       sp.graphics.peout = [nx+1;nx+2];
747       CLKSPLIT_f('plot',sp)
748     end
749
750     glue(gh_axes.children(1) ); //** create the compound
751     //** be very careful: here the graphics datastructure has ONE more element than the
752     //** "scs_m.objs" ;)
753     //---------------------------
754       scs_m.objs(ks)   = link1 ; //** adjust the data of the first half of the old "splitted" link
755
756       gh_ks = get_gri(ks,o_size(1)) + 1 ; //** I need to compensate for the last entry
757
758       gh_axes.children(gh_ks).children.data = [ link1.xx , link1.yy]  ; //** update the graphics datastructure
759       link1_color = gh_axes.children(gh_ks).children.foreground       ; //** save the color
760
761       //---------------------------
762
763       scs_m.objs(nx)  = sp    ; //** the graphics datastructure is already up to date in "nx" position
764
765       //---------------------------
766
767       scs_m.objs(nx+1) = link2 ;
768
769       xpoly (link2.xx , link2.yy) ;
770       gh_axes.children(1).foreground = link1_color ;
771       glue(gh_axes.children(1) ); //** create the compound :)
772
773     //** update the diagram 
774     scs_m.objs(to1(1)) = mark_prt(scs_m.objs(to1(1)),to1(2),outin(to1(3)+1),typ,nx+1)
775
776   end
777
778   //**----------------------------------------------------------------------------------
779
780   //** add new link in objects structure
781   nx = size(scs_m.objs)+1 ;
782   scs_m.objs($+1) = lk ;
783
784   drawlater(); 
785     drawobj(lk) ;
786   drawnow();
787
788   //** update connected blocks
789   scs_m.objs(kfrom) = mark_prt(scs_m.objs(kfrom),from(2),outin(from(3)+1),typ,nx)
790   scs_m.objs(kto)   = mark_prt(scs_m.objs(kto),to(2),outin(to(3)+1),typ,nx)
791
792   needcompile = 4; 
793
794   [scs_m_save,nc_save,enable_undo,edited] = resume(scs_m_save,nc_save,%t,%t)
795
796 endfunction