Fix images in help after recent ja_JP version changes
[scilab.git] / scilab / modules / graphics / macros / datatips / datatipEventhandler.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2010-2011 - INRIA - Serge Steer <serge.steer@inria.fr>
3 //
4 // This file must be used under the terms of the CeCILL.
5 // This source file is licensed as described in the file COPYING, which
6 // you should have received as part of this distribution.  The terms
7 // are also available at;
8 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
9
10 function datatipEventhandler(win,x,y,ibut)
11     //datatip utility function
12     //The event handler which rules the datatips interactive edition;
13     fig=get_figure_handle(win);
14     global datatipAngles zoom_box;
15     if ibut<0 then
16         if ibut==-1000 then
17             global datatipGUIwin
18             if datatipGUIwin<>[]&or(datatipGUIwin==winsid()) then //the gui window isopened
19                 delete(get_figure_handle(datatipGUIwin))
20                 clearglobal datatipGUIHandles datatipGUICurve datatipGUIwin
21             end
22         end
23         //     ax=getAxes([x,y],fig);
24         //     if or(datatipAngles<>ax.rotation_angles)|or(zoom_box<>ax.zoom_box) then
25         //       datatipAngles=ax.rotation_angles;
26         //       zoom_box=ax.zoom_box;
27         //     end
28         return,
29     end
30
31     fig.event_handler_enable = "off";
32     ax=getAxes([x,y],fig);
33     sca(ax);
34     //change the pixel coordinates to user coordinates
35
36     [x,y]=xchange(x,y,"i2f");pt=[x,y]
37     if or(ibut==[127 100]) then //delete current
38         curve_handles=datatipGetEntities(ax);
39         datatipDeleteSelected(curve_handles)
40     elseif or(ibut==[37 39]) then //left and right arrows
41         curve_handles=datatipGetEntities(ax);
42         [curve,ind]=datatipGetSelected(curve_handles)
43         if ind<>[] then
44             ud=datatipGetStruct(curve)
45             tip_handle=ud.tips.children(ind)
46             point_handle=tip_handle.children(1)
47
48             if ibut==39 then
49                 k=point_handle.user_data(2)+1
50                 if k<=size(curve.data,1) then
51                     datatipSetTipPosition(ud,tip_handle,curve.data(k,:),k)
52                 end
53             else
54                 k=point_handle.user_data(2)-1
55                 if k>=1 then
56                     datatipSetTipPosition(ud,tip_handle,curve.data(k,:),k)
57                 end
58             end
59         end
60     elseif or(ibut==[0 3]) then //select a point on a curve
61
62         //find  curves in the current axes
63         curve_handles=datatipGetEntities(ax);
64         if curve_handles==[] then;
65             return,
66         end
67         //The datatip text box origins are given in user coordinates but their
68         //computation takes into account the pixel dimensions of the text
69         //boxes, so rotations and zoom requires a recomputation of the
70         //origins. There is currently
71         if datatipAngles==[] then
72             datatipAngles=ax.rotation_angles;
73             zoom_box=ax.zoom_box;
74         else
75             if or(datatipAngles<>ax.rotation_angles)|or(zoom_box<>ax.zoom_box) then
76                 datatipAngles=ax.rotation_angles;
77                 zoom_box=ax.zoom_box;
78             end
79         end
80         //check for a text box present near the selected point
81         [k,l]=datatipLookfor(curve_handles,pt);
82         if k<>[] then;
83             datatipSetSelected(curve_handles,[k,l])
84             if ibut==0 then
85                 ud=datatipGetStruct(curve_handles(k));
86                 tip_handle=ud.tips.children(l);
87                 datatipMove(tip_handle);
88             end
89             fig.event_handler_enable = "on";
90             return,
91         end
92         [curve,dmin,ptmin,l]=datatipGetNearestEntity(pt,curve_handles);
93         if dmin<10 then;
94             //small minimal distance, create a text box at this point (or move
95             //an existing tip at this point
96             ud=datatipGetStruct(curve);// the curve datatips data structure
97             if typeof(ud)<>"datatips" then;
98                 ud=datatipGetStruct(curve);
99             end
100             if ud.replace&ud.tips.children<>[] then
101                 tip_handle=ud.tips.children($)
102                 if ud.interpolate then
103                     datatipSetTipPosition(ud,tip_handle,ptmin,l)
104                 else
105                     datatipSetTipPosition(ud,tip_handle,curve.data(l,:),l)
106                 end
107             else
108                 if ud.interpolate then
109                     datatipCreate(curve,ptmin);
110                 else
111                     datatipCreate(curve,l); //
112                 end
113             end
114         else
115             //      unselect all
116             [curve,ind]=datatipGetSelected(curve_handles)
117             if ind<>[] then
118                 ud=datatipGetStruct(curve);
119                 tip_handle=ud.tips.children(ind);
120                 datatipHilite(tip_handle) //unhilite
121                 ud.selected=0
122                 datatipSetStruct(curve,ud);
123             end
124         end
125     elseif or(ibut==5) then
126         datatipContextMenu(ax)
127
128     elseif or(ibut==[1 4]) then //middle button
129         curve_handles=datatipGetEntities(ax);
130         [k,l]=datatipLookfor(curve_handles,pt);
131         if k<>[] then;
132             ud=datatipGetStruct(curve_handles(k))// the curve datatips data structure
133             tip_handle=ud.tips.children(l);
134             orient=["automatic" "upper left" "upper right", "lower left", "lower right"];
135             orientations=[_("automatic") _("upper left") _("upper right"), _("lower left"), _("lower right")];
136             r=x_choose(orientations,_("Select tip orientation"));
137             if r<>0 then
138                 datatipSetOrientation(tip_handle,orient(r));
139             end
140         end
141     elseif ibut==1004 then //Ctrl-D
142         curve_handles=datatipGetEntities(ax);
143         datatipDeleteSelected(curve_handles)
144     end
145     fig.event_handler_enable = "on";
146 endfunction
147
148 function [curve_index,tip_index]=datatipLookfor(curve_handles,pt)
149     //looks for a datatip in the neighborhood of a given point
150     //curve_handles:  a vector of curves which are supposed to have datatips
151     //pt           :  a 2D point in pixels
152     //curve_index  :  the index of corresponding curve in curve_handles
153     //tip_index    :  the datatip index for the curve;
154     for curve_index=1:size(curve_handles,"*")
155         ud=datatipGetStruct(curve_handles(curve_index));
156         if typeof(ud)=="datatips" then
157             tips=ud.tips.children;
158             for tip_index=1:size(tips,"*")
159                 data=tips(tip_index).children(1).data(1,:);
160                 if size(data,"*")==3 then
161                     [xx,yy]=geom3d(data(1),data(2),data(3));
162                     d=pixDist([xx,yy],pt)/2;
163                 else
164                     d=pixDist(data,pt);
165                 end
166                 if d<10 then return, end
167             end
168         end
169     end
170     curve_index=[];
171     tip_index=[];
172 endfunction
173
174 function [curve,dmin,ptmin,l]=datatipGetNearestEntity(pt,ax)
175     //looks for the nearest entity from a given point
176     //ax     : either a handle on a xes or a vector of handles on curves
177     //curve  : the handle on the nearest entity
178     //dmin   : euclidean distance in pixel from the given point to the
179     //         nearest curve
180     //ptmin  : the orthogonal projection of the point on the curve
181     //l      : index of the segment containing the projection
182
183     dmin=%inf;
184     l=0;
185     curve=[];
186     ptmin=[];
187     if argn(2)==1 then
188         //only a point given look into the axes where the point lies
189         ax=getAxes(pt);
190     end
191     if size(ax,"*")==0 then return,end
192     if size(ax,"*")==1&ax.type=="Axes" then
193         curves=datatipGetEntities(ax);
194     else
195         curves=ax;
196         if or(curves.type<>"Polyline") then
197             error(msprintf(_("%s: Wrong type for input argument #%d: A ''%s'' handle expected.\n"),...
198             "datatipGetNearestEntity",2,"Polyline"))
199         end
200     end
201     kmin=[]
202     for k=1:size(curves,"*")
203         ck=curves(k)
204         ax=ck.parent;
205
206         while ax.type<>"Axes" then ax=ax.parent,end
207         if ck.type=="Polyline" then
208             //find the polylines point with realizes the minimal euclidean
209             //distance with pt
210             if ax.view=="3d" then
211                 [xx,yy]=geom3d(ck.data(:,1),ck.data(:,2),ck.data(:,3))
212                 [d,ptp,ind,c]=orthProj([xx,yy],pt)
213
214             else
215                 [d,ptp,ind]=orthProj(ck.data,pt)
216             end
217             if ind<>[] then
218                 d= pixDist(ptp,pt);
219                 if d<dmin then
220                     dmin=d
221                     l=ind
222                     kmin=k,
223                     if ax.view=="3d" then
224                         ptmin=ck.data(l,:)+c*(ck.data(l+1,:)-ck.data(l,:))
225                     else
226                         ptmin=ptp
227                     end
228                 end
229             end
230         elseif ck.type=="Plot3d" then
231             [m,n]=size(ck.data.z);
232             [xx,yy]=geom3d(ck.data.x*ones(1,n),ones(m,1)*ck.data.y',ck.data.z);
233             [xx,yy]=xchange(xx,yy,"f2i");
234             [xp,yp]=xchange(pt(1),pt(2),"f2i");
235             [d,ind]=min(abs(xx-xp)+abs(yy-yp));
236             if d<dmin then
237                 dmin=d
238                 l=ind
239                 kmin=k,
240                 ptmin=[ck.data.x(l(1)) ck.data.y(l(2))  ck.data.z(l(1),l(2))]
241             end
242         end
243     end
244     curve=curves(kmin)
245 endfunction
246
247 function datatipSelectFunction(curve)
248     p=uigetfile("*.sci");
249     if p=="" then return,end
250     nold=size(who("get"),"*");
251     if execstr("exec(p,-1);","errcatch")<>0 then
252         messagebox([_("The selected file cannot be executed");lasterror()],"modal")
253         return
254     end
255     new=who("get");
256     new=new(1:$-nold-1);
257     if size(new,"*")<>1 then
258         messagebox(_("The selected file defines more than one function"))
259         return
260     end
261     datatipSetDisplay(curve,evstr(new));
262 endfunction
263
264 function datatipSetReplaceMode(curve_handle,m)
265     //changes the tips creation modes for a given curve
266     // curve_handle : a handle on a polyline
267     // m            : %t (interpolation active) or %f
268     if argn(2)==1 then m=%f,end
269     if type(curve_handle)<>9|or(curve_handle.type<>"Polyline") then
270         error(msprintf(_("%s: Wrong type for input argument #%d: A ''%s'' handle expected.\n"),...
271         "datatipCreate",1,"Polyline"))
272     end
273
274     ud=datatipGetStruct(curve_handle);
275     if typeof(ud)<>"datatips" then;
276         ud=datatipGetStruct(curve_handle);
277     end
278     ud.replace=m;
279     datatipSetStruct(curve_handle,ud);
280 endfunction
281
282 function ax_handle=getAxes(pt,fig)
283     //Returns the axes handle where a point given in pixel lies in the
284     //current (or given) figure
285     // pt        : the vector or coordinates in pixel in the figure
286     // fig       : optional handle on the figure
287     // ax_handle : selected axes handle
288     if argn(2)==1 then fig=gcf(),end
289     axes=get(fig,"children");
290     axes(axes.type=="uimenu")=[];
291     if size(axes,"*")==1 then ax_handle=axes;return,end
292     sz=fig.axes_size;
293     for k=1:size(axes,"*")
294         if axes(k).type <> "Axes" then // uicontrol
295             continue
296         end
297         ax_handle=axes(k);
298         xbounds=ax_handle.axes_bounds(:,1)*sz(1);
299         ybounds=ax_handle.axes_bounds(:,2)*sz(2);
300         if prod(xbounds-pt(1))<0&prod(ybounds-pt(2))<0 then break,end
301     end
302 endfunction
303
304