Code covered by the BSD License  

Highlights from
CLICKUICONTROL

from CLICKUICONTROL by Jiro Doke
Emulates clicking on a UIcontrol object.

clickUIcontrol(h, focus, opt)
function clickUIcontrol(h, focus, opt)

%CLICKUICONTROL  Emulate clicking on a UIControl object
%   CLICKUICONTROL(H) behaves as if clicking on a UIControl object. The
%   object can be one of the following: pushbutton, checkbox, radiobutton,
%   togglebutton, slider, listbox, popupmenu. The Value property of the
%   object will be appropriately set, and the object's Callback is called
%   (ButtonDownFcn will be called if the object's Enable property is set to
%   OFF or INACTIVE). It will work with callbacks defined as strings or
%   function handles. The UICONTROL will not be brought to focus.
%
%   CLICKUICONTROL(H, 'focus') brings focus to the object. This is useful
%   for bringing focus to an EDIT box. Default is 'nofocus'.
%
%   CLICKUICONTROL(H, OPT)  or CLICKUICONTROL(H, 'focus', OPT)
%   Some objects accept a additional argument OPT. Acceptable arguments are
%   dependent on the style of UIControl object.
%
%     SLIDER:
%       '-'   : Click on the decreasing arrow.
%       '+'   : Click on the increasing arrow.
%       '--'  : Click on the decreasing slider trough.
%       '++'  : Click on the increasing slider trough.
%       '.'   : Click without change of value.
%
%     LISTBOX:
%       'top' : Select the top-most element.
%       'end' : Select the last element.
%       '+'   : Select the next element.
%       '-'   : Select the previous element.
%       '.'   : Select the current element.
%       N     : Select the N-th element. Can also be an array if multi
%               selection is permitted.
%
%     POPUPMENU:
%       'top' : Select the top-most element.
%       'end' : Select the last element.
%       '+'   : Select the next element.
%       '-'   : Select the previous element.
%       '.'   : Select the current element.
%       N     : Select the N-th element.
%
% Example:
%
%     h1 = uicontrol('style', 'slider', ...
%       'position', [5 5 150 20], ...
%       'callback', 'disp(get(h1, ''value''));');
%     h2 = uicontrol('style', 'pushbutton', ...
%       'position', [5 40 150 20], ...
%       'string', 'Change Figure Color', ...
%       'callback', 'set(gcbf, ''Color'', rand(1, 3))');
%     h3 = uicontrol('style', 'popupmenu', ...
%       'position', [5 75 150 20], ...
%       'string', {'Red', 'Green', 'Blue'}, ...
%       'value', 1, ...
%       'callback', 'fprintf(''Item # %d selected.\n'', get(gcbo, ''value''))');
%     h4 = uicontrol('style', 'edit', ...
%       'position', [5 110 150 20]);
% 
%     clickUIcontrol(h1, '++');     % increase slider value
%     clickUIcontrol(h2);           % click on button 2
%     clickUIcontrol(h3, 2);        % select item 2 of menu
%     clickUIcontrol(h4, 'focus')   % put cursor in edit box

%   VERSIONS:
%     v1.0 - first version
%     v1.1 - modify code based on MLINT
%     v1.2 - fix bug so that it works with UICONTROLs in panels. Also add
%            ability to set focus
%
% Copyright 2009 The MathWorks, Inc.

error(nargchk(1, 3, nargin, 'struct'));

if numel(h) ~= 1 || ~ishandle(h) || ~strcmpi(get(h, 'type'), 'uicontrol')
  error('clickUIcontrol:InvalidHandle', ...
    'It must be a handle to a UICONTROL');
end

if nargin == 1
  focus = 'nofocus';
  opt = '';
elseif nargin == 2
  if ischar(focus) && ismember(focus, {'focus', 'nofocus'})
    opt = '';
  else
    opt = focus;
    focus = 'nofocus';
  end
else
  if ischar(focus) && ismember(focus, {'focus', 'nofocus'})
  else
    if ischar(opt) && ismember(opt, {'focus', 'nofocus'})
      [focus, opt] = deal(opt, focus);
    else
      error('clickUIcontrol:InvalidInputArgs', ...
        'One of the input arguments must be either ''%s'' or ''%s''', ...
        'focus', 'nofocus');
    end
  end
end

cb = '';
switch lower(get(h, 'style'))
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % PUSHBUTTON
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  case 'pushbutton'
    if ~isempty(opt)
      warning('clickUIcontrol:IgnoreOption', 'Ignoring option...');
    end
    if strcmpi(get(h, 'enable'), 'on')
      cb = get(h, 'callback');
    else
      cb = get(h, 'buttondownfcn');
    end
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % CHECKBOX, RADIOBUTTON, TOGGLEBUTTON
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  case {'checkbox', 'radiobutton', 'togglebutton'}
    if ~isempty(opt)
      warning('clickUIcontrol:IgnoreOption', 'Ignoring option...');
    end
    if strcmpi(get(h, 'enable'), 'on')
      cb = get(h, 'callback');
      if get(h, 'value') == get(h, 'max')
        set(h, 'value', get(h, 'min'));
      else
        set(h, 'value', get(h, 'max'));
      end
    else
      cb = get(h, 'buttondownfcn');
    end
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % SLIDER
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  case 'slider'
    if strcmpi(get(h, 'enable'), 'on')
      cb = get(h, 'callback');
      
      sliderStep = get(h, 'sliderstep');
      sliderMax  = get(h, 'max');
      sliderMin  = get(h, 'min');
      sliderVal  = get(h, 'value');
      
      steps = [- (sliderMax - sliderMin) * sliderStep, ...
        (sliderMax - sliderMin) * sliderStep, 0];
      
      optChoices = {'-', '--', '+', '++', '.'};
      
      if isempty(opt)
        opt = '.';
      elseif ~ischar(opt) || ~ismember(opt, optChoices)
        error('clickUIcontrol:InvalidSliderStep', ...
          'Invalid step option for Slider.');
      end
      
      id = strmatch(opt, optChoices, 'exact');
      newSliderVal = sliderVal + steps(id);
      % make sure the new value is within the range:
      newSliderVal = max([min([newSliderVal, sliderMax]), sliderMin]);
      set(h, 'value', newSliderVal);
      
    else
      cb = get(h, 'buttondownfcn');
    end
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % LISTBOX
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  case 'listbox'
    if strcmpi(get(h, 'enable'), 'on')
      cb = get(h, 'callback');
      
      listboxMax = get(h, 'max');
      listboxMin = get(h, 'min');
      listboxStr = get(h, 'string');
      listboxVal = get(h, 'value');
      if ischar(listboxStr)
        listboxStr = {listboxStr};
      end
      
      isMulti = (listboxMax - listboxMin) > 1;
      
      optChoices = {'top', 'end', '+', '-', '.'};
      
      if isempty(opt)
        opt = '.';
      elseif ~ischar(opt) && ~isnumeric(opt)
        error('clickUIcontrol:InvalidListBoxOption', ...
          'Option must be either a string or a numeric array.');
      elseif ischar(opt) && ~ismember(opt, optChoices)
        error('clickUIcontrol:InvalidListBoxItem', ...
          'Invalid option for ListBox.');
      elseif isnumeric(opt) && min(size(opt)) > 1
        error('clickUIcontrol:VectorListBox', ...
          'Option must be 1-by-N numeric array.');
      end
      
      if ischar(opt)
        switch opt
          case 'top'
            listboxVal = 1;
          case 'end'
            listboxVal = length(listboxStr);
          case '+'
            listboxVal = min([length(listboxStr), listboxVal(end)+1]);
          case '-'
            listboxVal = max([1, listboxVal(1)-1]);
        end
      else % is a numeric array
        if ~isMulti && length(opt) > 1
          error('clickUIcontrol:SingleSelectListBox', ...
            'The ListBox is a single-select.');
        else
          if any(opt ~= fix(opt)) || min(opt) < 1 || ...
              max(opt) > length(listboxStr)
            error('clickUIcontrol:InvalidListBoxValue', ...
              'Invalid value for ListBox.');
          end
          listboxVal = opt;
        end
      end
      set(h, 'string', listboxStr, 'value', listboxVal);
      
    else
      cb = get(h, 'buttondownfcn');
    end
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % POPUPMENU
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  case 'popupmenu'
    if strcmpi(get(h, 'enable'), 'on')
      cb = get(h, 'callback');
      
      str = cellstr(get(h, 'string'));
      val = get(h, 'value');
      
      optChoices = {'top', 'end', '+', '-', '.'};
      
      if isempty(opt)
        opt = '.';
      elseif ~ischar(opt) && ~isnumeric(opt)
        error('clickUIcontrol:InvalidPopupMenuOption', ...
          'Option must be either a string or a scalar.');
      elseif ischar(opt) && ~ismember(opt, optChoices)
        error('clickUIcontrol:InvalidPopupMenuItem', ...
          'Invalid option for PopupMenu.');
      elseif isnumeric(opt) && numel(opt) > 1
        error('clickUIcontrol:ScalarPopupMenu', ...
          'Option must be a scalar.');
      end
      
      if ischar(opt)
        switch opt
          case 'top'
            val = 1;
          case 'end'
            val = length(str);
          case '+'
            val = min([length(str), val+1]);
          case '-'
            val = max([1, val-1]);
        end
      else % is a scalar
        if opt ~= fix(opt) || opt < 1 || opt > length(str)
          error('clickUIcontrol:InvalidMenuItem', ...
            'The value must be an integer within [1, %d].', length(str));
        end
        val = opt;
      end
      set(h, 'value', val);
      
    else
      cb = get(h, 'buttondownfcn');
    end
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % EDIT BOX
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  case 'edit'
    if ~isempty(opt)
      warning('clickUIcontrol:IgnoreOption', 'Ignoring option...');
    end
    if strcmpi(get(h, 'enable'), 'on')
      % just give focus (see below)
    else
      cb = get(h, 'buttondownfcn');
    end
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % TEXT BOX
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  case 'text'
    if ~isempty(opt)
      warning('clickUIcontrol:IgnoreOption', 'Ignoring option...');
    end
    if ~strcmpi(get(h, 'enable'), 'on')
      cb = get(h, 'buttondownfcn');
    end
    
  otherwise
    error('clickUIcontrol:InvalidUIControl', 'Invalid UI Control');
    
end

% set the current figure and object
hFig = ancestor(h, 'figure');
set(0, 'CurrentFigure', hFig);
set(hFig, 'CurrentObject', h);

% evaluate the Callback function
evaluateCallback(cb, h);

if strcmp(focus, 'focus')
  % bring focus
  uicontrol(h);
end

end

%%-------------------------------------------------------------------------
% Helper function for evaluating the Callback function of the UIControl
function evaluateCallback(cb, h)

if ~isempty(cb)
  switch class(cb)
    case 'function_handle'
      feval(cb, h, []);
    case 'cell'
      if strcmpi(class(cb{1}), 'function_handle')
        feval(cb{1}, h, [], cb{2:end});
      end
    case 'char'
      
      %%% Attempt to replace GCBO and GCBF with the appropriate GCO and GCF
      % This is necessary because Matlab will not recognize the original
      % callback object.
      cb = strrep(cb, 'gcbo', 'gco');
      cb = strrep(cb, 'gcbf', 'gcf');
      
      evalin('base', cb);
  end
end

end

Contact us