function out = hhsim_zoom(varargin) %ZOOM Zoom in and out on a 2-D plot. % ZOOM with no arguments toggles the zoom state. % ZOOM(FACTOR) zooms the current axis by FACTOR. % Note that this does not affect the zoom state. % ZOOM ON turns zoom on for the current figure. % ZOOM XON or ZOOM YON turns zoom on for the x or y axis only. % ZOOM OFF turns zoom off in the current figure. % % ZOOM RESET resets the zoom out point to the current zoom. % ZOOM OUT returns the plot to its current zoom out point. % If ZOOM RESET has not been called this is the original % non-zoomed plot. Otherwise it is the zoom out point % set by ZOOM RESET. % % When zoom is on, click the left mouse button to zoom in on the % point under the mouse. Click the right mouse button to zoom out. % Each time you click, the axes limits will be changed by a factor % of 2 (in or out). You can also click and drag to zoom into an area. % It is not possible to zoom out beyond the plots' current zoom out % point. If ZOOM RESET has not been called the zoom out point is the % original non-zoomed plot. If ZOOM RESET has been called the zoom out % point is the zoom point that existed when it was called. % Double clicking zooms out to the current zoom out point - % the point at which zoom was first turned on for this figure % (or to the point to which the zoom out point was set by ZOOM RESET). % Note that turning zoom on, then off does not reset the zoom out point. % This may be done explicitly with ZOOM RESET. % % ZOOM(FIG,OPTION) applies the zoom command to the figure specified % by FIG. OPTION can be any of the above arguments. % % Use LINKAXES to link zooming across multiple axes. % % See also PAN, LINKAXES. % Copyright 1993-2004 The MathWorks, Inc. % Internal use undocumented syntax (this may be removed in a future % release) % Additional syntax not already ded in zoom m-help % % ZOOM(FIG,'UIContextMenu',...) % Specify UICONTEXTMENU for use in zoom mode % ZOOM(FIG,'Constraint',...) % Specify constrain option: % 'none' - No constraint (default) % 'horizontal' - Horizontal zoom only for 2-D plots % 'vertical' - Vertical zoom only for 2-D plots % ZOOM(FIG,'Direction',...) % Specify zoom direction 'in' or 'out' % OUT = ZOOM(FIG,'IsOn') % Returns true if zoom is on, otherwise returns false. % OUT = ZOOM(FIG,'Constraint') % Returns 'none','horizontal', or 'vertical' % OUT = ZOOM(FIG,'Direction') % Returns 'in' or 'out' % Undocumented syntax that will never get documented % (but we have to keep it around for legacy reasons) % OUT = ZOOM(FIG,'getmode') 'in'|'out'|'off' % % Undocumented zoom object registration methods % OUT = ZOOM(FIG,'getzoom') % Get zoom object % ZOOM(FIG,'setzoom',...) % Set zoom object % Note: zoom uses the figure buttondown and buttonmotion functions % % ZOOM XON zooms x-axis only % ZOOM YON zooms y-axis only % ZOOM v6 off Switches to new zoom implementation % ZOOM v6 on Switches to old zoom implementation % ZOOM FILL scales a plot such that it is as big as possible % within the axis position rectangle for any azimuth and elevation. % Undocumented switch to v6 zoom implementation. This will be removed. if nargin==2 && ... isstr(varargin{1}) && ... strcmp(varargin{1},'v6') && ... isstr(varargin{2}) if strcmp(varargin{2},'on') localSetV6Zoom(true); else localSetV6Zoom(false); end return; end % Bypass to v6 zoom if localIsV6Zoom if nargout==0 v6_zoom(varargin{:}); else out = v6_zoom(varargin{:}); end return; end % Parse input arguments [target,action,action_data] = localParseArgs(varargin{:}); % If setting zoom object, ZOOM(H,HZOOM), then return early if strcmp(action,'setzoom') localRegisterZoomObject(action_data); return; end % Return early if target is not an axes or figure if isempty(target) || ... (~isa(target,'hg.axes') && ~isa(target,'hg.figure')) return; end hFigure = ancestor(target,'hg.figure'); % Return early if setting zoom off and there's no app data % this avoids making any objects or setting app data when % it doesn't need to. For example, hgload calls zoom(fig,'off') appdata = localGetData(hFigure); if strcmp(action,'off') && isempty(appdata.uistate) return; end % Get zoom object hZoom = localGetRegisteredZoomObject(hFigure); % Update zoom target in case it changed set(hZoom,'target',target); % Get current axes hCurrentAxes = get(hFigure,'CurrentAxes'); % Parse various zoom options change_ui = []; switch lower(action) case 'on' set(hZoom,'Constraint','none'); change_ui = 'on'; case 'xon' set(hZoom,'Constraint','horizontal'); change_ui = 'on'; case 'yon' set(hZoom,'Constraint','vertical'); change_ui = 'on'; case 'getzoom' out = hZoom; case 'getmode' if localIsZoomOn(hZoom) out = get(hZoom,'Direction'); else out = 'off'; end case 'constraint' out = get(hZoom,'Constraint'); case 'direction' out = get(hZoom,'Direction'); case 'ison' out = localIsZoomOn(hZoom); case 'ison' %TBD: Remove out = localIsZoomOn(hZoom); case 'getstyle' %TBD: Remove out = get(hZoom,'Constraint'); case 'getdirection' %TBD: Remove out = get(hZoom,'Direction'); case 'toggle' if localIsZoomOn(hZoom) change_ui = 'off'; else change_ui = 'on'; end % Undocumented legacy API, used by 'ident', see g194435 % It would be nice to get rid to dependencies on this API, but % many old toolboxes seem to be calling this API. case 'down' buttondownfcn(hZoom,'dorightclick',true); hLine = get(hZoom,'LineHandles'); if ishandle(hLine) % Mimic rbbox, don't return until line handles are % removed waitfor(hLine(1)); end case 'off' change_ui = 'off'; case 'inmode' set(hZoom,'Direction','in'); change_ui = 'on'; case 'outmode' set(hZoom,'Direction','out'); change_ui = 'on'; case 'scale' if ~isempty(hCurrentAxes) % Register current axes view for reset view support resetplotview(hCurrentAxes,'InitializeCurrentView'); applyzoomfactor(hZoom,hCurrentAxes,action_data); vc_vertslider_val; vc_slider_val; end case 'fill' if ~isempty(hCurrentAxes) resetplot(hZoom,hCurrentAxes); end case 'reset' resetplotview(hCurrentAxes,'SaveCurrentView'); case 'out' if ~isempty(hCurrentAxes) resetplot(hZoom,hCurrentAxes); end case 'setzoomproperties' % undocumented set(hZoom,action_data{:}); otherwise return end vc_vertslider_val; vc_slider_val; % Update the user interface if ~isempty(change_ui) localSetZoomState(hZoom,change_ui); end %-----------------------------------------------% function localSetZoomState(hZoom,state) hFigure = get(hZoom,'FigureHandle'); appdata = localGetData(hFigure); uistate = appdata.uistate; if strcmp(state,'on') % Turn off all other interactive modes if isempty(uistate) % Specify uninstaller callback: zoom(fig,'off') uistate = uiclearmode(double(hFigure),... 'docontext',... 'zoom',double(hFigure),'off'); % restore button down functions for uicontrol children of the figure uirestore(uistate,'uicontrols'); appdata.uistate = uistate; end % Enable zoom mode appdata.ison = true; set(hZoom,'IsOn',true); localSetData(hFigure,appdata); set(hFigure,'WindowButtonMotionFcn',{@localMotionFcn,hZoom}); set(hFigure,'WindowButtonUpFcn',[]) set(hFigure,'WindowButtonDownFcn',{@localWindowButtonDownFcn,hZoom}); set(hFigure,'KeyPressFcn',{@localKeyPressFcn,hZoom}); set(hFigure,'PointerShapeHotSpot',[5 5]); localMotionFcn(hFigure,[],hZoom); % Flush queue to update figure pointer display asap. drawnow expose; % Turn on Zoom UI (i.e. toolbar buttons, menus) % This must be called AFTER uiclear to avoid uiclear state munging zoom_direction = get(hZoom,'Direction'); switch zoom_direction case 'in' localUISetZoomIn(hFigure); case 'out' localUISetZoomOut(hFigure); end local_scribefiglisten(hFigure,'on'); % Define appdata to avoid breaking code in % scribefiglisten, hgsave, and figtoolset setappdata(hFigure,'ZoomOnState','on'); % zoom off elseif strcmp(state,'off') if ~isempty(uistate) % restore figure and non-uicontrol children % don't restore uicontrols because they were restored % already when zoom was turned on uirestore(uistate,'nouicontrols'); % Turn off Zoom UI (i.e. toolbar buttons, menus) localUISetZoomOff(hFigure); local_scribefiglisten(hFigure,'off'); % Remove uicontextmenu hui = get(hZoom,'UIContextMenu'); if ishandle(hui) delete(hui); end end % Reset appdata localRmData(hFigure); % Remove appdata to avoid breaking code in % scribefiglisten, hgsave, and figtoolset if isappdata(hFigure,'ZoomOnState'); rmappdata(hFigure,'ZoomOnState'); end end vc_vertslider_val; vc_slider_val; %-----------------------------------------------% function [bool] = localIsZoomOn(hZoom) % TBD, when zoom enabled property is wired correctly % do the following: %bool = strcmp(get(hZoom,'Enabled'),'on')); % For now, use app data hFigure = get(hZoom,'FigureHandle'); appdata = localGetData(hFigure); bool = appdata.ison; vc_vertslider_val; vc_slider_val; %-----------------------------------------------% function localWindowButtonDownFcn(hFigure,evd,hZoom) fig_sel_type = get(hFigure,'SelectionType'); fig_mod = get(hFigure,'CurrentModifier'); switch (lower(fig_sel_type)) case 'alt' % right click % display context menu hui = localGetContextMenu(hZoom); set(hui,... 'Position',get(hFigure,'CurrentPoint'),... 'Visible','on') otherwise % left click, center click, double click % Zoom out if user clicked on 'alt' if strcmp(fig_mod,'alt') switch get(hZoom,'Direction') case 'in' applyzoomfactor(hZoom,findaxes(hZoom),.9); vc_vertslider_val; vc_slider_val; case 'out' applyzoomfactor(hZoom,findaxes(hZoom),2); vc_vertslider_val; vc_slider_val; end % Delegate to registered zoom object else buttondownfcn(hZoom); end end vc_vertslider_val; vc_slider_val; %-----------------------------------------------% function localMotionFcn(hFigure,evd,hZoom) hTarget = handle(hittest(hFigure)); if ~isempty(ancestor(hTarget,'axes')) if strcmp(get(hZoom,'Direction'),'in') setptr(hFigure,'glassplus'); else setptr(hFigure,'glassminus'); end else setptr(hFigure,'arrow'); end vc_vertslider_val; vc_slider_val; slider_val; %-----------------------------------------------% function localKeyPressFcn(hFigure,evd,hZoom) % Delegate to registered zoom object keypressfcn(hZoom); %-----------------------------------------------% function [hZoom] = localGetRegisteredZoomObject(hFigure,dopeek) % TBD Get Zoom object from Figure Tool Manager hZoom = getappdata(hFigure,'ZoomObject'); if isempty(hZoom) || ~isa(hZoom,'graphics.zoom') hZoom = graphics.zoom(hFigure); setappdata(hFigure,'ZoomObject',hZoom); end vc_vertslider_val; vc_slider_val; slider_val; %-----------------------------------------------% function localRegisterZoomObject(hFigure,hZoom) hFigure = hZoom.FigureHandle; setappdata(hFigure,'ZoomObject',hZoom); vc_vertslider_val; vc_slider_val; slider_val; %-----------------------------------------------% function [appdata] = localGetData(fig) appdata = getappdata(fig,'ZoomFigureState'); if isempty(appdata) || ~isfield(appdata,'uistate') appdata.uistate = []; appdata.ison = false; end vc_vertslider_val; vc_slider_val; slider_val; %-----------------------------------------------% function localSetData(fig,appdata) setappdata(fig,'ZoomFigureState',appdata); vc_vertslider_val; vc_slider_val; slider_val; %-----------------------------------------------% function localRmData(fig) appdata = localGetData(fig); appdata.uistate = []; appdata.ison = false; localSetData(fig,appdata); vc_vertslider_val; vc_slider_val; slider_val; %-----------------------------------------------% function [hui] = localUICreateDefaultContextMenu(hZoom) % Create default context menu hFig = get(hZoom,'FigureHandle'); props_context.Parent = hFig; props_context.Tag = 'ZoomContextMenu'; props_context.Callback = {@localUIContextMenuCallback,hZoom}; props_context.ButtonDown = {@localUIContextMenuCallback,hZoom}; hui = uicontextmenu(props_context); % Generic attributes for all zoom context menus props.Callback = {@localUIContextMenuCallback,hZoom}; props.Parent = hui; props.Label = 'Zoom Out Alt-Click'; props.Tag = 'ZoomInOut'; props.Separator = 'off'; uzoomout = uimenu(props); % Full View context menu props.Label = 'Reset to Original View'; props.Tag = 'ResetView'; props.Separator = 'off'; ufullview = uimenu(props); % Zoom Constraint context menu props.Callback = ''; props.Label = 'Zoom Options'; props.Tag = 'Constraint'; props.Separator = 'on'; uConstraint = uimenu(props); props.Parent = uConstraint; props.Callback = {@localUIContextMenuCallback,hZoom}; props.Label = 'Unconstrained Zoom'; props.Tag = 'ZoomUnconstrained'; props.Separator = 'off'; uimenu(props); props.Label = 'Horizontal Zoom (2-D Plots Only)'; props.Tag = 'ZoomHorizontal'; uimenu(props); props.Label = 'Vertical Zoom (2-D Plots Only)'; props.Tag = 'ZoomVertical'; uimenu(props); localUIContextMenuUpdate(hZoom,get(hZoom,'Constraint')); %-----------------------------------------------% function [hui] = localGetContextMenu(hZoom) % Create context menu hui = get(hZoom,'UIContextMenu'); if isempty(hui) || ~ishandle(hui) local_scribefiglisten(get(hZoom,'Figure'),'off'); hui = localUICreateDefaultContextMenu(hZoom); local_scribefiglisten(get(hZoom,'Figure'),'on'); set(hZoom,'UIContextMenu',hui); localUIUpdateContextMenuLabel(hZoom); drawnow expose; end %-------------------------------------------------% function localUIContextMenuCallback(obj,evd,hZoom) tag = get(obj,'tag'); switch(tag) case 'ZoomInOut' switch get(hZoom,'Direction') case 'in' applyzoomfactor(hZoom,findaxes(hZoom),.9); vc_vertslider_val; vc_slider_val; case 'out' applyzoomfactor(hZoom,findaxes(hZoom),2); vc_vertslider_val; vc_slider_val; end case 'ResetView' hAxes = findaxes(hZoom); resetplotview(hAxes,'ApplyStoredView'); case 'ZoomContextMenu' localUIContextMenuUpdate(hZoom,get(hZoom,'Constraint')); case 'ZoomUnconstrained' localUIContextMenuUpdate(hZoom,'none'); case 'ZoomHorizontal' localUIContextMenuUpdate(hZoom,'horizontal'); case 'ZoomVertical' localUIContextMenuUpdate(hZoom,'vertical'); end %-------------------------------------------------% function localUIContextMenuUpdate(hZoom,zoom_Constraint) hFigure = get(hZoom,'FigureHandle'); ux = findall(hFigure,'Tag','ZoomHorizontal','Type','UIMenu'); uy = findall(hFigure,'Tag','ZoomVertical','Type','UIMenu'); uxy = findall(hFigure,'Tag','ZoomUnconstrained','Type','UIMenu'); switch(zoom_Constraint) case 'none' set(hZoom,'Constraint','none'); set(ux,'checked','off'); set(uy,'checked','off'); set(uxy,'checked','on'); case 'horizontal' set(hZoom,'Constraint','horizontal'); set(ux,'checked','on'); set(uy,'checked','off'); set(uxy,'checked','off'); case 'vertical' set(hZoom,'Constraint','vertical'); set(ux,'checked','off'); set(uy,'checked','on'); set(uxy,'checked','off'); end %-----------------------------------------------% function localUIMenuUpdate(fig) set(findall(fig,'Tag','figMenuZoomIn'),'Checked','on'); %-----------------------------------------------% function localUISetZoomIn(fig) set(uigettoolbar(fig,'Exploration.ZoomIn'),'State','on'); set(uigettoolbar(fig,'Exploration.ZoomOut'),'State','off'); %-----------------------------------------------% function localUISetZoomOut(fig) h = findall(fig,'type','uitoolbar'); set(uigettool(h,'Exploration.ZoomIn'),'State','off'); set(uigettool(h,'Exploration.ZoomOut'),'State','on'); %-----------------------------------------------% function localUISetZoomOff(fig) h = findall(fig,'type','uitoolbar'); set(uigettool(h,'Exploration.ZoomIn'),'State','off'); set(uigettool(h,'Exploration.ZoomOut'),'State','off'); % Remove the following lines after UITOOLBARFACTORY API is on by default set(findall(fig,'Tag','figToolZoomIn'),'State','off'); set(findall(fig,'Tag','figToolZoomOut'),'State','off'); %-----------------------------------------------% function localUIUpdateContextMenuLabel(hZoom); h = findobj(get(hZoom,'UIContextMenu'),'Tag','ZoomInOut'); zoom_direction = get(hZoom,'Direction'); if strcmp(zoom_direction,'in') set(h,'Label','Zoom Out Alt-Click'); else set(h,'Label','Zoom In Alt-Click'); end %-----------------------------------------------% function localSetNewZoom(bool) vc_vertslider_val; vc_slider_val; slider_val; setappdata(0,'NewZoomImplementation',bool); %-----------------------------------------------% function [target,action,action_data] = localParseArgs(varargin) target = []; action = []; action_data = []; errstr = {'Zoom:InvalidSyntax','Invalid Syntax'}; target = get(0,'CurrentFigure'); % zoom if nargin==0 action = 'toggle'; elseif nargin==1 arg1 = varargin{1}; % zoom(SCALE) if all(size(arg1)==[1,1]) & isnumeric(arg1) action = 'scale'; action_data = arg1; % zoom(OPTION) elseif isstr(arg1) action = arg1; % zoom(FIG) % zoom(HZOOM) elseif ishandle(arg1) if isa(handle(arg1),'graphics.zoom') target = get(arg1,'target'); action = 'setzoom'; elseif isa(handle(arg1),'hg.figure') target = arg1; action = 'toggle'; end else error(errstr{:}); end elseif nargin==2 % zoom('newzoom',0) if isstr(varargin{1}) action = varargin{1}; action_data = varargin{2}; % zoom(FIG,SCALE) % zoom(FIG,OPTION) elseif ishandle(varargin{1}) target = varargin{1}; arg2 = varargin{2}; if isstr(arg2) action = arg2; elseif isnumeric(arg2) action = 'scale'; action_data = arg2; end end % zoom(FIG,); elseif nargin>=3 target = varargin{1}; arg2 = varargin{2}; if ishandle(target) & isstr(arg2) action = 'setzoomproperties'; action_data = {varargin{2:end}}; end end target = handle(target); %-----------------------------------------------% function localSetV6Zoom(bool) setappdata(0,'V6Zoom',bool); %-----------------------------------------------% function [bool] = localIsV6Zoom bool = getappdata(0,'V6Zoom'); %-----------------------------------------------% function local_scribefiglisten(hFigure,val) scribefiglisten(hFigure,val);