source: trunk/src/mouse_up.m @ 681

Last change on this file since 681 was 681, checked in by sommeria, 11 years ago

mouse action improved for translations, use of magenta color to indicate that REFRESH is needed

File size: 20.3 KB
Line 
1%'mouse_up': function  activated when the mouse button is released
2%------------------------------------------------------------------------
3% function mouse_up(hObject,eventdata,handles)
4% activated by the command:
5% set(hObject,'WindowButtonUpFcn',{'mouse_up'}),
6% where hObject is the handle of the figure
7
8%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
9%  Copyright Joel Sommeria, 2008, LEGI / CNRS-UJF-INPG, sommeria@coriolis-legi.org.
10%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
11%     This file is part of the toolbox UVMAT.
12%
13%     UVMAT is free software; you can redistribute it and/or modify
14%     it under the terms of the GNU General Public License as published by
15%     the Free Software Foundation; either version 2 of the License, or
16%     (at your option) any later version.
17%
18%     UVMAT is distributed in the hope that it will be useful,
19%     but WITHOUT ANY WARRANTY; without even the implied warranty of
20%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21%     GNU General Public License (file UVMAT/COPYING.txt) for more details.
22%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
23
24function mouse_up(hObject,eventdata,handles)
25
26test_ruler=0;%default
27AxeData=get(gca,'UserData');
28if isfield(AxeData,'ParentAxes')% case of a zoom plot as current axis
29    hcurrentaxes=AxeData.ParentAxes;
30    AxeData=get(hcurrentaxes,'UserData');
31    hcurrentfig=get(hcurrentaxes,'parent');%handles of the GUI parent of the zoom plot
32    testsubplot=1;% mouse selection is on a zoom subplot
33else
34    hcurrentfig=hObject;
35    hcurrentaxes=gca; %store the current axes handle
36    testsubplot=0;
37end
38CurrentOrigin=[];
39if isfield(AxeData,'CurrentOrigin')
40    CurrentOrigin=AxeData.CurrentOrigin;
41end
42FigTag=get(hcurrentfig,'tag');
43hhcurrentfig=guidata(hcurrentfig);%the current figure is a GUI (uvmat or view_field)
44CheckZoom=get(hhcurrentfig.CheckZoom,'Value');
45CheckZoomFig=get(hhcurrentfig.CheckZoomFig,'Value');%exclusive to CheckZoom
46huvmat=findobj(allchild(0),'tag','uvmat');%find the uvmat interface handle
47if ~isempty(huvmat)
48    hhuvmat=guidata(huvmat);
49    UvData=get(huvmat,'UserData');
50   test_ruler=~CheckZoom && isequal(get(hhuvmat.MenuRuler,'checked'),'on');%test for ruler  action, second priority
51end
52test_drawing=0;%default, =1 to allow drawing by further mouse action
53if ~(isfield(AxeData,'Enable')&& strcmp(AxeData.Enable,'on'))
54    return
55end
56xy=get(gca,'CurrentPoint');%xy(1,1),xy(1,2): current x,y positions in axes coordinates
57
58
59%% proceed with the creation or editing (translation/deformation) of an object
60if ~isempty(huvmat) && isfield(AxeData,'Drawing') && ~isequal(AxeData.Drawing,'off') && isfield(AxeData,'CurrentObject')...
61        && ~isempty(AxeData.CurrentObject) && ishandle(AxeData.CurrentObject)
62    %     xy=get(currentaxes,'CurrentPoint');%xy(1,1),xy(1,2): current x,y positions in axes coordinates
63    PlotData=get(AxeData.CurrentObject,'UserData');%get data attached to the current projection object
64    IndexObj=PlotData.IndexObj;
65    ObjectData=UvData.ProjObject{IndexObj};
66    check_multiple=0;
67   
68    h_set_object=findobj(allchild(0),'Tag','set_object');
69    hh_set_object=guidata(h_set_object);
70    ObjectData.Coord=get(hh_set_object.Coord,'Data');
71   
72    % ending translation
73    if isequal(AxeData.Drawing,'translate')
74        XYData=AxeData.CurrentOrigin;
75        DX=xy(1,1)-XYData(1);%translation from initial position
76        DY=xy(1,2)-XYData(2);
77        ObjectData.Coord(:,1)=ObjectData.Coord(:,1)+DX;
78        ObjectData.Coord(:,2)=ObjectData.Coord(:,2)+DY;
79        set(hh_set_object.Coord,'Data',ObjectData.Coord);
80        %ending object deformation
81    elseif isequal(AxeData.Drawing,'deform')
82        ind_move=AxeData.CurrentIndex;
83        ObjectData.Coord(ind_move,1)=xy(1,1);
84        ObjectData.Coord(ind_move,2)=xy(1,2);
85        set(hh_set_object.Coord,'Data',ObjectData.Coord);
86        %creating object
87    else
88        switch ObjectData.Type
89            case {'line'}
90                if size(ObjectData.Coord,1)==1 % this is the mouse up for the first point, continue until next click
91                    check_multiple=1;
92                else
93                    %ObjectData.Coord=[ObjectData.Coord ;CurrentOrigin];% append the second point of the line (the last pointed position during mouse down)
94                end
95            case {'rectangle','ellipse','volume'}
96                %                  if size(ObjectData.Coord,1)==1 % this is the mouse up for the first point, continue until next click
97                %                     check_multiple=1;
98                %                  else
99                ObjectData.Coord=(CurrentOrigin+xy(1,1:2))/2;% keep only the first point coordinate
100                ObjectData.RangeX=abs(ObjectData.Coord(1,1)-xy(1,1));%rectangle width
101                ObjectData.RangeY=abs(ObjectData.Coord(1,2)-xy(1,2));%rectangle height
102                if isequal(ObjectData.RangeX,0)||isequal(ObjectData.RangeY,0)
103                    check_multiple=1;% pass to next mous up if width of height=0
104                end
105                %                 ObjectData.Coord(1,1)=(xy(1,1)+XYData(1))/2;%origin rectangle, x coordinate
106                %                 ObjectData.Coord(1,2)=(xy(1,2)+XYData(2))/2;
107                %                 ObjectData.RangeX=abs(xy(1,1)-XYData(1))/2;%rectangle width
108                %                 ObjectData.RangeY=abs(xy(1,2)-XYData(2))/2;%rectangle height
109                %                  end
110            case 'plane' %case of 'plane'
111                DX=(xy(1,1)-ObjectData.Coord(1,1));
112                DY=(xy(1,2)-ObjectData.Coord(1,2));
113                ObjectData.Phi=(angle(DX+i*DY))*180/pi;%rectangle width
114                if isfield(ObjectData,'RangeX')
115                    XMax=sqrt(DX*DX+DY*DY);
116                    if XMax>max(ObjectData.RangeX)
117                        ObjectData.RangeX=[min(ObjectData.RangeX) XMax];
118                    end
119                end
120            otherwise
121                check_multiple=1;
122        end
123    end
124   
125    %show object coordinates in the GUI set_object
126    %     h_set_object=findobj(allchild(0),'Tag','set_object');
127    %     hh_set_object=guidata(h_set_object);
128    %     set(hh_set_object.Coord,'Data',ObjectData.Coord);
129    if strcmp(ObjectData.Type,'rectangle')||strcmp(ObjectData.Type,'ellipse')
130        set(hh_set_object.num_RangeX_2,'String',num2str(ObjectData.RangeX,4));
131        set(hh_set_object.num_RangeY_2,'String',num2str(ObjectData.RangeY,4));
132    end
133   
134    %% stop drawing and plot the projected field if the object manipulation is finished
135    if check_multiple==0  || isequal(get(hcurrentfig,'SelectionType'),'alt')
136        AxeData.CurrentOrigin=[]; %suppress the current origin
137        hobject=UvData.ProjObject{IndexObj}.DisplayHandle.(FigTag);
138        if ~isempty(hObject)
139            ProjObject=UvData.ProjObject{get(hhuvmat.ListObject_1,'Value')};
140            AxeData.CurrentObject=plot_object(ObjectData,ProjObject,hobject,'m');%draw the object and its handle becomes AxeData.CurrentObject
141        end
142        %%
143        if  ~isempty(ObjectData)
144            % plot the field projected on the object
145            ProjData= proj_field(UvData.Field,ObjectData);%project the current interface field on ObjectData
146            if ~isempty(ProjData)
147                if strcmp(FigTag,'uvmat')% uvmat plot selected, projection plot seen in view_field
148                    hview_field=findobj(allchild(0),'tag','view_field');
149                    if isempty(hview_field)
150                        hview_field=view_field(ProjData); %open the view_field GUI for plot
151                    else
152                        hhview_field=guidata(hview_field);
153                        [PlotType,PlotParam]=plot_field(ProjData,hhview_field.PlotAxes,read_GUI(hview_field));%update an existing  plot in view_field
154                        errormsg=fill_GUI(PlotParam,hview_field);
155                    end
156                    ViewFieldData=get(hview_field,'UserData');
157                    haxes=findobj(hview_field,'tag','axes3');
158                    if strcmp(get(haxes,'Visible'),'off')%sempty(PlotParam.Coordinates)% case of no plot display (pure text table)
159                        h_TableDisplay=findobj(hview_field,'tag','TableDisplay');
160                        pos_table=get(h_TableDisplay,'Position');
161                        pos=get(hview_field,'Position');
162                        set(hview_field,'Position',[pos(1)+pos(3)-pos_table(3) pos(2)+pos(4)-pos_table(4) pos_table(3) pos_table(4)])
163                        drawnow
164                        set(hview_field,'UserData',ViewFieldData);% restore the previously stored GUI position after GUI resizing
165                    elseif isfield(ViewFieldData,'GUISize')
166                        set(hview_field,'Position',ViewFieldData.GUISize)
167                    end
168                else
169                    UvData.PlotAxes=ProjData;
170                    [PlotType,PlotParam]=plot_field(ProjData,hhuvmat.PlotAxes,read_GUI(huvmat));%update an existing field plot
171                    errormsg=fill_GUI(PlotParam,huvmat);
172                end
173            end
174            set(hhuvmat.CheckViewField,'Value',1);%
175            set(hhuvmat.CheckEditObject,'Value',1);%           
176            set(hhuvmat.CheckEditObject,'Enable','on');%
177            set(get(h_set_object,'children'),'Enable','on')
178        end
179        UvData.ProjObject{IndexObj}=ObjectData;
180        if isfield(UvData.ProjObject{IndexObj},'CreateMode')
181            UvData.ProjObject{IndexObj}=rmfield(UvData.ProjObject{IndexObj},'CreateMode');%remove createMode to mark the object as finished
182        end
183    else
184        test_drawing=1;%allow continuation of drawing object
185        AxeData.CurrentOrigin=[xy(1,1) xy(1,2)]; %the current point becomes the next current origin
186    end
187    %     UvData.ProjObject{IndexObj}=ObjectData;
188    hother=findobj('Tag','deformpoint');%find all the deformpoints
189    set(hother,'Color','b');%reset all the deformpoints in 'blue'
190end
191
192%% creation or update of a  zoom sub-plot
193if CheckZoomFig && isequal(get(hcurrentfig,'SelectionType'),'normal')&&...%if left button has been pressed
194     ~isempty(CurrentOrigin) && ~isequal(CurrentOrigin(1),xy(1,1)) && ~isequal(CurrentOrigin(2),xy(1,2))%if mouse moved in x and y since presed down
195    hparentfig=hcurrentfig;
196    %open or update a new zoom figure if a rectangle has been drawn
197    if ishandle(hcurrentaxes);
198        if isfield(AxeData,'CurrentRectZoom') && ~isempty(AxeData.CurrentRectZoom) && ishandle(AxeData.CurrentRectZoom)
199            %PosRect=get(AxeData.CurrentRectZoom,'Position');
200            if isfield(AxeData,'CurrentVec') && ~isempty(AxeData.CurrentVec) && ishandle(AxeData.CurrentVec)
201                delete(AxeData.CurrentVec)
202            end
203            if ~testsubplot% if we are not already on a zoom plot
204                hfig2=findobj(allchild(0),'Tag','zoom_fig');
205                if isempty(hfig2)% create zoom sub plot if absent
206                    hfig2=figure('name',['zoom_' FigTag],'tag','zoom_fig');%create new figure (unit='pixels' by default)
207                    set(0,'Unit','pixels')
208                    FigPos=get(hfig2,'Position');%get the standard width and height of the fig
209                    ScreenSize=get(0,'ScreenSize');% get the size of the screen, to put the fig on the upper right
210                    Left=ScreenSize(3)- FigPos(3)-40; %right edge close to the right, with margin=40
211                    Bottom=ScreenSize(4)-FigPos(4)-40; %put fig at top right
212                    FigPos(1:2)=[Left Bottom];
213                    set(hfig2,'Position',FigPos);% put the zoom fig close to the upper right of the screen
214                    map=colormap(hcurrentaxes);
215                    colormap(map);%transmit the current colormap to the zoom fig
216                    set(hfig2,'KeyPressFcn',{@keyboard_callback,handles})%set keyboard action function
217                    set(hfig2,'WindowButtonMotionFcn',{@mouse_motion,handles})%set mouse action function
218                    set(hfig2,'WindowButtonDownFcn',{@mouse_down})%set mouse click action function
219                    set(hfig2,'WindowButtonUpFcn',{@mouse_up,handles})
220                else
221                    zoom_axes=findobj(hfig2,'Type','axes');%delete existing axes
222                    axes(zoom_axes);%make the zoom axes apparent
223                    delete(zoom_axes)
224                end
225                set(hfig2,'DeleteFcn',{@close_fig,AxeData.CurrentRectZoom})
226                set(hfig2,'UserData',AxeData.CurrentRectZoom)% record the parent object (zoom rectangle) in the new fig   
227                AxeData.ZoomAxes=copyobj(hcurrentaxes,hfig2); %copy the current graph axes to the zoom figure
228                hrect_zoom=findobj(AxeData.ZoomAxes,'Tag','rect_zoom');%find and delete the copy of the rect_zoom rectangle
229                delete(hrect_zoom)
230                hcol=findobj(hparentfig,'Tag','Colorbar'); %look for colorbar axes
231                if ~isempty(hcol)
232                    hcol_new=colorbar;
233                    YTick=get(hcol,'YTick');
234                    YTicklabel=get(hcol,'Yticklabel');
235                    colbarlim=get(hcol,'YLim');
236                    newcolbarlim=get(hcol_new,'YLim');
237                    scale_bar=(newcolbarlim(2)-newcolbarlim(1))/(colbarlim(2)-colbarlim(1));
238                    YTick_rescaled=newcolbarlim(1)+scale_bar*(YTick-colbarlim(1));
239                    set(hcol_new,'YTick',YTick_rescaled);
240                    set(hcol_new,'Yticklabel',YTicklabel);
241                end
242                ChildAxeData=get(AxeData.ZoomAxes,'UserData');
243            end 
244            ChildAxeData.CurrentOrigin=[];% forget the current origin
245            ChildAxeData.CurrentRectZoom=[]; % no rect zoom in the new window
246            ChildAxeData.Drawing='off';
247            ChildAxeData.ParentAxes=hcurrentaxes;
248            ChildAxeData.ParentRect=AxeData.CurrentRectZoom;%set the rectangle drawing as a 'parent' associated to the new axe
249            %PosRect=CurrentOrigin;
250           % xy=get(hcurrentaxes,'CurrentPoint');%xy(1,1),xy(1,2): current x,y positions in axes coordinates
251            if xy(1,1)>CurrentOrigin(1)
252            set(AxeData.ZoomAxes,'Xlim',[CurrentOrigin(1) xy(1,1)])
253            else
254                set(AxeData.ZoomAxes,'Xlim',[xy(1,1) CurrentOrigin(1)])
255            end
256            if xy(1,2)>CurrentOrigin(2)
257            set(AxeData.ZoomAxes,'Ylim',[CurrentOrigin(2) xy(1,2)])
258            else
259                set(AxeData.ZoomAxes,'Ylim',[xy(1,2) CurrentOrigin(2)])
260            end
261            set(AxeData.ZoomAxes,'UserData',ChildAxeData);%update the AxeData of the new axes
262        end
263    end
264end
265
266%% zoom in or out by a factor 2 if no new figure is created
267if CheckZoom
268    if testsubplot
269        haxes=gca;% zoom on a zoom sub-plot
270    else
271        haxes=hcurrentaxes;% zoom on the main plot
272    end
273   % xy=get(haxes,'CurrentPoint');%xy(1,1),xy(1,2): current x,y positions in axes coordinates
274    xlim=get(haxes,'XLim');
275    ylim=get(haxes,'YLim');
276    % if left mouse button has been pressed, zoom in by a factor of 2
277    if  isequal(get(gcf,'SelectionType'),'normal');%if left button has been pressed, zoom in by a factor of 2
278        PlotBoxAspectRatio=get(haxes,'PlotBoxAspectRatio');
279        yoverx=PlotBoxAspectRatio(2)/PlotBoxAspectRatio(1);
280        if yoverx <2
281            xlim(1)=0.5*xy(1,1)+0.5*xlim(1);
282            xlim(2)=0.5*xy(1,1)+0.5*xlim(2);%double the field whith the middle at the selected points
283            set(haxes,'XLim',xlim)
284        end
285        if yoverx >0.5
286            ylim(2)=0.5*xy(1,2)+0.5*ylim(2);
287            ylim(1)=0.5*xy(1,2)+0.5*ylim(1);
288            set(haxes,'YLim',ylim)
289        end
290       
291        % if right mouse button has been pressed, zoom out by a factor of 2
292    else
293        xlim(1)=2*xlim(1)-xy(1,1);% reverse of the zoom on action
294        xlim(2)=2*xlim(2)-xy(1,1);
295        ylim(1)=2*ylim(1)-xy(1,2);
296        ylim(2)=2*ylim(2)-xy(1,2);
297        % adjust the zoom out to the available field
298        if ~testsubplot && isfield(AxeData,'RangeX')&& isfield(AxeData,'RangeY')
299            xlim(1)=max(AxeData.RangeX(1),xlim(1));
300            xlim(2)=min(AxeData.RangeX(2),xlim(2));
301            ylim(1)=max(AxeData.RangeY(1),ylim(1));
302            ylim(2)=min(AxeData.RangeY(2),ylim(2));
303            if ylim(1)>=ylim(2)|| xlim(1)>=xlim(2)
304                xlim=AxeData.RangeX;
305                ylim=AxeData.RangeY;
306            end
307            % desactivate the zoom if the full field is visible within the axes
308            if isequal(xlim,AxeData.RangeX) && isequal(ylim,AxeData.RangeY)
309                set(hhuvmat.CheckZoom,'Value',0)
310               % set(hhuvmat.CheckZoom,'BackgroundColor',[0.7 0.7 0.7])
311                set(hhuvmat.CheckFixLimits,'Value',0)
312              %  set(hhuvmat.CheckFixLimits,'BackgroundColor',[0.7 0.7 0.7])
313            end
314        end
315        set(haxes,'XLim',xlim)
316        set(haxes,'YLim',ylim)
317        %test whther zoom out is operating (to inactivate AxedAta
318        if ~isfield(AxeData,'CurrentXLim')|| ~isequal(xlim,AxeData.CurrentXLim)
319            AxeData.CurrentXLim=xlim;%
320        end
321    end
322    %if isfield(AxeData,'LimEditBox')&& AxeData.LimEditBox% update display of the GUI containing the axis (uvmat or view_field)
323    if testsubplot
324        set(AxeData.CurrentRectZoom,'Position',[xlim(1) ylim(1) xlim(2)-xlim(1) ylim(2)-ylim(1)])
325    else
326        set(hhcurrentfig.num_MinX,'String',num2str(xlim(1)))
327        set(hhcurrentfig.num_MaxX,'String',num2str(xlim(2)))
328        set(hhcurrentfig.num_MinY,'String',num2str(ylim(1)))
329        set(hhcurrentfig.num_MaxY,'String',num2str(ylim(2)))
330    end
331end
332
333%% editing calibration point
334if ~CheckZoom && isfield(AxeData,'Drawing') && isequal(AxeData.Drawing,'calibration')
335    h_geometry_calib=findobj(allchild(0),'tag','geometry_calib'); %find the geomterty_calib GUI
336    if ~isempty(h_geometry_calib)
337        hh_geometry_calib=guidata(h_geometry_calib);
338        edit_test=get(hh_geometry_calib.CheckEnableMouse,'Value');
339        hh=findobj(hcurrentaxes,'tag','calib_points');%look for handle of calibration points
340        if ~isempty(hh) && edit_test
341            index_point=get(hh,'UserData');
342            set(hh,'UserData',[])%remove edit mode
343            h_ListCoord=hh_geometry_calib.ListCoord; %handles of the coordinate list
344            Coord=get(h_ListCoord,'Data');
345           % data=read_geometry_calib(Coord);
346            %         val=get(h_ListCoord,'Value');
347          %  xy=get(hcurrentaxes,'CurrentPoint');%xy(1,1),xy(1,2): current x,y positions in axes coordinates
348            Coord(index_point,4)=xy(1,1);
349            Coord(index_point,5)=xy(1,2);
350            set(h_ListCoord,'Data',Coord)
351%             for ipoint=1:size(Coord,1)
352%                 for jcoord=1:5
353%                     Coord_cell{ipoint,jcoord}=num2str(data.Coord(ipoint,jcoord),4);%display coordiantes with 4 digits
354%                 end
355%             end
356%             Tabchar=cell2tab(Coord_cell,' | ');
357%             Tabchar=[Tabchar ;{'......'}];
358%             set(h_ListCoord,'String',Tabchar)
359            set(hh,'XData',Coord(:,4))
360            set(hh,'YData',Coord(:,5))
361        end
362    end
363end
364
365%% finalising ruler
366if test_ruler && ~isempty(xy)
367    set(hhuvmat.MenuRuler,'checked','off')%desable the ruler option in uvmat
368    xy=get(hcurrentaxes,'CurrentPoint');% get the current mouse coordinates
369    RulerCoord=[AxeData.RulerCoord ;xy(1,1:2)];% append the recorded ruler origin to the current mouse coordinates
370    RulerCoord=diff(RulerCoord,1);% coordiante difference between segment end and beginning
371    RulerCoord=RulerCoord(1)+i*RulerCoord(2);
372    distance=abs(RulerCoord);
373    azimuth=(180/pi)*angle(RulerCoord);
374    msgbox_uvmat('RULER','',['length: ' num2str(distance,3) ',  angle(degrees): ' num2str(azimuth,3)])
375    delete(AxeData.RulerHandle)%delete the ruler graphic object
376    AxeData=rmfield(AxeData,'RulerHandle');%remove the ruler handle in AxeData
377    AxeData.Drawing='off';%exit the ruler drawing mode
378end
379
380
381%% update
382if test_drawing==0
383        AxeData.Drawing='off';%stop current drawing action
384end
385set(hcurrentaxes,'UserData',AxeData);
386if ~isempty(huvmat)
387    set(huvmat,'UserData',UvData);
388end
389
390%------------------------------------------------------------------------   
391% --- 'close_fig': function  activated when a zoom figure is closed
392%------------------------------------------------------------------------
393function close_fig(ggg,eventdata,hparent)
394
395hfig=get(get(hparent,'parent'),'parent');
396hbutton=findobj(hfig,'Tag','CheckZoomFig');
397if ~isempty(hbutton)
398    set(hbutton,'Value',0)% desactivate the zoom fig option
399end
400delete(hparent)  % delete the rectangle showing the zoom graph in the parent fig
401
Note: See TracBrowser for help on using the repository browser.