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