Home > vbmeg > functions > gui > vb_dragzoom.m

vb_dragzoom

PURPOSE ^

DRAGZOOM Drag and zoom tool

SYNOPSIS ^

function vb_dragzoom(varargin)

DESCRIPTION ^

DRAGZOOM Drag and zoom tool

 Description:
   DRAGZOOM allows you to interactively manage the axes in figure.
   This simple function for usable draging and zooming of axes, using the 
   mouse and the keyboard shortcuts.

   - Supported 2D-Plots, 3D-plots, semilogx-plots, semilogy-plots, loglog-plots and Images;
   - Supported subplots (mixed axes).


 Using:
   vb_dragzoom()
   vb_dragzoom(hFig)
   vb_dragzoom(hAx)
   vb_dragzoom(hAxes)
   vb_dragzoom(hFig, status)
   vb_dragzoom(status)


 Input:
   hObj -- Figure or axes handle or array of axes handles
   status -- 'on' or 'off'
             = '3d' or '2d' : 'on' and 3D/2D mode.


 Control Enable Status of DRAGZOOM:
   vb_dragzoom(hFig, 'on')     : Enable DRAGZOOM for figure "hFig"
   vb_dragzoom(hFig, 'off')     : Disable DRAGZOOM for figure "hFig"
   vb_dragzoom(hFig, '3d')     : set DRAGZOOM to "3D" mode.
   vb_dragzoom(hFig, '2d')     : set DRAGZOOM to "2d" mode.


 Interactive mode:
   Available the following actions:
 
   Mouse actions in 2D mode:
   Normal mode:
       single-click and holding LB : Activation Drag mode
       single-click and holding RB : Activation Rubber Band for region zooming
       single-click MB             : Activation 'Extend' Zoom mode
       scroll wheel MB             : Activation Zoom mode
       double-click LB, RB, MB     : Reset to Original View
 
   Magnifier mode:
       single-click LB             : Not Used
       single-click RB             : Not Used
       single-click MB             : Reset Magnifier to Original View
       scroll MB                   : Change Magnifier Zoom
       double-click LB             : Increase Magnifier Size
       double-click RB             : Decrease Magnifier Size
 
   Hotkeys in 2D mode:
       'uparrow'                   : Up or down (inrerse) drag
       'downarrow'                 : Down or up (inverse) drag
       'leftarrow'                 : Left or right (inverse) drag
       'rightarrow'                : Right or left (inverse) drag
       'c'                         : On/Off Pointer Symbol 'fullcrosshair'
       'g'                         : On/Off Axes Grid
       'x'                         : If pressed and holding, zoom and drag works only for X axis
       'y'                         : If pressed and holding, zoom and drag works only for Y axis
       'm'                         : If pressed and holding, Magnifier mode on
       'l'                         : On/Off Synchronize XY manage of 2-D axes 
       'control+l'                 : On Synchronize X manage of 2-D axes 
       'alt+l'                     : On Synchronize Y manage of 2-D axes 
       's'                         : On/Off Smooth Plot (Experimental)
 
   Mouse actions in 3D mode:
       single-click and holding LB : Activation Rotate mode
       single-click and holding MB : Activation 'Extend' Zoom mode
       single-click and holding RB : Activation Drag mode
       scroll wheel MB             : Activation Zoom mode
       double-click LB, RB, MB     : Reset to Original View
 
   Hotkeys in 3D mode:
       '+'                         : Zoom plus
       '-'                         : Zoom minus  
       '0'                         : Set default axes (reset to original view)
       'uparrow'                   : Rotate up-down
       'downarrow'                 : Rotate down-up
       'leftarrow'                 : Rotate left-right
       'rightarrow'                : Rotate right-left
       'ctrl'+'uparrow'            : Up or down (inrerse) drag
       'ctrl'+'downarrow'          : Down or up (inverse) drag
       'ctrl'+'leftarrow'          : Left or right (inverse) drag
       'ctrl'+'rightarrow'         : Right or left (inverse) drag
       '1'                         : Go to X-Y view
       '2'                         : Go to X-Z view
       '3'                         : Go to Y-Z view
       'v'                         : On/Off Visible Axes
       'f'                         : On/Off Fixed Aspect Ratio
       'g'                         : On/Off Axes Grid
 

 Example:
   x = -pi:0.1:pi;
   y = sin(x);
   figure; plot(x, y);
   dragzoom

 Example:
   I = imread('cameraman.tif');
   figure; imshow(I, []);
   dragzoom

 Example:
   figure;
   x = -pi*2:0.1:pi*2;
   y1 = sin(x);
   y2 = cos(x);
   subplot(2,1,1); plot(x,y1, '.-r')
   title('Income')
   subplot(2,1,2); plot(x, y2, 'o-b')
   title('Outgo')
   dragzoom;

 Example:
   figure;
   x = -pi*2:0.1:pi*2;
   y1 = sin(x);
   y2 = cos(x);
   hax1 = subplot(2,1,1); plot(hax1, x, y1, '.-r')
   hax2 = subplot(2,1,2); plot(hax2, x, y2, 'o-b')
   dragzoom(hax1); % manage only axes 1

 Example:
   figure;
   x = -pi*2:0.1:pi*2;
   y1 = sin(x);
   y2 = cos(x);
   hax1 = subplot(2,1,1); plot(hax1, x, y1, '.-r')
   hax2 = subplot(2,1,2); plot(hax2, x, y2, 'o-b')
   dragzoom([hax1, hax2]); % manage axes 1 and axes 2

 Example:
   figure;
   k = 5;
   n = 2^k-1;
   [x,y,z] = sphere(n);
   surf(x,y,z);
   dragzoom;

 Example:
   x = 0:100;
   y = log10(x);
   figure;
   semilogx(x, y, '*-b')
   dragzoom;


 See Also PAN, ZOOM, PANZOOM, ROTATE3D

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function vb_dragzoom(varargin)
0002 %DRAGZOOM Drag and zoom tool
0003 %
0004 % Description:
0005 %   DRAGZOOM allows you to interactively manage the axes in figure.
0006 %   This simple function for usable draging and zooming of axes, using the
0007 %   mouse and the keyboard shortcuts.
0008 %
0009 %   - Supported 2D-Plots, 3D-plots, semilogx-plots, semilogy-plots, loglog-plots and Images;
0010 %   - Supported subplots (mixed axes).
0011 %
0012 %
0013 % Using:
0014 %   vb_dragzoom()
0015 %   vb_dragzoom(hFig)
0016 %   vb_dragzoom(hAx)
0017 %   vb_dragzoom(hAxes)
0018 %   vb_dragzoom(hFig, status)
0019 %   vb_dragzoom(status)
0020 %
0021 %
0022 % Input:
0023 %   hObj -- Figure or axes handle or array of axes handles
0024 %   status -- 'on' or 'off'
0025 %             = '3d' or '2d' : 'on' and 3D/2D mode.
0026 %
0027 %
0028 % Control Enable Status of DRAGZOOM:
0029 %   vb_dragzoom(hFig, 'on')     : Enable DRAGZOOM for figure "hFig"
0030 %   vb_dragzoom(hFig, 'off')     : Disable DRAGZOOM for figure "hFig"
0031 %   vb_dragzoom(hFig, '3d')     : set DRAGZOOM to "3D" mode.
0032 %   vb_dragzoom(hFig, '2d')     : set DRAGZOOM to "2d" mode.
0033 %
0034 %
0035 % Interactive mode:
0036 %   Available the following actions:
0037 %
0038 %   Mouse actions in 2D mode:
0039 %   Normal mode:
0040 %       single-click and holding LB : Activation Drag mode
0041 %       single-click and holding RB : Activation Rubber Band for region zooming
0042 %       single-click MB             : Activation 'Extend' Zoom mode
0043 %       scroll wheel MB             : Activation Zoom mode
0044 %       double-click LB, RB, MB     : Reset to Original View
0045 %
0046 %   Magnifier mode:
0047 %       single-click LB             : Not Used
0048 %       single-click RB             : Not Used
0049 %       single-click MB             : Reset Magnifier to Original View
0050 %       scroll MB                   : Change Magnifier Zoom
0051 %       double-click LB             : Increase Magnifier Size
0052 %       double-click RB             : Decrease Magnifier Size
0053 %
0054 %   Hotkeys in 2D mode:
0055 %       'uparrow'                   : Up or down (inrerse) drag
0056 %       'downarrow'                 : Down or up (inverse) drag
0057 %       'leftarrow'                 : Left or right (inverse) drag
0058 %       'rightarrow'                : Right or left (inverse) drag
0059 %       'c'                         : On/Off Pointer Symbol 'fullcrosshair'
0060 %       'g'                         : On/Off Axes Grid
0061 %       'x'                         : If pressed and holding, zoom and drag works only for X axis
0062 %       'y'                         : If pressed and holding, zoom and drag works only for Y axis
0063 %       'm'                         : If pressed and holding, Magnifier mode on
0064 %       'l'                         : On/Off Synchronize XY manage of 2-D axes
0065 %       'control+l'                 : On Synchronize X manage of 2-D axes
0066 %       'alt+l'                     : On Synchronize Y manage of 2-D axes
0067 %       's'                         : On/Off Smooth Plot (Experimental)
0068 %
0069 %   Mouse actions in 3D mode:
0070 %       single-click and holding LB : Activation Rotate mode
0071 %       single-click and holding MB : Activation 'Extend' Zoom mode
0072 %       single-click and holding RB : Activation Drag mode
0073 %       scroll wheel MB             : Activation Zoom mode
0074 %       double-click LB, RB, MB     : Reset to Original View
0075 %
0076 %   Hotkeys in 3D mode:
0077 %       '+'                         : Zoom plus
0078 %       '-'                         : Zoom minus
0079 %       '0'                         : Set default axes (reset to original view)
0080 %       'uparrow'                   : Rotate up-down
0081 %       'downarrow'                 : Rotate down-up
0082 %       'leftarrow'                 : Rotate left-right
0083 %       'rightarrow'                : Rotate right-left
0084 %       'ctrl'+'uparrow'            : Up or down (inrerse) drag
0085 %       'ctrl'+'downarrow'          : Down or up (inverse) drag
0086 %       'ctrl'+'leftarrow'          : Left or right (inverse) drag
0087 %       'ctrl'+'rightarrow'         : Right or left (inverse) drag
0088 %       '1'                         : Go to X-Y view
0089 %       '2'                         : Go to X-Z view
0090 %       '3'                         : Go to Y-Z view
0091 %       'v'                         : On/Off Visible Axes
0092 %       'f'                         : On/Off Fixed Aspect Ratio
0093 %       'g'                         : On/Off Axes Grid
0094 %
0095 %
0096 % Example:
0097 %   x = -pi:0.1:pi;
0098 %   y = sin(x);
0099 %   figure; plot(x, y);
0100 %   dragzoom
0101 %
0102 % Example:
0103 %   I = imread('cameraman.tif');
0104 %   figure; imshow(I, []);
0105 %   dragzoom
0106 %
0107 % Example:
0108 %   figure;
0109 %   x = -pi*2:0.1:pi*2;
0110 %   y1 = sin(x);
0111 %   y2 = cos(x);
0112 %   subplot(2,1,1); plot(x,y1, '.-r')
0113 %   title('Income')
0114 %   subplot(2,1,2); plot(x, y2, 'o-b')
0115 %   title('Outgo')
0116 %   dragzoom;
0117 %
0118 % Example:
0119 %   figure;
0120 %   x = -pi*2:0.1:pi*2;
0121 %   y1 = sin(x);
0122 %   y2 = cos(x);
0123 %   hax1 = subplot(2,1,1); plot(hax1, x, y1, '.-r')
0124 %   hax2 = subplot(2,1,2); plot(hax2, x, y2, 'o-b')
0125 %   dragzoom(hax1); % manage only axes 1
0126 %
0127 % Example:
0128 %   figure;
0129 %   x = -pi*2:0.1:pi*2;
0130 %   y1 = sin(x);
0131 %   y2 = cos(x);
0132 %   hax1 = subplot(2,1,1); plot(hax1, x, y1, '.-r')
0133 %   hax2 = subplot(2,1,2); plot(hax2, x, y2, 'o-b')
0134 %   dragzoom([hax1, hax2]); % manage axes 1 and axes 2
0135 %
0136 % Example:
0137 %   figure;
0138 %   k = 5;
0139 %   n = 2^k-1;
0140 %   [x,y,z] = sphere(n);
0141 %   surf(x,y,z);
0142 %   dragzoom;
0143 %
0144 % Example:
0145 %   x = 0:100;
0146 %   y = log10(x);
0147 %   figure;
0148 %   semilogx(x, y, '*-b')
0149 %   dragzoom;
0150 %
0151 %
0152 % See Also PAN, ZOOM, PANZOOM, ROTATE3D
0153 %
0154 
0155 % -------------------------------------------------------------------------
0156 %   Version   : 0.9.7
0157 %   Author    : Evgeny Pr aka iroln <esp.home@gmail.com>
0158 %   Created   : 10.07.10
0159 %   Updated   : 05.06.11
0160 %
0161 %   Copyright : Evgeny Pr (c) 2010-2011
0162 % -------------------------------------------------------------------------
0163 
0164 %TODO: Show Pixel Info (Pixel Value(s)) for Images
0165 %TODO: "Sticking to Data" PointerCross
0166 
0167 narginchk(0,3);
0168 
0169 
0170 % handles
0171 hFig = [];
0172 hAx = [];
0173 hAxes = [];
0174 
0175 % variables
0176 mOrigFigName = [];
0177 mOrigCallbacks = [];
0178 mAxesInfo = [];
0179 mDragStartX = [];
0180 mDragStartY = [];
0181 mDragKeysX = [];
0182 mDragKeysY = [];
0183 mDragShiftStep = [];
0184 mDragSaveShiftStep = [];
0185 mDragShiftStepInc = [];
0186 mDragSave3DShiftStep = [];
0187 mDrag3DShiftStep = [];
0188 mZoomScroll = [];
0189 mZoomMinPow = [];
0190 mZoomMaxPow = [];
0191 mZoomNum = [];
0192 mZoomExtendNum = [];
0193 mZoomKeysNum = [];
0194 mZoom3DExtendNum = [];
0195 mZoom3DKeysNum = [];
0196 mZoom3DIndex = [];
0197 mDefaultZoomGrid = [];
0198 mDefaultZoomSteps = [];
0199 mZoomGrid = [];
0200 mZoomSteps = [];
0201 mZoomIndexX = [];
0202 mZoomIndexY = [];
0203 mZoom3DStartX = [];
0204 mZoom3DStartY = [];
0205 mZoom3DBindX = [];
0206 mZoom3DBindY = [];
0207 mDefaultXLim = [];
0208 mDefaultYLim = [];
0209 mDefaultAxPos = [];
0210 mRotStartAZ = [];
0211 mRotStartEL = [];
0212 mRotStartX = [];
0213 mRotStartY = [];
0214 mRot3DKeysInc = [];
0215 mPointerCross = [];
0216 mRubberBand = [];
0217 mRbEdgeColor = [];
0218 mRbFaceColor = [];
0219 mRbFaceAlpha = [];
0220 mMagnifier = [];
0221 mMgSize = [];
0222 mMgMinSize = [];
0223 mMgMaxSize = [];
0224 mMgZoom = [];
0225 mMgMinZoom = [];
0226 mMgMaxZoom = [];
0227 mMgLinesWidth = [];
0228 mMgShadow = [];
0229 mMgSizeStep = [];
0230 mMgZoomStep = [];
0231 mMgDirection = [];
0232 mLinkOpt = 'xy';
0233 
0234 % flags
0235 fIsEnabled = false;
0236 fIsSelectedCurrentAxes = true;
0237 fIsDragAllowed = false;
0238 fIsZoomExtendAllowed = false;
0239 fIsZoomExtend3DAllowed = false;
0240 fIsRotate3DAllowed = false;
0241 fIsRubberBandOn = false;
0242 fIsPointerCross = false;
0243 fIsAxesGrid = false;
0244 fIsSmoothing = false;
0245 fIsEnableDragX = true;
0246 fIsEnableDragY = true;
0247 fIsEnableZoomX = true;
0248 fIsEnableZoomY = true;
0249 fIsAxes2D = false;
0250 fIsImage = false;
0251 fIsMagnifierOn = false;
0252 fIsLinkAxesOn = false;
0253 fIsEnableControl = false;
0254 fIsMouseOnLegend = false;
0255 fMode = '';
0256 
0257 
0258 % Initialize and Setup
0259 Initialize(varargin{:})
0260 %--------------------------------------------------------------------------
0261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0262 
0263 
0264 %==========================================================================
0265     function Setup()
0266         %Setup setup options
0267         
0268         % Drag Options
0269         mDragKeysX = 'normal';      % 'normal', 'reverse'
0270         mDragKeysY = 'normal';      % 'normal', 'reverse'
0271         mDragShiftStep = 3;         % step dragging on keys
0272         mDragShiftStepInc = 1;      % increase speed dragging on keys
0273         mDrag3DShiftStep = 10;      % step dragging 3D on keys
0274         
0275         % Zoom Options
0276         mZoomScroll = 'normal';     % 'normal', 'reverse'
0277         mZoomMinPow = 0;            % min zoom percent 10 ^ mZoomMinPow
0278         mZoomMaxPow = 5;            % max zoom perzent 10 ^ mZoomMaxPow
0279         mZoomNum = 51;              % count steps of log zoom grid
0280         mZoomExtendNum = 301;       % count steps of log grid zoom extend for 2D
0281         mZoomKeysNum = 181;         % count steps of log grid zoom for keys for 2D
0282         mZoom3DExtendNum = 201;     % count steps of log grid zoom extend for 3D
0283         mZoom3DKeysNum = 181;       % count steps of log grid zoom for keys for 3D
0284         
0285         % Rubber Band Options
0286         mRbEdgeColor = 'k';         % rubber band edge color
0287         mRbFaceColor = 'none';      % rubber band face color
0288         mRbFaceAlpha = 1;           % rubber band face alpha (transparency)
0289         
0290         % Magnifier Options
0291         mMgSize = 100;              % default size of magnifier (pixels)
0292         mMgMinSize = 50;            % min size of magnifier
0293         mMgMaxSize = 200;           % max size of magnifier
0294         mMgZoom = 2;                % default zoom on magnifier
0295         mMgMinZoom = 1;             % min zoom on magnifier
0296         mMgMaxZoom = 100;           % max zoom on magnifier
0297         mMgLinesWidth = 1;          % lines width on magnifier
0298         mMgShadow = 0.95;           % shadow area without magnifier
0299         mMgSizeStep = 15;           % step change in the magnifier size
0300         mMgZoomStep = 1.2;          % step change in the magnifier zoom
0301         
0302         % Rotate Options
0303         mRot3DKeysInc = 3;          % rotate increase for keys
0304 
0305     end
0306 %--------------------------------------------------------------------------
0307 
0308 %==========================================================================
0309     function Initialize(varargin)
0310         %Initialize initialize tool
0311         
0312         % Parse Input Arguments
0313         isWithStatus = ParseInputs(varargin{:});
0314         
0315         if isempty(hAxes), return; end
0316         
0317         hAx = hAxes(1);
0318         set(hFig, 'CurrentAxes', hAx);
0319         
0320         % setup tool
0321         Setup();
0322         
0323         % initialize tool
0324         UserData = get(hFig, 'UserData');
0325         if isempty(UserData), UserData = struct; end
0326         
0327         if (isfield(UserData, 'axesinfo') && isWithStatus)
0328             mAxesInfo = UserData.axesinfo;
0329             mOrigCallbacks = UserData.origcallbacks;
0330             mOrigFigName = UserData.origfigname;
0331         else
0332             % first call dragzoom or call without enable status
0333             if ~isfield(UserData, 'origfigname')
0334                 mOrigFigName = get(hFig, 'Name');
0335             end
0336             
0337             if isfield(UserData, 'origcallbacks')
0338                 mOrigCallbacks = UserData.origcallbacks;
0339                 SetOriginalCallbacks();
0340             end
0341             
0342             % save original callbacks
0343             SaveOriginalCallbacks();
0344             
0345             % get info about all axes and create axes info struct
0346             mAxesInfo = GetAxesInfo();
0347             
0348             % save initialize view for all axes
0349             for i = 1:numel(mAxesInfo)
0350                 resetplotview(mAxesInfo(i).handle, 'InitializeCurrentView');
0351             end
0352             
0353             UserData.axesinfo = mAxesInfo;
0354             UserData.origcallbacks = mOrigCallbacks;
0355             UserData.origfigname = mOrigFigName;
0356             
0357             if ~isfield(UserData, 'tools')
0358                 UserData.tools.pointercross = mPointerCross;
0359                 UserData.tools.islinkaxeson = fIsLinkAxesOn;
0360             end
0361             
0362             set(hFig, 'UserData', UserData);    
0363         end
0364         
0365         DeleteOldTools();
0366         
0367         axi = GetCurrentAxesIndex();
0368         SetCurrentAxes(axi);
0369         SetDefaultZoomGrid();
0370         SetFigureName();
0371         
0372         mDragSaveShiftStep = mDragShiftStep;
0373         mDragSave3DShiftStep = mDrag3DShiftStep;
0374         
0375         % In case the figure will be saved
0376         set(hFig, 'CreateFcn', {@CreateFigureCallback});
0377         
0378         if fIsEnabled
0379             SetCallbacks();
0380         else
0381             SetOriginalCallbacks();
0382         end
0383     end
0384 %--------------------------------------------------------------------------
0385 
0386 %==========================================================================
0387     function SaveOriginalCallbacks()
0388         %SaveOriginalCallbacks
0389         
0390         mOrigCallbacks.window_button_down_fcn   = get(hFig, 'WindowButtonDownFcn');
0391         mOrigCallbacks.window_button_up_fcn     = get(hFig, 'WindowButtonUpFcn');
0392         mOrigCallbacks.window_button_motion_fcn = get(hFig, 'WindowButtonMotionFcn');
0393         mOrigCallbacks.create_fcn               = get(hFig, 'CreateFcn');
0394 
0395         try
0396         mOrigCallbacks.window_scroll_whell_fcn  = get(hFig, 'WindowScrollWheelFcn');
0397         mOrigCallbacks.window_key_press_fcn     = get(hFig, 'WindowKeyPressFcn');
0398         mOrigCallbacks.window_key_release_fcn   = get(hFig, 'WindowKeyReleaseFcn');
0399         catch
0400         end
0401     end
0402 %--------------------------------------------------------------------------
0403 
0404 %==========================================================================
0405     function SetOriginalCallbacks()
0406         %SetOriginalCallbacks
0407         
0408         set(hFig, ...
0409               'WindowButtonDownFcn',      mOrigCallbacks.window_button_down_fcn, ...
0410               'WindowButtonUpFcn',        mOrigCallbacks.window_button_up_fcn, ...
0411               'WindowButtonMotionFcn',    mOrigCallbacks.window_button_motion_fcn, ...
0412               'CreateFcn',                mOrigCallbacks.create_fcn);
0413         
0414         try
0415         set(hFig, ...
0416              'WindowScrollWheelFcn',     mOrigCallbacks.window_scroll_whell_fcn, ...
0417              'WindowKeyPressFcn',        mOrigCallbacks.window_key_press_fcn, ...
0418              'WindowKeyReleaseFcn',      mOrigCallbacks.window_key_release_fcn);
0419         catch
0420         end
0421         
0422     end
0423 %--------------------------------------------------------------------------
0424 
0425 %==========================================================================
0426     function SetCallbacks()
0427         %SetCallbacks
0428         
0429         if fIsAxes2D
0430             % 2D mode
0431             SetFigureCallbacks2D();
0432         else
0433             % 3D mode
0434             SetFigureCallbacks3D();
0435         end
0436     end
0437 %--------------------------------------------------------------------------
0438 
0439 %==========================================================================
0440     function SetFigureCallbacks2D()
0441         %SetFigureCallbacks2D set callback-functions for processing figure events in mode 2D
0442         
0443         set(hFig, ...
0444             'WindowButtonDownFcn',      {@WindowButtonDownCallback2D}, ...
0445             'WindowButtonUpFcn',        {@WindowButtonUpCallback2D}, ...
0446             'WindowButtonMotionFcn',    {@WindowButtonMotionCallback2D});
0447         try
0448         set(hFig, ...
0449             'WindowScrollWheelFcn',     {@WindowScrollWheelFcn2D}, ...
0450             'WindowKeyPressFcn',        {@WindowKeyPressCallback2D}, ...
0451             'WindowKeyReleaseFcn',      {@WindowKeyReleaseCallback2D});
0452         catch
0453         end
0454     end
0455 %--------------------------------------------------------------------------
0456 
0457 %==========================================================================
0458     function SetFigureCallbacks3D()
0459         %SetFigureCallbacks3D set callback-functions for processing figure events in mode 3D
0460         
0461         set(hFig, ...
0462             'WindowButtonDownFcn',      {@WindowButtonDownCallback3D}, ...
0463             'WindowButtonUpFcn',        {@WindowButtonUpCallback3D}, ...
0464             'WindowButtonMotionFcn',    {@WindowButtonMotionCallback3D});
0465         try
0466         set(hFig, ...
0467             'WindowScrollWheelFcn',     {@WindowScrollWheelFcn3D}, ...
0468             'WindowKeyPressFcn',        {@WindowKeyPressCallback3D}, ...
0469             'WindowKeyReleaseFcn',      {@WindowKeyReleaseCallback3D});
0470         catch
0471         end
0472     end
0473 %--------------------------------------------------------------------------
0474 
0475 %==========================================================================
0476     function WindowButtonDownCallback2D(src, evnt)    %#ok
0477         %WindowButtonDownCallback2D
0478         
0479         if fIsMouseOnLegend, return; end
0480         
0481         clickType = get(src, 'SelectionType');
0482         
0483         switch clickType
0484             case 'normal'
0485                 DragMouseBegin();
0486                 mMgDirection = 'plus';
0487             case 'open'
0488                 if fIsMagnifierOn
0489                     MagnifierSizeChange(mMgDirection);
0490                 else
0491                     ResetAxesToOrigView();
0492                 end
0493             case 'alt'
0494                 RubberBandBegin();
0495                 mMgDirection = 'minus';
0496             case 'extend'
0497                 if fIsMagnifierOn
0498                     MagnifierReset();
0499                 else
0500                     ZoomMouseExtendBegin();
0501                 end
0502         end
0503         eval(mOrigCallbacks.window_button_down_fcn);
0504     end
0505 %--------------------------------------------------------------------------
0506 
0507 %==========================================================================
0508     function WindowButtonUpCallback2D(src, evnt)      %#ok
0509         %WindowButtonUpCallback2D
0510         
0511         DragMouseEnd();
0512         ZoomMouseExtendEnd();
0513         RubberBandEnd();
0514         eval(mOrigCallbacks.window_button_up_fcn);
0515     end
0516 %--------------------------------------------------------------------------
0517 
0518 %==========================================================================
0519     function WindowButtonMotionCallback2D(src, evnt)  %#ok
0520         %WindowButtonMotionCallback2D
0521                 
0522         if ~(fIsMagnifierOn || fIsDragAllowed || fIsRubberBandOn)
0523             % set current axes under cursor
0524             SelectAxesUnderCursor();
0525         end
0526         
0527         if fIsEnableControl
0528             DragMouse();
0529             RubberBandUpdate();
0530             MagnifierUpdate();
0531         end
0532         
0533         ZoomMouseExtend();
0534         PointerCrossUpdate();
0535         eval(mOrigCallbacks.window_button_motion_fcn);
0536     end
0537 %--------------------------------------------------------------------------
0538 
0539 %==========================================================================
0540     function WindowScrollWheelFcn2D(src, evnt)        %#ok
0541         %WindowScrollWheelFcn2D
0542         
0543         if fIsMouseOnLegend, return; end
0544         
0545         % Update Zoom Info
0546         % because it can be changed function 'zoom'
0547         UpdateCurrentZoomAxes();
0548         
0549         switch mZoomScroll
0550             case 'normal'
0551                 directions = {'minus', 'plus'};
0552             case 'reverse'
0553                 directions = {'plus', 'minus'};
0554         end
0555         
0556         verScrollCount = evnt.VerticalScrollCount;
0557         
0558         if (verScrollCount > 0)
0559             direction = directions{1};
0560         elseif (verScrollCount < 0)
0561             direction = directions{2};
0562         else
0563             return;
0564         end
0565         ZoomKeys(direction);
0566 
0567         % if fIsEnableControl
0568         ZoomMouse(direction);
0569         PointerCrossUpdate();
0570         % end
0571         MagnifierZoomChange(direction);
0572     end
0573 %--------------------------------------------------------------------------
0574 
0575 %==========================================================================
0576     function WindowKeyPressCallback2D(src, evnt)      %#ok
0577         %WindowKeyPressCallback2D
0578         
0579         modifier = evnt.Modifier;
0580         
0581         switch evnt.Key
0582 % rhayashi 2014/3/7 commented out
0583 %            case '0'
0584 %                ResetAxesToOrigView();
0585              case {'equal', 'add'}
0586                  ZoomKeys('plus');
0587              case {'hyphen', 'subtract'}
0588                  ZoomKeys('minus');
0589             case 'leftarrow'
0590                 DragKeys('left');
0591             case 'rightarrow'
0592                 DragKeys('right');
0593             case 'uparrow'
0594                 DragKeys('up');
0595             case 'downarrow'
0596                 DragKeys('down');
0597             case 'c'
0598                 %SetPointerCrossKeys();
0599             case 'g'
0600                 SetAxesGridKeys();
0601              case 'x'
0602                 DragEnable('y', 'off');
0603                 ZoomEnable('y', 'off');
0604             case 'y'
0605                 DragEnable('x', 'off');
0606                 ZoomEnable('x', 'off');
0607             case 'm'
0608                 if fIsEnableControl
0609                     MagnifierOn();
0610                 end
0611             case 'l'
0612                 SetLinkAxesKeys(modifier);
0613             case 's'
0614                 % smooth plot
0615                 SetSmoothKeys();
0616         end
0617     end
0618 %--------------------------------------------------------------------------
0619 
0620 %==========================================================================
0621     function WindowKeyReleaseCallback2D(src, evnt)    %#ok
0622         %WindowKeyReleaseCallback2D
0623         
0624         switch evnt.Key
0625             case {'leftarrow', 'rightarrow', 'uparrow', 'downarrow'}
0626                 mDragShiftStep = mDragSaveShiftStep;
0627             case 'x'
0628                 DragEnable('y', 'on');
0629                 ZoomEnable('y', 'on');
0630             case 'y'
0631                 DragEnable('x', 'on');
0632                 ZoomEnable('x', 'on');
0633             case 'm'
0634                 MagnifierOff();
0635         end
0636     end
0637 %--------------------------------------------------------------------------
0638 
0639 %==========================================================================
0640     function WindowButtonDownCallback3D(src, evnt)    %#ok
0641         %WindowButtonDownCallback3D
0642         
0643         if fIsMouseOnLegend, return; end
0644         
0645         clickType = get(src, 'SelectionType');
0646         
0647         switch clickType
0648             case 'normal'
0649 % rhayashi 2017/8/22 reversed normal and alt operation.
0650                 RotateMouseBegin3D();
0651 % rhayashi 2014/2/26 commented out
0652 %            case 'open'
0653 %                ResetAxesToOrigView3D();
0654             case 'alt'
0655                 DragMouseBegin3D();
0656             case 'extend'
0657                 ZoomMouseExtendBegin3D();
0658         end
0659         eval(mOrigCallbacks.window_button_down_fcn);
0660     end
0661 %--------------------------------------------------------------------------
0662 
0663 %==========================================================================
0664     function WindowButtonUpCallback3D(src, evnt)    %#ok
0665         %WindowButtonUpCallback3D
0666                 
0667         DragMouseEnd3D();
0668         ZoomMouseExtendEnd3D();
0669         RotateMouseEnd3D();
0670         eval(mOrigCallbacks.window_button_up_fcn);
0671     end
0672 %--------------------------------------------------------------------------
0673 
0674 %==========================================================================
0675     function WindowButtonMotionCallback3D(src, evnt)    %#ok
0676         %WindowButtonMotionCallback3D
0677                 
0678         if ~(fIsDragAllowed || fIsZoomExtend3DAllowed || fIsRotate3DAllowed)
0679             SelectAxesUnderCursor();
0680         end
0681         
0682         if fIsEnableControl
0683             DragMouse3D();
0684             RotateMouse3D();
0685         end
0686         ZoomMouseExtend3D();
0687         eval(mOrigCallbacks.window_button_motion_fcn);
0688     end
0689 %--------------------------------------------------------------------------
0690 
0691 %==========================================================================
0692     function WindowScrollWheelFcn3D(src, evnt)    %#ok
0693         %WindowScrollWheelFcn3D
0694         
0695         if fIsMouseOnLegend, return; end
0696         
0697         UpdateCurrentZoomAxes3D();
0698         
0699         switch mZoomScroll
0700             case 'normal'
0701                 directions = {'minus', 'plus'};
0702             case 'reverse'
0703                 directions = {'plus', 'minus'};
0704         end
0705         
0706         verScrollCount = evnt.VerticalScrollCount;
0707         
0708         if (verScrollCount > 0)
0709             direction = directions{1};
0710         elseif (verScrollCount < 0)
0711             direction = directions{2};
0712         else
0713             return;
0714         end
0715         
0716         % if fIsEnableControl
0717         ZoomMouse3D(direction);
0718         % end
0719     end
0720 %--------------------------------------------------------------------------
0721 
0722 %==========================================================================
0723     function WindowKeyPressCallback3D(src, evnt)    %#ok
0724         %WindowKeyPressCallback3D
0725         
0726         isModifier = ~isempty(intersect(evnt.Modifier, {'control', 'command'}));
0727         
0728         switch evnt.Key
0729             case {'equal', 'add'}
0730                 ZoomKeys3D('plus');
0731             case {'hyphen', 'subtract'}
0732                 ZoomKeys3D('minus');
0733 % rhayashi 2014/3/7 commented out
0734 %             case 'leftarrow'
0735 %                 if isModifier
0736 %                     DragKeys3D('left');
0737 %                 else
0738 %                     RotateKeys3D('az-');
0739 %                 end
0740 %             case 'rightarrow'
0741 %                 if isModifier
0742 %                     DragKeys3D('right');
0743 %                 else
0744 %                     RotateKeys3D('az+');
0745 %                 end
0746 %             case 'uparrow'
0747 %                 if isModifier
0748 %                     DragKeys3D('up');
0749 %                 else
0750 %                     RotateKeys3D('el-');
0751 %                 end
0752 %             case 'downarrow'
0753 %                 if isModifier
0754 %                     DragKeys3D('down');
0755 %                 else
0756 %                     RotateKeys3D('el+');
0757 %                 end
0758 %            case '0'
0759 %                ResetAxesToOrigView3D();
0760 %             case '1'
0761 %                 RotateKeys3D('xy');
0762 %             case '2'
0763 %                 RotateKeys3D('xz');
0764 %             case '3'
0765 %                 RotateKeys3D('yz');
0766 %             case 'v'
0767 %                 VisibleAxesKeys3D();
0768 %             case 'f'
0769 %                 SwitchAspectRatioKeys3D()
0770 %             case 'g'
0771 %                 SetAxesGridKeys();
0772         end
0773     end
0774 %--------------------------------------------------------------------------
0775 
0776 %==========================================================================
0777     function WindowKeyReleaseCallback3D(src, evnt)    %#ok
0778         %WindowKeyReleaseCallback3D
0779         
0780         switch evnt.Key
0781             case {'equal', 'add', 'hyphen', 'subtract'}
0782                 SetDefaultZoomGrid3D();
0783             case {'leftarrow', 'rightarrow', 'uparrow', 'downarrow'}
0784                 mDrag3DShiftStep = mDragSave3DShiftStep;
0785         end
0786     end
0787 %--------------------------------------------------------------------------
0788 
0789 %==========================================================================
0790     function CreateFigureCallback(src, evnt)    %#ok
0791         %CreateFigureCallback
0792         
0793         hFig = src;
0794         
0795         UserData = get(hFig, 'UserData');
0796         mAxesInfo = UserData.axesinfo;
0797         mOrigCallbacks = UserData.origcallbacks;
0798         mOrigFigName = UserData.origfigname;
0799         hAxes = arrayfun(@(x) x.handle, mAxesInfo);
0800         
0801         axi = GetCurrentAxesIndex();
0802         SetCurrentAxes(axi)
0803         DeleteOldTools();
0804     end
0805 %--------------------------------------------------------------------------
0806 
0807 %==========================================================================
0808     function SetFigureName()
0809         %SetFigureName Set Name of Figure
0810         
0811         enableStatus = 'off';
0812         if fIsEnabled
0813             enableStatus = 'on';
0814         end
0815         
0816         syncMode = 'Normal';
0817         if fIsLinkAxesOn
0818             syncMode = sprintf('Synchronized %s', upper(mLinkOpt));
0819         end
0820         
0821         sep = '';
0822         if ~isempty(mOrigFigName)
0823             sep = ':';
0824         end
0825 % 2014/2/26 rhayashi commented out
0826 %         newName = sprintf('[DRAGZOOM : "%s" (%s)]%s %s', ...
0827 %             enableStatus, syncMode, sep, mOrigFigName);
0828 %         set(hFig, 'Name', newName)
0829     end
0830 %--------------------------------------------------------------------------
0831 
0832 %==========================================================================
0833     function DragMouseBegin()
0834         %DragMouseBegin begin draging
0835         
0836         if (~fIsDragAllowed && ~fIsMagnifierOn)
0837             [cx, cy] = GetCursorCoordOnWindow();
0838             
0839             mDragStartX = cx;
0840             mDragStartY = cy;
0841             
0842             fIsDragAllowed = true;
0843         end
0844     end
0845 %--------------------------------------------------------------------------
0846 
0847 %==========================================================================
0848     function DragMouseEnd()
0849         %DragMouseEnd end draging
0850 
0851         if fIsDragAllowed
0852             fIsDragAllowed = false;
0853         end
0854     end
0855 %--------------------------------------------------------------------------
0856 
0857 %==========================================================================
0858     function DragMouse()
0859         %DragMouse
0860 
0861         if fIsDragAllowed
0862             [cx, cy] = GetCursorCoordOnWindow();
0863             
0864             pdx = mDragStartX - cx;
0865             pdy = mDragStartY - cy;
0866             
0867             mDragStartX = cx;
0868             mDragStartY = cy;
0869             
0870             DragAxes(pdx, pdy);
0871         end
0872     end
0873 %--------------------------------------------------------------------------
0874 
0875 %==========================================================================
0876     function DragKeys(direction)
0877         %DragKeys
0878         
0879         dx = mDragShiftStep;
0880         dy = mDragShiftStep;
0881         
0882         % Increment of speed when you hold the button
0883         mDragShiftStep = mDragShiftStep + mDragShiftStepInc;
0884         
0885         directionsX = {'right', 'left'};
0886         directionsY = {'down', 'up'};
0887         
0888         switch mDragKeysX
0889             case 'normal'
0890             case 'reverse'
0891                 directionsX = fliplr(directionsX);
0892         end
0893         switch mDragKeysY
0894             case 'normal'
0895             case 'reverse'
0896                 directionsY = fliplr(directionsY);
0897         end
0898         
0899         switch direction
0900             case directionsX{1}
0901                 DragAxes(-dx, 0);
0902             case directionsX{2}
0903                 DragAxes(dx, 0);
0904             case directionsY{1}
0905                 DragAxes(0, dy);
0906             case directionsY{2}
0907                 DragAxes(0, -dy);
0908         end
0909         
0910         PointerCrossUpdate();
0911     end
0912 %--------------------------------------------------------------------------
0913 
0914 %==========================================================================
0915     function DragAxes(pdx, pdy)
0916         %DragAxes
0917         
0918         [xLim, yLim] = GetAxesLimits();
0919         
0920         pos = GetObjPos(hAx, 'Pixels');
0921         pbar = get(hAx, 'PlotBoxAspectRatio');
0922         
0923         %NOTE: MATLAB Bug?
0924         % Fixed problem with AspectRatio and Position of Axes
0925         % MATLAB Function PAN is not correct works with rectangular images!
0926         % Here it is correctly.
0927         
0928         imAspectRatioX = pbar(2) / pbar(1);
0929         if (imAspectRatioX ~= 1)
0930             posAspectRatioX = pos(3) / pos(4);
0931             arFactorX = imAspectRatioX * posAspectRatioX;
0932             if (arFactorX < 1)
0933                 arFactorX = 1;
0934             end
0935         else
0936             arFactorX = 1;
0937         end
0938         
0939         imAspectRatioY = pbar(1) / pbar(2);
0940         if (imAspectRatioY ~= 1)
0941             posAspectRatioY = pos(4) / pos(3);
0942             arFactorY = imAspectRatioY * posAspectRatioY;
0943             if (arFactorY < 1)
0944                 arFactorY = 1;
0945             end
0946         else
0947             arFactorY = 1;
0948         end
0949         
0950         if fIsEnableDragX
0951             % For log plots, transform to linear scale
0952             if strcmp(get(hAx, 'xscale'), 'log')
0953                 xLim = log10(xLim);
0954                 xLim = FixInfLogLimits('x', xLim);
0955                 isXLog = true;
0956             else
0957                 isXLog = false;
0958             end
0959             
0960             dx = pdx * range(xLim) / (pos(3) / arFactorX);
0961             xLim = xLim + dx;
0962             
0963             % For log plots, untransform limits
0964             if isXLog
0965                 xLim = 10.^(xLim);
0966             end
0967         end
0968         if fIsEnableDragY
0969             if strcmp(get(hAx, 'yscale'), 'log')
0970                 yLim = log10(yLim);
0971                 yLim = FixInfLogLimits('y', yLim);
0972                 isYLog = true;
0973             else
0974                 isYLog = false;
0975             end
0976             
0977             dy = pdy * range(yLim) / (pos(4) / arFactorY);
0978             
0979             if fIsImage
0980                 yLim = yLim - dy; 
0981             else
0982                 yLim = yLim + dy; 
0983             end
0984             
0985             if isYLog
0986                 yLim = 10.^(yLim);
0987             end
0988         end
0989         
0990         SetAxesLimits(xLim, yLim);
0991     end
0992 %--------------------------------------------------------------------------
0993 
0994 %==========================================================================
0995     function DragMouseBegin3D()
0996         %DragMouseBegin3D
0997         
0998         if ~fIsDragAllowed
0999             [wcx, wcy] = GetCursorCoordOnWindow('pixels');
1000             
1001             mDragStartX = wcx;
1002             mDragStartY = wcy;
1003             
1004             fIsDragAllowed = true;
1005         end
1006     end
1007 %--------------------------------------------------------------------------
1008 
1009 %==========================================================================
1010     function DragMouseEnd3D()
1011         %DragMouseEnd3D
1012         
1013         if fIsDragAllowed
1014             fIsDragAllowed = false;
1015         end
1016     end
1017 %--------------------------------------------------------------------------
1018 
1019 %==========================================================================
1020     function DragMouse3D()
1021         %DragMouse3D
1022         
1023         if fIsDragAllowed
1024             [wcx, wcy] = GetCursorCoordOnWindow('pixels');
1025             
1026             dx = mDragStartX - wcx;
1027             dy = mDragStartY - wcy;
1028             
1029             DragAxes3D(dx, dy);
1030             
1031             mDragStartX = wcx;
1032             mDragStartY = wcy;
1033         end
1034     end
1035 %--------------------------------------------------------------------------
1036 
1037 %==========================================================================
1038     function DragKeys3D(direction)
1039         %DragKeys3D
1040         
1041         dx = mDrag3DShiftStep;
1042         dy = mDrag3DShiftStep;
1043         
1044         mDrag3DShiftStep = mDrag3DShiftStep + mDragShiftStepInc;
1045         
1046         directionsX = {'right', 'left'};
1047         directionsY = {'down', 'up'};
1048         
1049         switch mDragKeysX
1050             case 'normal'
1051             case 'reverse'
1052                 directionsX = fliplr(directionsX);
1053         end
1054         switch mDragKeysY
1055             case 'normal'
1056             case 'reverse'
1057                 directionsY = fliplr(directionsY);
1058         end
1059         
1060         switch direction
1061             case directionsX{1}
1062                 DragAxes3D(-dx, 0);
1063             case directionsX{2}
1064                 DragAxes3D(dx, 0);
1065             case directionsY{1}
1066                 DragAxes3D(0, dy);
1067             case directionsY{2}
1068                 DragAxes3D(0, -dy);
1069         end
1070     end
1071 %--------------------------------------------------------------------------
1072 
1073 %==========================================================================
1074     function DragAxes3D(dx, dy)
1075         %DragAxes3D
1076         
1077         axPos = GetObjPos(hAx, 'pixels');
1078         
1079         axPos(1) = axPos(1) - dx;
1080         axPos(2) = axPos(2) - dy;
1081         
1082         SetObjPos(hAx, axPos, 'pixels');
1083     end
1084 %--------------------------------------------------------------------------
1085 
1086 %==========================================================================
1087     function DragEnable(ax, action)
1088         %DragEnable
1089         
1090         switch lower(action)
1091             case 'on'
1092                 tf = true;
1093             case 'off'
1094                 tf = false;
1095         end
1096                 
1097         switch lower(ax)
1098             case 'x'
1099                 fIsEnableDragX = tf;
1100             case 'y'
1101                 fIsEnableDragY = tf;
1102         end
1103     end
1104 %--------------------------------------------------------------------------
1105 
1106 %==========================================================================
1107     function ZoomEnable(ax, action)
1108         %ZoomEnable
1109         
1110         switch lower(action)
1111             case 'on'
1112                 tf = true;
1113             case 'off'
1114                 tf = false;
1115         end
1116                 
1117         switch lower(ax)
1118             case 'x'
1119                 fIsEnableZoomX = tf;
1120             case 'y'
1121                 fIsEnableZoomY = tf;
1122         end
1123     end
1124 %--------------------------------------------------------------------------
1125 
1126 %==========================================================================
1127     function ZoomMouse(direction)
1128         %ZoomMouse zooming axes with mouse
1129         
1130         if (IsZoomMouseAllowed && ~fIsMagnifierOn)
1131             [acx, acy] = GetCursorCoordOnAxes();
1132             ZoomAxes(direction, acx, acy)
1133         end
1134     end
1135 %--------------------------------------------------------------------------
1136 
1137 %==========================================================================
1138     function ZoomMouseExtendBegin()
1139         %ZoomMouseExtendBegin
1140         
1141         if ~fIsZoomExtendAllowed
1142             UpdateCurrentZoomAxes();
1143             
1144             % set new zoom grid for extend zoom
1145             [mZoomGrid, mZoomSteps] = ZoomLogGrid(mZoomMinPow, mZoomMaxPow, mZoomExtendNum);
1146             UpdateCurrentZoomAxes();
1147             
1148             [wcx, wcy] = GetCursorCoordOnWindow('pixels');
1149             [acx, acy] = GetCursorCoordOnAxes();
1150             
1151             mZoom3DStartX = wcx;
1152             mZoom3DStartY = wcy;
1153             
1154             mZoom3DBindX = acx;
1155             mZoom3DBindY = acy;
1156             
1157             fIsZoomExtendAllowed = true;
1158         end
1159     end
1160 %--------------------------------------------------------------------------
1161 
1162 %==========================================================================
1163     function ZoomMouseExtendEnd()
1164         %ZoomMouseExtendEnd
1165         
1166         if fIsZoomExtendAllowed
1167             % set default zoom grid
1168             SetDefaultZoomGrid();
1169             fIsZoomExtendAllowed = false;
1170         end
1171     end
1172 %--------------------------------------------------------------------------
1173 
1174 %==========================================================================
1175     function ZoomMouseExtend()
1176         %ZoomMouseExtend
1177         
1178         if fIsZoomExtendAllowed
1179             directions = {'minus', 'plus'};
1180             
1181             switch mZoomScroll
1182                 case 'normal'
1183                 case 'reverse'
1184                     directions = fliplr(directions);
1185             end
1186         
1187             % Heuristic for pixel change to camera zoom factor
1188             % (taken from function ZOOM)
1189             [wcx, wcy] = GetCursorCoordOnWindow('pixels');
1190             
1191             xy(1) = wcx - mZoom3DStartX;
1192             xy(2) = wcy - mZoom3DStartY;
1193             q = max(-0.9, min(0.9, sum(xy)/70)) + 1;
1194    
1195             if (q < 1)
1196                 direction = directions{1};
1197             elseif (q > 1)
1198                 direction = directions{2};
1199             else
1200                 return;
1201             end
1202             
1203             ZoomAxes(direction, mZoom3DBindX, mZoom3DBindY)
1204             
1205             mZoom3DStartX = wcx;
1206             mZoom3DStartY = wcy;            
1207         end
1208     end
1209 %--------------------------------------------------------------------------
1210 
1211 %==========================================================================
1212     function ZoomKeys(direction)
1213         %ZoomKeys zooming axes with keyboard
1214         
1215         UpdateCurrentZoomAxes();
1216         
1217         [mZoomGrid, mZoomSteps] = ZoomLogGrid(mZoomMinPow, mZoomMaxPow, mZoomKeysNum);
1218         UpdateCurrentZoomAxes();
1219         
1220         [acx, acy] = GetCursorCoordOnAxes();
1221         
1222         ZoomAxes(direction, acx, acy)
1223         PointerCrossUpdate();
1224         SetDefaultZoomGrid();
1225     end
1226 %--------------------------------------------------------------------------
1227 
1228 %==========================================================================
1229     function ZoomAxes(direction, cx, cy)
1230         %ZoomAxes Zoom axes in 2D and image modes
1231         
1232         [xLim, yLim] = GetAxesLimits();
1233         
1234         if fIsImage
1235             mZoomIndexX = ChangeZoomIndex(direction, mZoomIndexX);
1236             mZoomIndexY = mZoomIndexX;
1237             zoomPct = GetZoomPercent(mZoomIndexX);
1238             
1239             xLim = RecalcZoomAxesLimits('x', xLim, mDefaultXLim, cx, zoomPct);
1240             yLim = RecalcZoomAxesLimits('y', yLim, mDefaultYLim, cy, zoomPct);            
1241         else
1242             if fIsEnableZoomX
1243                 mZoomIndexX = ChangeZoomIndex(direction, mZoomIndexX);
1244                 zoomPct = GetZoomPercent(mZoomIndexX);
1245                 
1246                 xLim = RecalcZoomAxesLimits('x', xLim, mDefaultXLim, cx, zoomPct);
1247             end
1248             if fIsEnableZoomY
1249                 mZoomIndexY = ChangeZoomIndex(direction, mZoomIndexY);
1250                 zoomPct = GetZoomPercent(mZoomIndexY);
1251                 
1252                 yLim = RecalcZoomAxesLimits('y', yLim, mDefaultYLim, cy, zoomPct);
1253             end
1254         end
1255         
1256         SetAxesLimits(xLim, yLim);
1257     end
1258 %--------------------------------------------------------------------------
1259 
1260 %==========================================================================
1261     function zoomPct = GetZoomPercent(zoomIndex, zoomGrid)
1262         %GetZoomPercent get zoom percent
1263 
1264         if (nargin < 2)
1265             zoomGrid = mZoomGrid;
1266         end
1267         
1268         zoomPct = zoomGrid(zoomIndex);       
1269     end
1270 %--------------------------------------------------------------------------
1271 
1272 %==========================================================================
1273     function zoomIndex = ChangeZoomIndex(direction, zoomIndex, zoomSteps)
1274         %ChangeZoomIndex
1275         
1276         if (nargin < 3)
1277             zoomSteps = mZoomSteps;
1278         end
1279         
1280         switch direction
1281             case 'plus'
1282                 if (zoomIndex < zoomSteps)
1283                     zoomIndex = zoomIndex + 1;
1284                 end
1285             case 'minus'
1286                 if (zoomIndex > 1)
1287                     zoomIndex = zoomIndex - 1;
1288                 end
1289         end
1290     end
1291 %--------------------------------------------------------------------------
1292 
1293 %==========================================================================
1294     function axLim = RecalcZoomAxesLimits(ax, axLim, axLimDflt, zcCrd, zoomPct)
1295         %RecalcZoomAxesLimits recalc axes limits
1296         
1297         if strcmp(get(hAx, [ax, 'scale']), 'log')
1298             axLim = log10(axLim);
1299             axLim = FixInfLogLimits(ax, axLim);
1300             axLimDflt = log10(axLimDflt);
1301             zcCrd = log10(zcCrd);
1302             isLog = true;
1303         else
1304             isLog = false;
1305         end
1306                 
1307         if (zcCrd < axLim(1)), zcCrd = axLim(1); end
1308         if (zcCrd > axLim(2)), zcCrd = axLim(2); end
1309         
1310         rf = range(axLim);
1311         ra = range([axLim(1), zcCrd]);
1312         rb = range([zcCrd, axLim(2)]);
1313         
1314         cfa = ra / rf; 
1315         cfb = rb / rf;
1316         
1317         newRange = range(axLimDflt) * 100 / zoomPct;
1318         dRange = newRange - rf;
1319         
1320         axLim(1) = axLim(1) - dRange * cfa;
1321         axLim(2) = axLim(2) + dRange * cfb;
1322         
1323         if isLog
1324             axLim = 10.^axLim;
1325         end
1326     end
1327 %--------------------------------------------------------------------------
1328 
1329 %==========================================================================
1330     function UpdateCurrentZoomAxes()
1331         %UpdateCurrentZoomAxes
1332         
1333         [xLim, yLim] = GetAxesLimits();
1334         [curentZoomX, curentZoomY] = GetCurrentZoomAxesPercent(xLim, yLim);
1335         
1336         if (curentZoomX ~= GetZoomPercent(mZoomIndexX))
1337             [nu, mZoomIndexX] = min(abs(mZoomGrid - curentZoomX));  %#ok ([~, ...])
1338         end
1339         if (curentZoomY ~= GetZoomPercent(mZoomIndexY))
1340             [nu, mZoomIndexY] = min(abs(mZoomGrid - curentZoomY));  %#ok ([~, ...])
1341         end
1342     end
1343 %--------------------------------------------------------------------------
1344 
1345 %==========================================================================
1346     function [curentZoomX, curentZoomY] = GetCurrentZoomAxesPercent(xLim, yLim)
1347         %GetCurrentZoomAxesPercent
1348         
1349         if strcmp(get(hAx, 'xscale'), 'log')
1350             xLim = log10(xLim);
1351             defaultXLim = log10(mDefaultXLim);
1352         else
1353             defaultXLim = mDefaultXLim;
1354         end
1355         if strcmp(get(hAx, 'yscale'), 'log')
1356             yLim = log10(yLim);
1357             defaultYLim = log10(mDefaultYLim);
1358         else
1359             defaultYLim = mDefaultYLim;
1360         end
1361         
1362         curentZoomX = range(defaultXLim) * 100 / range(xLim);
1363         curentZoomY = range(defaultYLim) * 100 / range(yLim);
1364     end
1365 %--------------------------------------------------------------------------
1366 
1367 %==========================================================================
1368     function ZoomMouse3D(direction)
1369         %ZoomMouse3D
1370         
1371         if IsZoomMouseAllowed
1372             [wcx, wcy] = GetCursorCoordOnWindow('pixels');
1373             ZoomAxes3D(direction, wcx, wcy)
1374         end
1375     end
1376 %--------------------------------------------------------------------------
1377 
1378 %==========================================================================
1379     function ZoomMouseExtendBegin3D()
1380         %ZoomMouseExtendBegin3D
1381         
1382         if ~fIsZoomExtend3DAllowed
1383             UpdateCurrentZoomAxes3D();
1384             [wcx, wcy] = GetCursorCoordOnWindow('pixels');
1385             
1386             % set new zoom grid for extend zoom
1387             SetNewZoomGrid3D(mZoomMinPow, mZoomMaxPow, mZoom3DExtendNum);
1388             
1389             mZoom3DStartX = wcx;
1390             mZoom3DStartY = wcy;
1391             
1392             mZoom3DBindX = wcx;
1393             mZoom3DBindY = wcy;
1394             
1395             fIsZoomExtend3DAllowed = true;
1396         end
1397     end
1398 %--------------------------------------------------------------------------
1399 
1400 %==========================================================================
1401     function ZoomMouseExtendEnd3D()
1402         %ZoomMouseExtendEnd3D
1403         
1404         if fIsZoomExtend3DAllowed
1405             SetDefaultZoomGrid3D();
1406             
1407             fIsZoomExtend3DAllowed = false;
1408         end
1409     end
1410 %--------------------------------------------------------------------------
1411 
1412 %==========================================================================
1413     function ZoomMouseExtend3D()
1414         %ZoomMouseExtended3D
1415         
1416         if fIsZoomExtend3DAllowed
1417             directions = {'minus', 'plus'};
1418             
1419             switch mZoomScroll
1420                 case 'normal'
1421                 case 'reverse'
1422                     directions = fliplr(directions);
1423             end
1424         
1425             % Heuristic for pixel change to camera zoom factor
1426             % (taken from function ZOOM)
1427             [wcx, wcy] = GetCursorCoordOnWindow('pixels');
1428             
1429             xy(1) = wcx - mZoom3DStartX;
1430             xy(2) = wcy - mZoom3DStartY;
1431             q = max(-0.9, min(0.9, sum(xy)/70)) + 1;
1432    
1433             if (q < 1)
1434                 direction = directions{1};
1435             elseif (q > 1)
1436                 direction = directions{2};
1437             else
1438                 return;
1439             end
1440             
1441             ZoomAxes3D(direction, mZoom3DBindX, mZoom3DBindY)
1442             
1443             mZoom3DStartX = wcx;
1444             mZoom3DStartY = wcy;
1445         end
1446     end
1447 %--------------------------------------------------------------------------
1448 
1449 %==========================================================================
1450     function ZoomAxes3D(direction, cx, cy)
1451         %ZoomAxes3D
1452         
1453         mZoom3DIndex = ChangeZoomIndex(direction, mZoom3DIndex, mZoomSteps);
1454         zoomPct = GetZoomPercent(mZoom3DIndex, mZoomGrid);
1455         
1456         axPos = GetObjPos(hAx, 'pixels');
1457         
1458         [axPos(1), axPos(3)] = RecalcZoomAxesPos3D(axPos(1), axPos(3), ...
1459             mDefaultAxPos(3), cx, zoomPct);
1460         
1461         [axPos(2), axPos(4)] = RecalcZoomAxesPos3D(axPos(2), axPos(4), ...
1462             mDefaultAxPos(4), cy, zoomPct);
1463         
1464         SetObjPos(hAx, axPos, 'pixels');
1465     end
1466 %--------------------------------------------------------------------------
1467 
1468 %==========================================================================
1469     function [npc, nsz] = RecalcZoomAxesPos3D(pc, sz, dfltSz, zcCrd, zoomPct)
1470         %RecalcZoomAxesPos3D
1471         
1472         dd = dfltSz * zoomPct / 100 - sz;
1473         rng = range([pc zcCrd]);
1474         cf = rng / sz; 
1475         nsz = sz + dd;
1476         npc = pc - dd * cf;
1477     end
1478 %--------------------------------------------------------------------------
1479         
1480 %==========================================================================
1481     function UpdateCurrentZoomAxes3D()
1482         %UpdateCurrentZoomAxes3D
1483         
1484         curentZoom = GetCurrentZoomAxesPercent3D();
1485         [nu, mZoom3DIndex] = min(abs(mZoomGrid - curentZoom));  %#ok ([~, ...])
1486     end
1487 %--------------------------------------------------------------------------
1488 
1489 %==========================================================================
1490     function currentZoom = GetCurrentZoomAxesPercent3D()
1491         %GetCurrentZoomAxesPercent3D
1492 
1493         axPos = GetObjPos(hAx, 'pixels');
1494         currentZoom = axPos(3) / mDefaultAxPos(3) * 100;
1495     end
1496 %--------------------------------------------------------------------------
1497 
1498 %==========================================================================
1499     function ZoomKeys3D(direction)
1500         %ZoomKeys3D
1501         
1502         UpdateCurrentZoomAxes3D();
1503         SetNewZoomGrid3D(mZoomMinPow, mZoomMaxPow, mZoom3DKeysNum);
1504         
1505         [wcx, wcy] = GetCursorCoordOnWindow('pixels');
1506         ZoomAxes3D(direction, wcx, wcy)
1507     end
1508 %--------------------------------------------------------------------------
1509 
1510 %==========================================================================
1511     function SetNewZoomGrid3D(minPow, maxPow, num)
1512         %SetNewZoomGrid3D set new zoom grid for 3D mode
1513         
1514         [mZoomGrid, mZoomSteps] = ZoomLogGrid(minPow, maxPow, num);
1515         UpdateCurrentZoomAxes3D();
1516     end
1517 %--------------------------------------------------------------------------
1518 
1519 %==========================================================================
1520     function SetDefaultZoomGrid()
1521         %SetDefaultZoomGrid set default zoom grid
1522         
1523         [mDefaultZoomGrid, mDefaultZoomSteps] = ...
1524             ZoomLogGrid(mZoomMinPow, mZoomMaxPow, mZoomNum);
1525         
1526         mZoomGrid = mDefaultZoomGrid;
1527         mZoomSteps = mDefaultZoomSteps;
1528         
1529         mZoomIndexX = find(mZoomGrid == 100);
1530         mZoomIndexY = mZoomIndexX;
1531         mZoom3DIndex = mZoomIndexX;
1532     end
1533 %--------------------------------------------------------------------------
1534 
1535 %==========================================================================
1536     function SetDefaultZoomGrid3D()
1537         %SetDefaultZoomGrid for 3D mode
1538         
1539         mZoomGrid = mDefaultZoomGrid;
1540         mZoomSteps = mDefaultZoomSteps;
1541         UpdateCurrentZoomAxes3D();
1542     end
1543 %--------------------------------------------------------------------------
1544 
1545 %==========================================================================
1546     function VisibleAxesKeys3D()
1547         %VisibleAxesKeys3D
1548         
1549         axi = GetCurrentAxesIndex();
1550         
1551         if mAxesInfo(axi).isvisible
1552             set(hAx, 'Visible', 'off');
1553             mAxesInfo(axi).isvisible = false;
1554         else
1555             set(hAx, 'Visible', 'on');
1556             mAxesInfo(axi).isvisible = true;
1557         end
1558     end
1559 %--------------------------------------------------------------------------
1560 
1561 %==========================================================================
1562     function SwitchAspectRatioKeys3D()
1563         %SwitchAspectRatioKeys3D
1564         
1565         axi = GetCurrentAxesIndex();
1566         
1567         if mAxesInfo(axi).isvis3d
1568             axis(hAx, 'normal');
1569             mAxesInfo(axi).isvis3d = false;
1570         else
1571             axis(hAx, 'vis3d');
1572             mAxesInfo(axi).isvis3d = true;
1573         end
1574     end
1575 %--------------------------------------------------------------------------
1576 
1577 %==========================================================================
1578     function RotateMouseBegin3D()
1579         %RotateMouseBegin3D
1580         
1581         if ~fIsRotate3DAllowed
1582             [wcx, wcy] = GetCursorCoordOnWindow('pixels');
1583             
1584             [az, el] = view(hAx);
1585             
1586             mRotStartAZ = az;
1587             mRotStartEL = el;
1588             mRotStartX = wcx;
1589             mRotStartY = wcy;
1590                         
1591             fIsRotate3DAllowed = true;
1592         end
1593     end
1594 %--------------------------------------------------------------------------
1595 
1596 %==========================================================================
1597     function RotateMouseEnd3D()
1598         %RotateMouseEnd3D
1599         
1600         if fIsRotate3DAllowed
1601             fIsRotate3DAllowed = false;
1602         end
1603     end
1604 %--------------------------------------------------------------------------
1605 
1606 %==========================================================================
1607     function RotateMouse3D()
1608         %RotateMouse3D
1609         
1610         if fIsRotate3DAllowed
1611             [wcx, wcy] = GetCursorCoordOnWindow('pixels');
1612             
1613             dAZ = mRotStartX - wcx;
1614             dEL = mRotStartY - wcy;
1615             
1616             az = mRotStartAZ + dAZ;
1617             el = mRotStartEL + dEL;
1618             
1619             SetView3D(az, el);
1620         end
1621     end
1622 %--------------------------------------------------------------------------
1623 
1624 %==========================================================================
1625     function RotateKeys3D(mode)
1626         %RotateKeys3D
1627         
1628         [az, el] = view(hAx);
1629                 
1630         switch lower(mode)
1631             case 'xy'
1632                 az = 0;
1633                 el = 90;                
1634             case 'xz'
1635                 az = 0;
1636                 el = 0;
1637             case 'yz'
1638                 az = 90;
1639                 el = 0;
1640             case 'az+'
1641                 az = az + mRot3DKeysInc;
1642             case 'az-'
1643                 az = az - mRot3DKeysInc;
1644             case 'el+'
1645                 el = el + mRot3DKeysInc;
1646             case 'el-'
1647                 el = el - mRot3DKeysInc;
1648         end
1649         
1650         SetView3D(az, el)
1651     end
1652 %--------------------------------------------------------------------------
1653 
1654 %==========================================================================
1655     function SetView3D(az, el)
1656         %SetView3D
1657         
1658         if (el > 90), el = 90; end
1659         if (el < -90), el = -90; end
1660         
1661         view(hAx, [az, el]);
1662     end
1663 %--------------------------------------------------------------------------
1664 
1665 %==========================================================================
1666     function PointerCrossOn()
1667         %PointerCrossOn
1668         
1669         if ~fIsPointerCross
1670             %SetPointer('fullcrosshair');
1671             [xlim, ylim] = GetAxesLimits();
1672             x = (xlim(2)-xlim(1))/2;
1673             y = (ylim(2)-ylim(1))/2;
1674             state = get(hAx, 'NextPlot');
1675             hold on;
1676             hcross = [ line('Parent', hAx, 'Xdata', [x, x], 'Ydata', [y, y])   % horizontal
1677                        line('Parent', hAx, 'Xdata', [x, x], 'Ydata', [y, y])]; % vertical
1678             set(hcross, 'HitTest', 'off');
1679             set(hAx, 'NextPlot', state);
1680             % text objects
1681             h = [
1682                 text('Parent', hAx)     % left
1683                 text('Parent', hAx)     % right
1684                 text('Parent', hAx)     % bottom
1685                 text('Parent', hAx)     % top
1686                 ];
1687             
1688             % create pointer cross struct
1689             mPointerCross = struct(...
1690                 'htext',     h, ...
1691                 'left',      1, ...
1692                 'right',     2, ...
1693                 'bottom',    3, ...
1694                 'top',       4, ...
1695                 'hcross',    hcross, ...
1696                 'horizontal',1, ...
1697                 'vertical',  2);
1698             
1699             PointerCrossSetup();
1700             fIsPointerCross = true;
1701             PointerCrossUpdate();
1702         end
1703     end
1704 %--------------------------------------------------------------------------
1705 
1706 %==========================================================================
1707     function PointerCrossOff()
1708         %PointerCrossOff
1709         
1710         if fIsPointerCross
1711             delete(mPointerCross.htext);
1712             delete(mPointerCross.hcross);
1713             SetPointer('arrow');
1714             fIsPointerCross = false;
1715             mPointerCross = [];
1716         end
1717     end
1718 %--------------------------------------------------------------------------
1719 
1720 %==========================================================================
1721     function PointerCrossSetup()
1722         %PointerCrossSetup
1723         
1724         left = mPointerCross.left;
1725         right = mPointerCross.right;
1726         bottom = mPointerCross.bottom;
1727         top = mPointerCross.top;
1728         
1729         vabt = {'top', 'bottom'};
1730         if fIsImage
1731             vabt = fliplr(vabt);
1732         end
1733         
1734         set(mPointerCross.htext(left), 'VerticalAlignment', 'bottom');
1735         set(mPointerCross.htext(right), 'VerticalAlignment', 'bottom');
1736         set(mPointerCross.htext(bottom), 'VerticalAlignment', vabt{1});
1737         set(mPointerCross.htext(top), 'VerticalAlignment', vabt{2});
1738         
1739         bgColor = [251 248 230]/255;
1740         set(mPointerCross.htext(left), 'BackgroundColor', bgColor);
1741         set(mPointerCross.htext(right), 'BackgroundColor', bgColor);
1742         set(mPointerCross.htext(bottom), 'BackgroundColor', bgColor);
1743         set(mPointerCross.htext(top), 'BackgroundColor', bgColor);
1744         
1745         edColor = [180 180 180]/255;
1746         set(mPointerCross.htext(left), 'EdgeColor', edColor);
1747         set(mPointerCross.htext(right), 'EdgeColor', edColor);
1748         set(mPointerCross.htext(bottom), 'EdgeColor', edColor);
1749         set(mPointerCross.htext(top), 'EdgeColor', edColor);
1750     end
1751 %--------------------------------------------------------------------------
1752 
1753 %==========================================================================
1754     function PointerCrossUpdate()
1755         %PointerCrossUpdate
1756         
1757         if fIsPointerCross
1758             [xlim, ylim] = GetAxesLimits();
1759             [acx, acy] = GetCursorCoordOnAxes();
1760             
1761             if acx <= xlim(1), acx = xlim(1); end
1762             if acx >= xlim(2), acx = xlim(2); end
1763             if acy <= ylim(1), acy = ylim(1); end
1764             if acy >= ylim(2), acy = ylim(2); end
1765 
1766             left = mPointerCross.left;
1767             right = mPointerCross.right;
1768             bottom = mPointerCross.bottom;
1769             top = mPointerCross.top;
1770             vertical = mPointerCross.vertical;
1771             horizontal = mPointerCross.horizontal;
1772                         
1773             if fIsImage
1774                 xValStr = sprintf(' %d ', round(acx));
1775                 yValStr = sprintf(' %d ', round(acy));
1776             else
1777                 xtick = get(hAx, 'XTick');
1778                 ytick = get(hAx, 'YTick');
1779                 
1780                 %FIXME:
1781                 prth = 5;
1782                 
1783                 [lenTick, maxi] = max(arrayfun(@(x) length(num2str(x)), xtick));
1784                 atick = abs(xtick(maxi));
1785                 flt = mod(atick, 1);
1786                 
1787                 if (flt == 0)
1788                     countDigX = lenTick + 1;
1789                     if countDigX > prth
1790                         countDigX = prth;
1791                     end
1792                 else
1793                     countDigX = length(num2str(atick));
1794                     if (fix(acx) == 0)
1795                         countDigX = countDigX - 1;
1796                     end
1797                 end
1798                 
1799                 [lenTick, maxi] = max(arrayfun(@(x) length(num2str(x)), ytick));
1800                 atick = abs(ytick(maxi));
1801                 flt = mod(atick, 1);
1802                 
1803                 if (flt == 0)
1804                     countDigY = lenTick + 1;
1805                     if countDigY > prth
1806                         countDigY = prth;
1807                     end
1808                 else
1809                     countDigY = length(num2str(atick));
1810                     if (fix(acy) == 0)
1811                         countDigY = countDigY - 1;
1812                     end
1813                 end
1814                 
1815                 xValStr = sprintf(' %.*g ', countDigX, acx);
1816                 yValStr = sprintf(' %.*g ', countDigY, acy);
1817             end
1818             
1819             set(mPointerCross.htext(left), 'String', yValStr);
1820             set(mPointerCross.htext(right), 'String', yValStr);
1821             set(mPointerCross.htext(bottom), 'String', xValStr);
1822             set(mPointerCross.htext(top), 'String', xValStr);
1823             
1824             extent = get(mPointerCross.htext(left), 'Extent');
1825             xx = extent(3);
1826             
1827             if strcmp(get(hAx, 'xscale'), 'log')
1828                 leftx = xlim(1);
1829             else
1830                 leftx = xlim(1) - xx;
1831             end
1832             
1833             set(mPointerCross.htext(left), 'Position', [leftx, acy]);
1834             set(mPointerCross.htext(right), 'Position', [xlim(2) acy]);
1835             set(mPointerCross.htext(bottom), 'Position', [acx, ylim(1)]);
1836             set(mPointerCross.htext(top), 'Position', [acx, ylim(2)]);
1837             set(mPointerCross.hcross(horizontal), 'Xdata', xlim, 'Ydata', [acy, acy]);
1838             set(mPointerCross.hcross(vertical),   'Xdata', [acx, acx], 'Ydata', ylim);
1839         end
1840     end
1841 %--------------------------------------------------------------------------
1842 
1843 %==========================================================================
1844     function RubberBandBegin()
1845         %RubberBandBegin
1846         
1847         if (~fIsRubberBandOn && ~fIsMagnifierOn)
1848             [acx, acy] = GetCursorCoordOnAxes();
1849             
1850             % create rubber band struct
1851             mRubberBand = struct(...
1852                 'obj',    [patch('Parent', hAx), patch('Parent', hAx)], ...
1853                 'x1',      acx, ...
1854                 'y1',      acy, ...
1855                 'x2',      acx, ...
1856                 'y2',      acy);
1857             
1858             hAxes2d = GetHandlesAxes2D();
1859             if ~isempty(hAxes2d)
1860                 set(hAxes2d, ...
1861                     'XLimMode', 'manual', ...
1862                     'YLimMode', 'manual');
1863             end
1864             
1865             RubberBandSetPos();
1866             RubberBandSetup();
1867             fIsRubberBandOn = true;
1868         end
1869     end
1870 %--------------------------------------------------------------------------
1871 
1872 %==========================================================================
1873     function RubberBandEnd()
1874         %RubberBandEnd
1875         
1876         if fIsRubberBandOn
1877             fIsRubberBandOn = false;
1878             
1879             delete(mRubberBand.obj);          
1880             RubberBandZoomAxes();
1881             PointerCrossUpdate();
1882             mRubberBand = [];
1883         end
1884     end
1885 %--------------------------------------------------------------------------
1886 
1887 %==========================================================================
1888     function RubberBandUpdate()
1889         %RubberBandUpdate
1890         
1891         if fIsRubberBandOn
1892             [acx, acy] = GetCursorCoordOnAxes();
1893             
1894             mRubberBand.x2 = acx;
1895             mRubberBand.y2 = acy;
1896             RubberBandSetPos();
1897         end
1898     end
1899 %--------------------------------------------------------------------------
1900 
1901 %==========================================================================
1902     function RubberBandSetPos()
1903         %RubberBandSetPos set position of rubber band
1904         
1905         x1 = mRubberBand.x1;
1906         y1 = mRubberBand.y1;
1907         x2 = mRubberBand.x2;
1908         y2 = mRubberBand.y2;
1909         
1910         set(mRubberBand.obj, ...
1911             'XData', [x1 x2 x2 x1], ...
1912             'YData', [y1 y1 y2 y2]);
1913     end
1914 %--------------------------------------------------------------------------
1915 
1916 %==========================================================================
1917     function RubberBandSetup()
1918         %RubberBandSetup
1919         
1920         set(mRubberBand.obj(1), ...
1921             'EdgeColor', 'w', ...
1922             'FaceColor', 'none', ...
1923             'LineWidth', 1.5, ...
1924             'LineStyle', '-');
1925         
1926         set(mRubberBand.obj(2), ...
1927             'EdgeColor', mRbEdgeColor, ...
1928             'FaceColor', mRbFaceColor, ...
1929             'FaceAlpha', mRbFaceAlpha, ...
1930             'LineWidth', 0.5, ...
1931             'LineStyle', '-');    
1932     end
1933 %--------------------------------------------------------------------------
1934 
1935 %==========================================================================
1936     function RubberBandZoomAxes()
1937         %RubberBandZoomAxes apply zoom from rubber band
1938         
1939         xLim = sort([mRubberBand.x1, mRubberBand.x2]);
1940         yLim = sort([mRubberBand.y1, mRubberBand.y2]);
1941         
1942         if (range(xLim) == 0 || range(yLim) == 0)
1943             return;
1944         end
1945         
1946         [zoomPctX, zoomPctY] = GetCurrentZoomAxesPercent(xLim, yLim);
1947         
1948         if fIsImage
1949             zoomPctX = min(zoomPctX, zoomPctY);
1950             zoomPctY = zoomPctX;
1951         end
1952         
1953         cx = mean(xLim);
1954         cy = mean(yLim);
1955         
1956         xLim = RecalcZoomAxesLimits('x', xLim, mDefaultXLim, cx, zoomPctX);
1957         yLim = RecalcZoomAxesLimits('y', yLim, mDefaultYLim, cy, zoomPctY);
1958         
1959         SetAxesLimits(xLim, yLim);
1960     end
1961 %--------------------------------------------------------------------------
1962 
1963 %==========================================================================
1964     function MagnifierOn()
1965         %MagnifierCreate
1966         
1967         if ~fIsMagnifierOn    
1968             if fIsPointerCross
1969                 isPointerCross = true;
1970                 PointerCrossOff();
1971             else
1972                 isPointerCross = false;
1973             end
1974             
1975             mMgDirection = 'plus';
1976             
1977             % create magnifier struct
1978             mMagnifier = struct(...
1979                 'obj',          copyobj(hAx, hFig), ...
1980                 'frame_obj',    [], ...
1981                 'size',         mMgSize, ...
1982                 'zoom',         mMgZoom);
1983             
1984             fIsMagnifierOn = true;
1985             MagnifierSetup();
1986             MagnifierUpdate();
1987             
1988             if isPointerCross
1989                 PointerCrossOn();
1990             end
1991         end
1992     end
1993 %--------------------------------------------------------------------------
1994 
1995 %==========================================================================
1996     function MagnifierOff()
1997         %MagnifierOff
1998         
1999         if fIsMagnifierOn
2000             fIsMagnifierOn = false;
2001             set(hAx, 'Color', get(mMagnifier.obj, 'Color'));
2002             
2003             delete(mMagnifier.obj);
2004             mMagnifier = [];
2005         end
2006     end
2007 %--------------------------------------------------------------------------
2008 
2009 %==========================================================================
2010     function MagnifierUpdate()
2011         %MagnifierUpdate
2012         
2013         if fIsMagnifierOn            
2014             % see original idea of magnify by Rick Hindman -- 7/29/04
2015             % http://www.mathworks.com/matlabcentral/fileexchange/5961
2016             
2017             [acx, acy] = GetCursorCoordOnAxes();
2018             [wcx, wcy] = GetCursorCoordOnWindow('pixels');
2019             
2020             [xLim, yLim] = GetAxesLimits();
2021             
2022             if strcmp(get(hAx, 'xscale'), 'log')
2023                 xLim = log10(xLim);
2024                 xLim = FixInfLogLimits('x', xLim);
2025                 acx = log10(acx);
2026                 isXLog = true;
2027             else
2028                 isXLog = false;
2029             end
2030             if strcmp(get(hAx, 'yscale'), 'log')
2031                 yLim = log10(yLim);
2032                 yLim = FixInfLogLimits('y', yLim);
2033                 acy = log10(acy);
2034                 isYLog = true;
2035             else
2036                 isYLog = false;
2037             end
2038             
2039             figPos = GetObjPos(hFig, 'pixels');
2040             axPos = GetObjPos(hAx, 'normalized');
2041             
2042             % always square magnifier
2043             pbar = get(hAx, 'PlotBoxAspectRatio');
2044             af = pbar(1) / pbar(2);
2045             if (af == 1 && (pbar(1) == 1 && pbar(2) == 1))
2046                 af = figPos(3) / figPos(4);
2047             end
2048             
2049             mgSizePix = round(mMagnifier.size);
2050             mgZoom = mMagnifier.zoom;
2051             
2052             mgSize = mgSizePix / figPos(3); % normalized size
2053             
2054             mgPos(3) = mgSize * 2;
2055             mgPos(4) = mgPos(3) * af;
2056             
2057             mg3 = round(mgPos(3) * figPos(3));
2058             mg4 = round(mgPos(4) * figPos(4));
2059             
2060             if (mg4 < mg3)
2061                 mgSize = (mgSizePix * (mg3 / mg4)) / figPos(3);
2062             end
2063             
2064             mgPos(3) = mgSize * 2;
2065             mgPos(4) = mgPos(3) * af;
2066             
2067             mgPos(1) = wcx / figPos(3) - mgSize;
2068             mgPos(2) = wcy / figPos(4) - mgSize * af;
2069             
2070             mgXLim = acx + (1 / mgZoom) * (mgPos(3) / axPos(3)) * diff(xLim) * [-0.5 0.5];
2071             mgYLim = acy + (1 / mgZoom) * (mgPos(4) / axPos(4)) * diff(yLim) * [-0.5 0.5];
2072             
2073             SetObjPos(mMagnifier.obj, mgPos, 'normalized');
2074             
2075             if isXLog
2076                 mgXLim = 10.^mgXLim;
2077             end
2078             if isYLog
2079                 mgYLim = 10.^mgYLim;
2080             end
2081             
2082             set(mMagnifier.obj, ...
2083                 'XLim', mgXLim, ...
2084                 'YLim', mgYLim);
2085             
2086             MagnifierBorderUpdate();
2087         end
2088     end
2089 %--------------------------------------------------------------------------
2090 
2091 %==========================================================================
2092     function MagnifierSetup()
2093         %MagnifierSetup
2094 
2095         set(mMagnifier.obj, ...
2096             'Box', 'on', ...
2097             'XMinorTick', 'on', ...
2098             'YMinorTick', 'on');
2099         
2100         title(mMagnifier.obj, '');
2101         xlabel(mMagnifier.obj, ''); 
2102         ylabel(mMagnifier.obj, '');
2103         
2104         if fIsImage
2105             mMagnifier.frame_obj = ...
2106                 [patch('Parent', mMagnifier.obj), ...
2107                 patch('Parent', mMagnifier.obj)];
2108             
2109             set(mMagnifier.frame_obj, 'FaceColor', 'none');
2110             
2111             set(mMagnifier.frame_obj(1), ...
2112                 'LineWidth', 1.5, ...
2113                 'EdgeColor', 'w')
2114             set(mMagnifier.frame_obj(2), ...
2115                 'LineWidth', 1, ...
2116                 'EdgeColor', 'k')
2117             
2118             MagnifierBorderUpdate();
2119         end
2120         
2121         hLines = findobj(mMagnifier.obj, 'Type', 'line');
2122         if ~isempty(hLines)
2123             if (mMgLinesWidth ~= 1)
2124                 set(hLines, 'LineWidth', mMgLinesWidth);
2125             end
2126         end
2127         
2128         set(hAx, 'Color', get(hAx, 'Color')*mMgShadow);
2129     end
2130 %--------------------------------------------------------------------------
2131 
2132 %==========================================================================
2133     function MagnifierBorderUpdate()
2134         %MagnifierBorderUpdate
2135         
2136         if fIsImage
2137             x = get(mMagnifier.obj, 'XLim');
2138             y = get(mMagnifier.obj, 'YLim');
2139             
2140             set(mMagnifier.frame_obj, ...
2141                 'XData', [x(1) x(2) x(2) x(1)], ...
2142                 'YData', [y(1) y(1) y(2) y(2)]);
2143         end
2144     end
2145 %--------------------------------------------------------------------------
2146 
2147 %==========================================================================
2148     function MagnifierSizeChange(direction)
2149         %MagnifierSizeChange
2150         
2151         if fIsMagnifierOn
2152             switch direction
2153                 case 'plus'
2154                     if (mMagnifier.size < mMgMaxSize)
2155                         mMagnifier.size = mMagnifier.size + mMgSizeStep;
2156                     end
2157                 case 'minus'
2158                     if (mMagnifier.size > mMgMinSize)
2159                         mMagnifier.size = mMagnifier.size - mMgSizeStep;
2160                     end
2161             end
2162             
2163             MagnifierUpdate();
2164         end
2165     end
2166 %--------------------------------------------------------------------------
2167 
2168 %==========================================================================
2169     function MagnifierZoomChange(direction)
2170         %MagnifierZoomChange
2171         
2172         if fIsMagnifierOn
2173             switch direction
2174                 case 'plus'
2175                     if (mMagnifier.zoom < mMgMaxZoom)
2176                         mMagnifier.zoom = mMagnifier.zoom * mMgZoomStep;
2177                     end
2178                 case 'minus'
2179                     if (mMagnifier.zoom > mMgMinZoom)
2180                         mMagnifier.zoom = mMagnifier.zoom / mMgZoomStep;
2181                     end
2182             end
2183             
2184             MagnifierUpdate();
2185         end
2186     end
2187 %--------------------------------------------------------------------------
2188 
2189 %==========================================================================
2190     function MagnifierReset()
2191         %MagnifierReset
2192         
2193         if fIsMagnifierOn
2194             mMagnifier.size = mMgSize;
2195             mMagnifier.zoom = mMgZoom;
2196             MagnifierUpdate();
2197         end
2198     end
2199 %--------------------------------------------------------------------------
2200 
2201 %==========================================================================
2202     function SetLinkAxesKeys(modifier)
2203         %SetLinkAxesKeys Set Linking of 2-D axes
2204         
2205         if isempty(modifier)
2206             mLinkOpt = 'xy';
2207         else
2208             switch modifier{1}
2209                 case 'control'
2210                     mLinkOpt = 'x';
2211                 case 'alt'
2212                     mLinkOpt = 'y';
2213             end
2214         end
2215         
2216         if fIsLinkAxesOn
2217             LinkAxesOff();
2218         else
2219             LinkAxesOn();
2220         end
2221         
2222         UserData = get(hFig, 'UserData');
2223         UserData.tools.islinkaxeson = fIsLinkAxesOn;
2224         set(hFig, 'UserData', UserData);
2225     end
2226 %--------------------------------------------------------------------------
2227 
2228 %==========================================================================
2229     function LinkAxesOn()
2230         %LinkAxesOn On of 2-D axes linking
2231         
2232         if ~fIsLinkAxesOn
2233             hAxes2d = GetHandlesAxes2D();
2234             if (length(hAxes2d) > 1)
2235                 linkaxes(hAxes2d, mLinkOpt);
2236                 fIsLinkAxesOn = true;
2237                 SetFigureName();
2238             end
2239         end
2240     end
2241 %--------------------------------------------------------------------------
2242 
2243 %==========================================================================
2244     function LinkAxesOff()
2245         %LinkAxesOff Off of 2-D axes linking
2246         
2247         if fIsLinkAxesOn
2248             fIsLinkAxesOn = false;
2249             
2250             SetFigureName();
2251             hAxes2d = GetHandlesAxes2D();
2252             linkaxes(hAxes2d, 'off');    
2253         end
2254     end
2255 %--------------------------------------------------------------------------
2256 
2257 %==========================================================================
2258     function DeleteOldTools()
2259         %DeleteOldTools
2260         
2261         UserData = get(hFig, 'UserData');
2262         
2263         if (~isempty(UserData) && isfield(UserData, 'tools'))
2264             if ~isempty(UserData.tools.pointercross) && ...
2265                 isempty(find(ishandle(UserData.tools.pointercross) == 0))
2266                 mPointerCross = UserData.tools.pointercross;
2267                 fIsPointerCross = true;
2268                 PointerCrossOff();
2269                 UserData.tools.pointercross = [];
2270             end
2271             
2272             if UserData.tools.islinkaxeson
2273                 fIsLinkAxesOn = true;
2274                 LinkAxesOff();
2275                 UserData.tools.islinkaxeson = false;
2276             end
2277             
2278             set(hFig, 'UserData', UserData);
2279         end
2280     end
2281 %--------------------------------------------------------------------------
2282 
2283 %==========================================================================
2284     function hAxes2d = GetHandlesAxes2D()
2285         %GetHandlesAxes2D Get handles of 2-D axes
2286         
2287         isAxes2d = arrayfun(@(x) x.is2d && ~x.islegend, mAxesInfo);
2288         hAxes2d = hAxes(isAxes2d);
2289         
2290         if ~isempty(hAxes2d)
2291             % Set current axes on first position
2292             hAxes2d(eq(hAxes2d, hAx)) = 0;
2293             hAxes2d = sort(hAxes2d);
2294             hAxes2d(eq(hAxes2d, 0)) = hAx;
2295         end
2296     end
2297 %--------------------------------------------------------------------------
2298 
2299 %==========================================================================
2300     function ResetAxesToOrigView()
2301         %ResetAxesToOrigView reset axes to original limits
2302         
2303         SetAxesLimits(mDefaultXLim, mDefaultYLim);
2304         PointerCrossUpdate();
2305         
2306         mZoomIndexX = find(mZoomGrid == 100);
2307         mZoomIndexY = mZoomIndexX;
2308     end
2309 %--------------------------------------------------------------------------
2310 
2311 %==========================================================================
2312     function ResetAxesToOrigView3D()
2313         %ResetAxesToOrigView3D reset axes to original position in 3D mode
2314         
2315         % position reset
2316         axi = GetCurrentAxesIndex();
2317         pos = mAxesInfo(axi).normposition;
2318         SetObjPos(hAx, pos, 'normalized');
2319         
2320         % view reset
2321         resetplotview(hAx, 'ApplyStoredView'); % (!!!) undocumented function
2322         
2323         if mAxesInfo(axi).isvis3d
2324             axis(hAx, 'vis3d');
2325         end
2326         
2327         % zoom reset
2328         mZoom3DIndex = find(mZoomGrid == 100);
2329     end
2330 %--------------------------------------------------------------------------
2331 
2332 %==========================================================================
2333     function [x, y, z] = GetCursorCoordOnAxes()
2334         %GetCursorCoordOnAxImg
2335         
2336         crd = get(hAx, 'CurrentPoint');
2337         x = crd(2,1);
2338         y = crd(2,2);
2339         z = crd(2,3);
2340     end
2341 %--------------------------------------------------------------------------
2342 
2343 %==========================================================================
2344     function [x, y] = GetCursorCoordOnWindow(units)
2345         %GetCursorCoordOnWindow
2346         
2347         if (nargin < 1), units = 'pixels'; end
2348         
2349         dfltUnits = get(hFig, 'Units');
2350         set(hFig, 'Units', units);
2351         
2352         crd = get(hFig, 'CurrentPoint');
2353         x = crd(1); 
2354         y = crd(2);
2355         
2356         set(hFig, 'Units', dfltUnits);
2357     end
2358 %--------------------------------------------------------------------------
2359 
2360 %==========================================================================
2361     function pos = GetObjPos(h, units)
2362         %GetObjPos get object position
2363         
2364         if (nargin < 2), units = get(h, 'Units'); end
2365         
2366         dfltUnits = get(h, 'Units');
2367         set(h, 'Units', units);
2368         pos = get(h, 'Position');
2369         set(h, 'Units', dfltUnits);
2370     end
2371 %--------------------------------------------------------------------------
2372 
2373 %==========================================================================
2374     function SetObjPos(h, pos, units)
2375         %SetObjPos set object position
2376         
2377         if (nargin < 3), units = get(h, 'Units'); end
2378         
2379         dfltUnits = get(h, 'Units');
2380         set(h, 'Units', units);
2381         set(h, 'Position', pos);
2382         set(h, 'Units', dfltUnits);
2383     end
2384 %--------------------------------------------------------------------------
2385 
2386 %==========================================================================
2387     function [xLim, yLim] = GetAxesLimits()
2388         %GetAxesLimits
2389         
2390         xLim = get(hAx, 'XLim');
2391         yLim = get(hAx, 'YLim');
2392     end
2393 %--------------------------------------------------------------------------
2394 
2395 %==========================================================================
2396     function SetAxesLimits(xLim, yLim)
2397         %SetAxesLimits
2398         
2399         set(hAx, 'XLim', xLim);
2400         set(hAx, 'YLim', yLim);
2401     end
2402 %--------------------------------------------------------------------------
2403 
2404 %==========================================================================
2405     function SetPointerCrossKeys()
2406         %SetPointerCrossKeys set pointer fullcross
2407         
2408         if fIsPointerCross
2409             PointerCrossOff();
2410         else
2411             PointerCrossOn();
2412         end
2413         
2414         UserData = get(hFig, 'UserData');
2415         UserData.tools.pointercross = mPointerCross;
2416         set(hFig, 'UserData', UserData);
2417     end
2418 %--------------------------------------------------------------------------
2419 
2420 %==========================================================================
2421     function SetPointer(pointerType)
2422         %SetPointer set pointer symbol
2423         
2424         set(hFig, 'Pointer', pointerType);
2425     end
2426 %--------------------------------------------------------------------------
2427 
2428 %==========================================================================
2429     function SetAxesGridKeys()
2430         %SetAxesGridKeys on/off axes grid
2431         
2432         if fIsAxesGrid
2433             action = 'off';
2434             fIsAxesGrid = false;
2435         else
2436             action = 'on';
2437             fIsAxesGrid = true;
2438         end
2439         
2440         set(hAx, 'XGrid', action, 'YGrid', action, 'ZGrid', action);
2441         
2442         if fIsMagnifierOn
2443             set(mMagnifier.obj, 'XGrid', action, 'YGrid', action);
2444         end
2445     end
2446 %--------------------------------------------------------------------------
2447 
2448 %==========================================================================
2449     function SetSmoothKeys()
2450         %SetSmoothKeys on/off cmoothing plots
2451         
2452         if fIsSmoothing
2453             action = 'off';
2454             fIsSmoothing = false;
2455         else
2456             action = 'on';
2457             fIsSmoothing = true;
2458         end
2459         
2460         if ~fIsImage
2461             %FIXME: bug with switching opengl/painter renderer here
2462             %Lost figure focus
2463             hLine = findobj(hAx, 'Type', 'Line');
2464             if ~isempty(hLine)
2465                 set(hLine, 'LineSmooth', action);   % !!! Undocumented property
2466             end
2467         end
2468     end
2469 %--------------------------------------------------------------------------
2470 
2471 %==========================================================================
2472     function [zg, st] = ZoomLogGrid(a, b, n)
2473         %ZoomLogGrid log zoom grid
2474         
2475         zg = unique(round(logspace(a, b, n)));
2476         
2477         zg(zg<10) = [];    % begin zoom == 10%
2478         st = length(zg);
2479         
2480         if isempty(find(zg == 100, 1))
2481             error('dragzoom:badZoomGridOptions', 'Options for zoom grid is bad.')
2482         end
2483     end
2484 %--------------------------------------------------------------------------
2485 
2486 %==========================================================================
2487     function tf = IsZoomMouseAllowed()
2488         %IsZoomMouseAllowed
2489         
2490         [wcx, wcy] = GetCursorCoordOnWindow();
2491 %         cur_units = get(hAxes, 'Units');
2492 %         set(hAxes, 'Units', 'pixels');
2493 %         figPos = get(hAxes, 'Position');
2494 %         set(hAxes, 'Units', cur_units);
2495         
2496         cur_units = get(gca, 'Units');
2497         set(gca, 'Units', 'pixels');
2498         figPos = get(gca, 'Position');
2499         set(gca, 'Units', cur_units);
2500 
2501         Xrange = [figPos(1), figPos(1)+figPos(3)];
2502         Yrange = [figPos(2), figPos(2)+figPos(4)];
2503         if (Xrange(1) <= wcx && wcx <= Xrange(2)) && ...
2504            (Yrange(1) <= wcy && wcx <= Yrange(2))
2505             tf = true;
2506         else
2507             tf = false;
2508         end
2509     end
2510 %--------------------------------------------------------------------------
2511 
2512 %==========================================================================
2513     function tf = IsImageOnAxes(ax)
2514         %IsImageOnAxes
2515         
2516         if (nargin < 1), ax = hAx; end
2517         
2518         h = findobj(ax, 'Type', 'Image');
2519         
2520         if isempty(h)
2521             tf = false;
2522         else
2523             tf = true;
2524         end
2525     end
2526 %--------------------------------------------------------------------------
2527 
2528 %==========================================================================
2529     function tf = IsAxes2D(ax)
2530         %IsAxes2D
2531         
2532         if (nargin < 1), ax = hAx; end
2533         
2534         if isempty(fMode)
2535             tf = is2D(ax); % (!!!) internal undocumented function
2536         elseif strcmpi(fMode, '2d')
2537             tf = true;
2538         else
2539             tf = false;
2540         end
2541     end
2542 %--------------------------------------------------------------------------
2543 
2544 %==========================================================================
2545     function tf = IsLegendAxes(ax)
2546         %IsLegendAxes
2547         
2548         tf = strcmp(get(ax, 'Tag'), 'legend');
2549     end
2550 %--------------------------------------------------------------------------
2551 
2552 %==========================================================================
2553     function targetInBounds = IsInBoundsAxes(ax)
2554         %InBoundsAxes Check if the user clicked within the bounds of the axes. If not, do nothing
2555         
2556         targetInBounds = true;
2557         tol = 3e-16;
2558         cp = get(ax, 'CurrentPoint');
2559         
2560         XLims = get(ax, 'XLim');
2561         if ((cp(1,1) - min(XLims)) < -tol || (cp(1,1) - max(XLims)) > tol) && ...
2562                 ((cp(2,1) - min(XLims)) < -tol || (cp(2,1) - max(XLims)) > tol)
2563             targetInBounds = false;
2564         end
2565         
2566         YLims = get(ax, 'YLim');
2567         if ((cp(1,2) - min(YLims)) < -tol || (cp(1,2) - max(YLims)) > tol) && ...
2568                 ((cp(2,2) - min(YLims)) < -tol || (cp(2,2) - max(YLims)) > tol)
2569             targetInBounds = false;
2570         end
2571         
2572         ZLims = get(ax, 'ZLim');
2573         if ((cp(1,3) - min(ZLims)) < -tol || (cp(1,3) - max(ZLims)) > tol) && ...
2574                 ((cp(2,3) - min(ZLims)) < -tol || (cp(2,3) - max(ZLims)) > tol)
2575             targetInBounds = false;
2576         end
2577     end
2578 %--------------------------------------------------------------------------
2579 
2580 %==========================================================================
2581     function tf = IsCurrentAxes(ax)
2582         %IsCurrentAxes
2583         
2584         hcAx = get(hFig, 'CurrentAxes');
2585         tf = eq(ax, hcAx);
2586     end
2587 %--------------------------------------------------------------------------
2588 
2589 %==========================================================================
2590     function tf = IsAxesVis3D(ax)
2591         %IsAxesVis3D
2592         
2593         visProp = {
2594             get(ax, 'PlotBoxAspectRatioMode')
2595             get(ax, 'DataAspectRatioMode')
2596             get(ax, 'CameraViewAngleMode')
2597             };
2598         
2599         tf = all(strcmpi(visProp, 'manual'));
2600     end
2601 %--------------------------------------------------------------------------
2602 
2603 %==========================================================================
2604     function AxesInfo = GetAxesInfo()
2605         %GetAxesInfo make and get axes info struct
2606         
2607         countAxes = length(hAxes);
2608         
2609         AxesInfo = struct(...
2610             'handle',       cell(1, countAxes), ...
2611             'iscurrent',    cell(1, countAxes), ...
2612             'is2d',         cell(1, countAxes), ...
2613             'isimage',      cell(1, countAxes), ...  
2614             'isvisible',    cell(1, countAxes), ...  
2615             'isvis3d',      cell(1, countAxes), ...
2616             'islegend',     cell(1, countAxes), ...
2617             'position',     cell(1, countAxes), ...
2618             'normposition', cell(1, countAxes), ...
2619             'xlim',         cell(1, countAxes), ...
2620             'ylim',         cell(1, countAxes), ...
2621             'camtarget',    cell(1, countAxes), ...
2622             'camposition',  cell(1, countAxes));
2623         
2624         for i = 1:countAxes
2625             h = hAxes(i);
2626             
2627             AxesInfo(i).handle = h;
2628             AxesInfo(i).iscurrent = IsCurrentAxes(h);
2629             AxesInfo(i).is2d = IsAxes2D(h);
2630             AxesInfo(i).isimage = IsImageOnAxes(h);
2631             AxesInfo(i).isvisible = strcmpi(get(h, 'Visible'), 'on');
2632             AxesInfo(i).isvis3d = IsAxesVis3D(h);
2633             AxesInfo(i).islegend = IsLegendAxes(h);
2634             AxesInfo(i).position = GetObjPos(h, 'pixels');
2635             AxesInfo(i).normposition = GetObjPos(h, 'normalized');
2636             AxesInfo(i).xlim = get(h, 'XLim');
2637             AxesInfo(i).ylim = get(h, 'YLim');
2638             AxesInfo(i).camtarget = get(h, 'CameraTarget');
2639             AxesInfo(i).camposition = get(h, 'CameraPosition');
2640         end
2641     end
2642 %--------------------------------------------------------------------------
2643 
2644 %==========================================================================
2645     function SelectAxesUnderCursor()
2646         %SelectAxesUnderCursor select axes under cursor as current
2647         
2648         axi = GetAxesIndexUnderCursor();
2649         
2650         if (axi > 0)
2651             fIsEnableControl = true;
2652             
2653             if ~mAxesInfo(axi).iscurrent
2654                 caxi = GetCurrentAxesIndex();
2655                 
2656                 if isempty(caxi)
2657                     DeleteInvalidAxesInfo();
2658                     
2659                     axi = GetAxesIndexUnderCursor();
2660                     isCax2d = mAxesInfo(axi).is2d;
2661                 else
2662                     isCax2d = mAxesInfo(caxi).is2d;
2663                 end
2664                 
2665                 SetCurrentAxes(axi);
2666                 
2667                 % for fix "legend" axes capture
2668                 if mAxesInfo(axi).islegend;
2669                     fIsMouseOnLegend = true;
2670                 else
2671                     fIsMouseOnLegend = false;
2672                 end
2673                 
2674                 % check callbacks
2675                 if (isCax2d ~= mAxesInfo(axi).is2d)
2676                     % if dimension of axes has changed
2677                     SetCallbacks();
2678                     
2679                     if fIsPointerCross
2680                         % disable pointer cross
2681                         PointerCrossOff()
2682                     end
2683                 else
2684                     if fIsPointerCross
2685                         % reset pointer cross
2686                         PointerCrossOff()
2687                         SetPointerCrossKeys()
2688                     end
2689                 end
2690             end
2691         else
2692             fIsEnableControl = false;
2693         end
2694     end
2695 %--------------------------------------------------------------------------
2696 
2697 %==========================================================================
2698     function SetCurrentAxes(axi)
2699         %SetCurrentAxes set current axes and work mode
2700         
2701         hAx = mAxesInfo(axi).handle;
2702         
2703         set(hFig, 'CurrentAxes', hAx);
2704         for i = 1:numel(mAxesInfo)
2705             mAxesInfo(i).iscurrent = false;
2706         end
2707         mAxesInfo(axi).iscurrent = true;
2708         
2709         fIsAxes2D = mAxesInfo(axi).is2d;
2710         fIsImage = mAxesInfo(axi).isimage;
2711         
2712         mDefaultAxPos = mAxesInfo(axi).position;
2713         mDefaultXLim = mAxesInfo(axi).xlim;
2714         mDefaultYLim = mAxesInfo(axi).ylim;
2715         
2716         % save info to work correctly after saving figures
2717         UserData = get(hFig, 'UserData');
2718         UserData.axesinfo = mAxesInfo;
2719         set(hFig, 'UserData', UserData);
2720     end
2721 %--------------------------------------------------------------------------
2722 
2723 %==========================================================================
2724     function axi = GetCurrentAxesIndex()
2725         %GetCurrentAxesIndex
2726         
2727         axi = [];
2728         
2729         for i = 1:numel(mAxesInfo)
2730             if (ishandle(mAxesInfo(i).handle) && mAxesInfo(i).iscurrent)
2731                 axi = i;
2732                 return;
2733             end
2734         end
2735     end
2736 %--------------------------------------------------------------------------
2737 
2738 %==========================================================================
2739     function axi = GetAxesIndexUnderCursor()
2740         %FindAxesUnderCursor find current axes under cursor
2741         
2742         axi = GetCurrentAxesIndex();
2743         
2744         if ~fIsSelectedCurrentAxes
2745             caxi = GetCurrentAxesIndex();
2746             if ~IsInBoundsAxes(mAxesInfo(caxi).handle)
2747                 axi = 0;
2748             end
2749             return;
2750         end
2751         
2752         for i = 1:numel(mAxesInfo)
2753             if (ishandle(mAxesInfo(i).handle) && IsInBoundsAxes(mAxesInfo(i).handle))
2754                 axi = i;
2755                 return;
2756             else
2757                 axi = 0; % without axes
2758             end
2759         end
2760     end
2761 %--------------------------------------------------------------------------
2762 
2763 %==========================================================================
2764     function axLim = FixInfLogLimits(ax, axLim)
2765         %FixInfLogLimits Fix Axes Inf Log Limits
2766         
2767         if (~all(isfinite(axLim)) || ~all(isreal(axLim)))
2768             
2769             % The following code has been taken from zoom.m
2770             % If any of the public limits are inf then we need the actual limits
2771             % by getting the hidden deprecated RenderLimits.
2772             oldstate = warning('off', 'MATLAB:HandleGraphics:NonfunctionalProperty:RenderLimits');
2773             renderlimits = get(hAx, 'RenderLimits');
2774             warning(oldstate);
2775             
2776             switch ax
2777                 case 'x'
2778                     axLim = renderlimits(1:2);
2779                 case 'y'
2780                     axLim = renderlimits(3:4);
2781             end
2782             axLim = log10(axLim);
2783         end
2784     end
2785 %--------------------------------------------------------------------------
2786 
2787 %==========================================================================
2788     function DeleteInvalidAxesInfo()
2789         %DeleteInvalidAxesInfo
2790         
2791         invalidAxes = arrayfun(@(x) ~ishandle(x.handle), mAxesInfo);
2792         mAxesInfo(invalidAxes) = [];
2793         hAxes(invalidAxes) = [];
2794     end
2795 %--------------------------------------------------------------------------
2796 
2797 %==========================================================================
2798     function isWithStatus = ParseInputs(varargin)
2799         %ParseInputs parse input arguments
2800         
2801         isWithStatus = false;
2802         
2803         switch nargin
2804             case 0
2805                 hObj = gcf;
2806                 status = 'on';
2807                 ih = 0;
2808             case 1
2809                 if ischar(varargin{1})
2810                     isWithStatus = true;
2811                     hObj = gcf;
2812                     status = varargin{1};
2813                     ih = 2;
2814                     is = 1;
2815                 else
2816                     hObj = varargin{1};
2817                     status = 'on';
2818                     ih = 1;
2819                     is = 2;
2820                 end
2821             case 2
2822                 % (hFig, status)
2823                 isWithStatus = true;
2824                 hObj = varargin{1};
2825                 status = varargin{2};
2826                 ih = 1;
2827                 is = 2;
2828         end
2829         
2830         switch lower(status)
2831             case 'on'
2832                 fIsEnabled = true;
2833             case 'off'
2834                 fIsEnabled = false;
2835             case '2d'
2836                 fIsEnabled = true;
2837                 fMode = '2d';
2838             case '3d'
2839                 fIsEnabled = true;
2840                 fMode = '3d';
2841             otherwise
2842                 error('dragzoom:invalidInputs', ...
2843                     'Input Argument %d must be a string "on" or "off".', is)
2844         end
2845         
2846         if all(ishandle(hObj))
2847             handleType = get(hObj(1), 'Type');
2848             
2849             switch handleType
2850                 case 'axes'
2851                     hAxes = unique(hObj);
2852                     hFig = ancestor(hAxes(1), 'figure');
2853                     
2854                 case 'figure'
2855                     hFig = hObj;
2856                     hAxes = findobj(hFig, 'Type', 'axes'); % all axes
2857                     
2858                     if isempty(hAxes)
2859                         warning('dragzoom:notFoundAxes', 'Not found axes objects on figure.')
2860                     end
2861                     
2862                 otherwise
2863                     error('dragzoom:invalidHandle', ...
2864                         'Input Argument %d must be figure or axes handle.', ih)
2865             end
2866         else
2867             error('dragzoom:invalidInputs', ...
2868                 'Input Argument %d must be a figure or axes handle.', ih)
2869         end
2870     end
2871 %--------------------------------------------------------------------------
2872 
2873 %==========================================================================
2874     function res = range(x)
2875         %RANGE
2876         
2877         res = abs(diff([min(x) max(x)]));
2878     end
2879 %--------------------------------------------------------------------------
2880 
2881 end % DRAGZOOM
2882

Generated on Mon 22-May-2023 06:53:56 by m2html © 2005