Code covered by the BSD License  

Highlights from
choose_profile_limits

image thumbnail
from choose_profile_limits by Kevin Bartlett
Allows user to choose limits of oceanographic profile (e.g., CTD cast)

draglines(varargin)
function varargout = draglines(varargin)
%
% draglines.m--Permits mouse-dragging of lines in a plot.
%
% Line-dragging can be freeform or restricted to either the x or
% y-direction by specifying the 'action' argument to be 'x', 'y' or 'xy'.
% The default in the absence of an action string is 'xy'.
%
% An action of 'revert' returns the line(s) to their original location. An
% action of 'off' freezes the line in its current position, which then
% becomes its "revert" position.
%
% A second string argument containing a Matlab command can be included in
% calls to enable line-dragging. This string will be evaluated and run
% after each line-drag is complete.
%
% The current offset of line(s) from their original position can be queried
% by calling draglines.m with a single output argument and either zero
% input arguments or a single input argument specifying which lines to
% query.
%
% If a line is not specified, all lines in the current axes are affected.
%
% Syntax: <offset> = draglines(<lineHndl>,<action>)
%
% e.g.,   x=linspace(0,40,200);h(1)=line(x,sin(x));h(2)=line(x,cos(x./2),'color','r');
%         set(gca,'xlim',[-10 50],'ylim',[-1.5 1.5]); set(gcf,'pos',[1039 530 240 195]);
%         draglines
%         draglines(h)
%         draglines('x')
%         draglines(h,'y')
%         draglines(h,'xy',['sprintf(''[%d %d %d]'',get(gco,''color''))'])
%         draglines(h,'revert')
%         draglines('revert')
%         draglines(h,'off')
%         draglines('off')
%         offset = draglines
%         offset = draglines(h)

% Developed in Matlab 6.5.1.199709 (R13) Service Pack 1 on SUN OS 5.8.
% Kevin Bartlett(kpb@hawaii.edu), 2004/04/05, 11:04
%------------------------------------------------------------------------------

% Define constants.
XDRAG = 1;
YDRAG = 2;
XYDRAG = 3;
REVERT = 4;
OFF = 5;
STARTDRAG = 6;
ENDDRAG = 7;
REMOVEZOOMSTATE = 8;
QUERY = 9;

% Test to see if this is a recursive call to draglines.m. Recursive calls
% have the format: draglines(lineHndl,'recursion','action'), where 'action'
% is a string specifying the action to be taken.
if nargin == 3 & isstr(varargin{2}) & strcmp(varargin{2},'recursion')==1
   
   lineHndl = varargin{1};
   isRecursive = 1;
   actionStr = varargin{3};
   
else 
   isRecursive = 0;
end % if

% If not a recursive call, still need to sort out the input arguments.
if isRecursive == 0

    if nargin>3
        error([mfilename '.m--Incorrect number of input arguments.']);
    end % if
    
    actionStr = 'xy'; % Default
    lineHndl = 'lineHndl not specified'; % Dummy value
    postDragActionStr = '';
    
    for argCount = 1:nargin
        
        thisArg = varargin{argCount};
        
        if all(ishandle(thisArg))
            lineHndl = thisArg;
        else
            
            if ~isstr(thisArg)
                error([mfilename '.m--actionStr and postDragActionStr input arguments must be strings.']);
            else
                
                if ismember(thisArg,{'x' 'y' 'xy' 'revert' 'off'})
                    actionStr = thisArg;
                else
                    postDragActionStr = thisArg;
                end % if
                
            end % if
            
        end % if        
        
    end % for
    
    % If lineHndl was not specified by user, it will currently have a
    % string value. In this case, lineHndl should contain handles to all
    % lines in the current axes.
    if isstr(lineHndl)
        lineHndl = findobj(gca,'type','line');
    end % if
    
    % If draglines.m was called with an output argument, it is being called
    % to query the status of any lines. In this case, override the
    % actionStr and postDragActionStr values.
    if nargout > 0
        
        if isempty(lineHndl)
            varargout{1} = [];
        else
            actionStr = 'query';
            postDragActionStr = '';
        end % if
        
    end % if
   
    %disp(['actionStr is ' actionStr]);
    %disp(['postDragActionStr is ' postDragActionStr]);
    %disp(['lineHndl is ' lineHndl]);
    
end % if not recursive

if ~all(ishandle(lineHndl)==1) | ~all(ismember(get(lineHndl,'type'),'line'))
   error([mfilename '.m--Input argument ''lineHndl'' must be a vector of handles to line objects.']);
end % if

numLines = length(lineHndl);

actionStr = lower(actionStr);

if strcmp(actionStr,'x')
   action = XDRAG;
elseif strcmp(actionStr,'y')
   action = YDRAG;
elseif strcmp(actionStr,'xy')
   action = XYDRAG;
elseif strcmp(actionStr,'revert')
   action = REVERT;
elseif strcmp(actionStr,'off')
   action = OFF;
elseif strcmp(actionStr,'startdrag')
   action = STARTDRAG;
elseif strcmp(actionStr,'enddrag')
   action = ENDDRAG;
elseif strcmp(actionStr,'removezoomstate')
   action = REMOVEZOOMSTATE;
elseif strcmp(actionStr,'query')
   action = QUERY;   
else
   error([mfilename '.m--Unrecognised action string: ''' actionStr '''.']);
end % if

%disp(['Action is: ' actionStr])
%disp(['Handles are ' sprintf('%f\n',lineHndl)])

if isRecursive == 0 & ismember(action,[XDRAG YDRAG XYDRAG]);   
   
   % Remove any zoom state.
   draglines(lineHndl,'recursion','removezoomstate');
   set(gcf,'pointer','fleur');
   
   for lineCount = 1:numLines
      thisLine = lineHndl(lineCount);
      set(thisLine,'ButtonDownFcn',['draglines( gco, ''recursion'', ''startdrag''  )']);
      setappdata(thisLine,'draglines_action',action);
      setappdata(thisLine,'draglines_offset',[0 0]);
      setappdata(thisLine,'postDragActionStr',postDragActionStr);
   end % for
   
elseif isRecursive == 0 & action == REVERT      
   
   for lineCount = 1:numLines
      
      thisLine = lineHndl(lineCount);
      setappdata(thisLine,'draglines_action',action);        
      xdata = get(thisLine,'xdata');
      ydata = get(thisLine,'ydata');
      offset = getappdata(thisLine,'draglines_offset');
      set(thisLine,'xdata',xdata-offset(1),'ydata',ydata-offset(2));
      setappdata(thisLine,'draglines_offset',[0 0]);
      setappdata(thisLine,'postDragActionStr',postDragActionStr);
      
   end % for
   
elseif isRecursive == 0 & action == OFF

   set(lineHndl,'ButtonDownFcn',[]);
   set(gcf,'pointer',get(0,'factoryFigurePointer'));
   
   for lineCount = 1:numLines

       thisLine = lineHndl(lineCount);
       setappdata(thisLine,'draglines_offset',[0 0]);
       
    end % for
   
elseif isRecursive == 1 & action == STARTDRAG
   
   % Remove any zoom state.
   draglines(lineHndl,'recursion','removezoomstate');
   
   thisLine = gco;
   currentPoint = get(gca,'CurrentPoint');
   currentPoint = [currentPoint(1,1) currentPoint(1,2)];
   
   setappdata(thisLine,'draglines_lastPos',currentPoint);   
   set(gcf,'WindowButtonUpFcn',['draglines( gco, ''recursion'', ''enddrag''  )']);   
   
elseif isRecursive == 1 & action == ENDDRAG
   
   thisLine = gco;
   endPoint = get(gca,'currentpoint');
   endPoint = [endPoint(1,1) endPoint(1,2)];
   
   lastPos = getappdata(thisLine,'draglines_lastPos');  
   moveBy = endPoint - lastPos;
   
   % Find out if dragging in x-direction, y-direction, or mixed x-y
   % direction.
   thisAction = getappdata(thisLine,'draglines_action');
   
   if thisAction == XDRAG
      moveBy(2) = 0;
   elseif thisAction == YDRAG
      moveBy(1) = 0;
   end % if
   
   xdata = get(thisLine,'xdata');
   ydata = get(thisLine,'ydata');
   set(thisLine,'xdata',xdata+moveBy(1),'ydata',ydata+moveBy(2));
   
   oldOffset = getappdata(thisLine,'draglines_offset');
   newOffset = oldOffset + moveBy;
   setappdata(thisLine,'draglines_offset',newOffset);
   
   set(gcf,'WindowButtonUpFcn','');   

   % Evaluate post-dragging action string.
   postDragActionStr = getappdata(thisLine,'postDragActionStr');
   eval(postDragActionStr);
   
elseif isRecursive == 1 & action == REMOVEZOOMSTATE
   
   % Switch to non-zoom state.
   set(gcf,'WindowButtonDownFcn','');
   
   % Get handles to axes' zoom buttons.
   HiddenState = get(0,'ShowHiddenHandles');
   set(0,'ShowHiddenHandles','on');
   figToolZoomIn = findobj('tag','figToolZoomIn');
   figToolZoomOut = findobj('tag','figToolZoomOut');
   set(0,'ShowHiddenHandles',HiddenState);
   
   set(figToolZoomIn,'state','off');
   set(figToolZoomOut,'state','off');
   
end % if

% Return an output argument, if requested.
if nargout == 1

   if action == QUERY
   
      offsetsOut = zeros(numLines,2);
      
      for lineCount = 1:numLines
         thisLine = lineHndl(lineCount);
         thisLineOffsets = getappdata(thisLine,'draglines_offset');
         
         if ~isempty(thisLineOffsets)
            offsetsOut(lineCount,:) = thisLineOffsets;
         end % if
         
      end % for
      
      varargout{1} = offsetsOut;
      
   else
      % Return empty variable if output requested for non-query call.
      varargout{1} = [];
   end % if
   
elseif nargout ~= 0
   error([mfilename '.m--Wrong number of output arguments.']);
end % if

Contact us at files@mathworks.com