function varargout = respfcn(action,RespObj,varargin)
%RESPFCN  Perform user-specified action on Response Objects.
%
%   RESPFCN(ACTION,RespObj) performs the action specified by 
%   ACTION, for the Response Object, RespObj.
%
%   RespObj = RESPFCN(ACTION,RespObj) passes the updated Response Object
%   back to the calling function.

%   Authors: Karen Gondoly, 1-27-98
%   Revised: Adam DiVergilio, 2-2000
%   Copyright 1986-2000 The MathWorks, Inc. 
%   $Revision: 1.69 $  $Date: 2000/08/28 19:48:29 $

ni = nargin;
name = inputname(2);
ContextMenu = RespObj.UIContextMenu;

%---Initialize some variables
onFaceColor=[0 0 0];
offFaceColor=[.8 .8 .8];

try
%---Turn a watch on.
if ~strcmp(action,'zoom'),
   WatchFigNumber = watchon;
end

switch lower(action)
case 'closeselector',
   %---Callback from the Close button on the I/O selector
   %---Here, the second input argument is the ContextMenu
   set(RespObj,'ChannelSelector','off');
   
case 'initializeresponse',
   %--Invoked when 
   %    * initializing a new response plot (nextplot = 'replace')
   %    * adding to an exiting response plot (nextplot = 'add')
   %--Quick assign selections and visibility properties   
   [RespObj.SystemVisibility,RespObj.SelectedChannels,...
         RespObj.SelectedModels] = deal(varargin{1:3});
   
   %--Set zoom mode to 'tight' for Nyquist and Nichols
   if any(strcmp(RespObj.ResponseType,{'nyquist' 'nichols'}))
      % Set Zoom property to 'tight'
      RespObj.Zoom = 'tight';
      set(RespObj.UIContextMenu.ZoomMenu.ZoomTight,'Checked','on')
      RespObj.XlimMode = 'manual';
      RespObj.YlimMode = 'manual';
   end
   
   %--Make correct subset of plot axes visible
   %  RE: axes grouping must be performed first to get right axes lims
   if strcmp(RespObj.NextPlot,'replace')
      % New response
      set(RespObj.PlotAxes,'visible','on')
   else
      % Hold mode: use CONFIGAXES for axis layout
      configaxes(RespObj)
   end
   
   % Make correct ResponseHandles visible
   RespObj = modeltog(RespObj);
   
   % Adjust axis limits
   RespObj = axeslims(RespObj);
   
   %--Adjust labels.
   labeltog(RespObj)
   
case 'makeselector',
   %---Callback to initialize an I/O selector for the Response Object
   RespObj = LocalMakeSelector(RespObj,onFaceColor,offFaceColor);
   
case 'replotopt',
   IndShow = [];
   MarkerType = varargin{1};
   OptType = varargin{2};
   RespObj = LocalRemovePlotOpt(RespObj,MarkerType,IndShow);
   RespObj = feval(OptType,RespObj,IndShow);
   
case 'selectall',
   %---All text callback: make all channel visible
   set(RespObj,'SelectedChannels',logical(ones(size(RespObj.SelectedChannels))));
   
case 'selectcircle',
   %---CallbackObj for selecting markers on the I/O Selector Figure
   %---Toggle the selected state or multi-select based on the SelectionType
   OnChannels = RespObj.SelectedChannels;
   
   %---Get Selection Type and perform appropriate action
   downtype=get(gcbf,'SelectionType');
   switch downtype
   case {'open'}
      %---Double-click...no action
   case {'normal'}
      %---Click-left...show only that channel
      NewChannelInd=zeros(size(OnChannels));
      ijData=get(gcbo,'UserData');
      NewChannelInd(ijData(1),ijData(2))=1;
      set(RespObj,'SelectedChannels',logical(NewChannelInd))
      
   case 'extend'
      %---Shift-click left...multi select channels
      if get(gcbo,'Color')==onFaceColor, 
         ChannelVal=0;
      else
         ChannelVal=1;
      end
      
      %---Update AxesMenu Userdata
      ijData=get(gcbo,'UserData');
      OnChannels(ijData(1),ijData(2))=ChannelVal;
      %---Ignore if last channel has been deselected
      if any(logical(OnChannels(:)))
         set(RespObj,'SelectedChannels',logical(OnChannels))
      end

   case 'alt'
      %---Click-right...LTIdisplayAxes related line
      if isequal(get(gcbo,'color'),[0 0 0]),
         set(gcbo,'Color',[1 1 0],'MarkerFaceColor',[1 1 0])
         ijData=get(gcbo,'UserData');  % (i,j) coordinate
         IndIn = ijData(2); 
         
         % Get corresponding row index in PlotAxes array
         if any(strcmp(RespObj.ResponseType,{'bode','margin'})),
            IndPlotAx = [2*ijData(1)-1 , 2*ijData(1)];
         else
            IndPlotAx = ijData(1);
         end
         
         VisibleSys = strcmp(RespObj.SystemVisibility,'on');
         ResponseHandles = RespObj.ResponseHandles(VisibleSys);
         
         %---Initialize UserData for the Selector I/O window
         nsys = length(ResponseHandles);
         respline = cell(nsys,1);
         linestyle = cell(nsys,3);
         
         %---Find the appropriate channel for all the systems
         for ctsys=1:nsys,
            AllModelLines = cat(1,ResponseHandles{ctsys}{IndPlotAx,IndIn});
            respline{ctsys} = findobj(cat(1,AllModelLines{:}),'Tag','LTIresponseLines');
            linestyle(ctsys,:) = get(respline{ctsys}(1),{'Color','Linestyle','Marker'});
            set(respline{ctsys},'LineStyle','-','Linewidth',2)
         end
         
         CloseButton = findobj(gcbf,'Tag','SelectorCloseButton');
         udClose = get(CloseButton,'UserData');
         udClose.LineHandles = respline(:); 
         udClose.LineStyles = linestyle;
         udClose.SelectedDot = gcbo;
         set(gcbf,'WindowButtonUpFcn',...
            ['respfcn(''selectcirclebuttonup'',', ...
               'get(get(gcbf,''UserData''),''UserData''));'])
         set(CloseButton,'UserData',udClose)
      end % if isequal(gcbo color)
      
   end % switch downtype
   
case 'selectcirclebuttonup',
   %---Button up for an Alt selection type of a I/O selector button
   CloseButton = findobj(gcbf,'Tag','SelectorCloseButton');
   udClose = get(CloseButton,'UserData');
   
   %---Switch the dot color back
   set(udClose.SelectedDot,'Color',onFaceColor,'MarkerFaceColor',onFaceColor)
   
   %---Convert the line back
   for ctl=1:length(udClose.LineHandles),
      set(udClose.LineHandles{ctl},'Color',udClose.LineStyles{ctl,1},...
         'LineWidth',0.5,'Linestyle',udClose.LineStyles{ctl,2},...
         'Marker',udClose.LineStyles{ctl,3})
   end % for ctl
   
   %---Clear out the CloseButton UserData
   udClose.SelectedDot=[];
   udClose.LineHandles=[];
   set(CloseButton,'UserData',udClose)
   %---Put ContextMenu Handle back into UserData
   set(gcbf,'WindowButtonUpFcn',' ')
   
case 'selectrbbox'
   %---rbbox selection of I/O channels
   % Toggle the selected state or multi-select based on the SelectionType
   OnChannels = zeros(size(RespObj.SelectedChannels));
   
   SelectorFig = gcbf;
   ax=gcbo;
   dots = findobj(ax,'Marker','o');
   CP=get(ax,'CurrentPoint');
   maxX=max(get(ax,'Xlim'));
   maxY=max(get(ax,'Ylim'));
   
   %---Get figure current point data
   FigUnits=get(SelectorFig,'Unit');
   set(SelectorFig,'unit','norm');
   set(ax,'unit','norm');
   axpos=get(ax,'Position');
   P=get(SelectorFig,'CurrentPoint');
   
   %---Draw the rubberband box
   rect = rbbox;
   rect(1)=max([0,(rect(1)-axpos(1))]);
   rect(2)=max([0,(rect(2)-axpos(2))]);
   rect(1:2)=rect(1:2)./axpos(3:4);
   rect(3:4)=rect(3:4)./axpos(3:4);
   if rect(1)<0,
      rect(1)=0;
   end
   if rect(2)<0,
      rect(2)=0;
   end
   if rect(3)>1;
      rect(3)=1;
   end
   if rect(4)>1,
      rect(4)=1;
   end
   
   %---Get the current rectangle 
   XV=[rect(1);
      rect(1)+rect(3);
      rect(1)+rect(3);
      rect(1);
      rect(1)];
   
   YV=[rect(2);
      rect(2);
      rect(2)+rect(4);
      rect(2)+rect(4);
      rect(2)];
   
   Xdata = get(dots,'Xdata');
   Xdata = cat(1,Xdata{:});
   Ydata = get(dots,'Ydata');
   Ydata = cat(1,Ydata{:});
   
   Xdata=Xdata/maxX;
   Ydata=((ones(size(Ydata))*maxY)-Ydata)/maxY;
   
   indots=inpolygon(Xdata,Ydata,XV,YV);
   inds=find(indots);
   
   %---Return figure back to original units
   set(SelectorFig,'Unit',FigUnits);
   
   %---Proceed with callback based on whether systems or channels are selected
   if ~isempty(inds),
      for ctI=1:length(inds)
         ijData=get(dots(inds(ctI)),'UserData');
         OnChannels(ijData(1),ijData(2))=1;
      end
      set(RespObj,'SelectedChannels',logical(OnChannels))
   end
   
case 'selecttext',
   % Toggle the selected column on and off, turn everything else off
   OnChannels = zeros(size(RespObj.SelectedChannels));
   ToggleColor=get(gcbo,'Color');
   
   if isequal(ToggleColor,[1 0 0]); % Red, was on before
      ChannelVal=0;
   else
      ChannelVal=1;
   end % if/else isequal
   
   ud=get(gcbo,'UserData');
   if isequal(ud(2),1), % Selecting an output..highlight whole row
      OnChannels(ud(1),:)=1;
   else
      OnChannels(:,ud(1))=1;
   end
   
   %---Show appropriate response plots
   set(RespObj,'SelectedChannels',logical(OnChannels))
      
case 'setgrid',
   %---Callback from set(RespObj,'Grid',...
   if ~any(strcmp(RespObj.ResponseType,{'pzmap','nichols'}))
      switch RespObj.Grid
      case 'on'
         set(RespObj.PlotAxes(:),'Xgrid','on','Ygrid','on');
      case 'off'
         set(RespObj.PlotAxes(:),'Xgrid','off','Ygrid','off');
      end
   end
   
case 'setnicgrid',
   %---Callback from set(RespObj,'Grid' for NICPLOT objects
   NewGridState = varargin{1};
   if ~strcmpi(RespObj.Grid,NewGridState)
      RespObj.Grid = NewGridState;
      %---Change the Checked property of the Grid Context Menu
      set(RespObj.UIContextMenu.GridMenu,'Checked',NewGridState);

      if prod(size(RespObj.PlotAxes))>1
         %---MIMO case: use HG grid
         set(RespObj.PlotAxes(:),'XGrid',NewGridState,'YGrid',NewGridState);
      else
         %---SISO case: add/remove an Ngrid
         if strcmp(NewGridState,'off')
            set(RespObj.PlotAxes(:),'XGrid','off','YGrid','off');
            GridLines = get(RespObj,'GridLines');
            delete(GridLines(ishandle(GridLines)));
            set(RespObj,'GridLines',[]);
         end
         RespObj.RefreshAxisLimits = 1;  % This will result in grid rendering
      end
   end

case 'setpzgrid',
   % Callback from set(RespObj,'Grid'... for PZPLOT and RLPLOT response objects
   NewGridState = varargin{1};
   if ~strcmpi(RespObj.Grid,NewGridState),
      % Update grid state
      RespObj.Grid = NewGridState;
      %---Change the Checked property of the Grid Context Menu
      set(RespObj.UIContextMenu.GridMenu,'Checked',NewGridState)
      
      GridType = get(RespObj,'GridType');
      switch NewGridState,
      case 'on',
         % Trigger axis limit refresh (axeslims will make sure that the unit
         % circle is included for zgrids, and then draw grid lines/labels)
         RespObj.RefreshAxisLimits = 1;
      case 'off',
         switch GridType
         case 'square',
            set(RespObj.PlotAxes(:),'Xgrid','off','Ygrid','off')
         otherwise
            GridLines = get(RespObj,'GridLines');
            delete(GridLines(ishandle(GridLines)))
            % Trigger axis limit refresh (since a zgrid may have stretched
            % limits to include the unit circle, we need to call axeslims
            % after deleting grid lines to get new auto limits)
            RespObj.RefreshAxisLimits = 1;
         end 
      end
   end
   
case 'setxylims'
   %---Sets plot axis limits as computed by AXESLIMS
   %   Does not alter XlimMode and YlimMode
   PlotAxes = RespObj.PlotAxes;
   [NumRows,NumCols] = size(PlotAxes);
   Xlims = varargin{1}; 
   Ylims = varargin{2};
   
   for ctAx=1:NumCols,
      set(PlotAxes(:,ctAx),'Xlim',Xlims{ctAx})
   end
   for ctAx=1:NumRows,
      set(PlotAxes(ctAx,:),'Ylim',Ylims{ctAx})
   end % for ctax
   
   RespObj.Xlim = Xlims;
   RespObj.Ylim = Ylims;
   if ni>4,
      RespObj.ResponseHandles = varargin{3};
   end
   
   %---Disable ZoomOut menu if we are fully zoomed-out
   ZoomM = getfield(RespObj.UIContextMenu.ZoomMenu,'ZoomOut');
   if strcmpi(RespObj.XlimMode,'auto') & strcmpi(RespObj.YlimMode,'auto')
      set(ZoomM,'Enable','off');
   else
      set(ZoomM,'Enable','on');
   end

case {'showmargin','showallmargin'},
   %---Display/hide the stability margin marker
   % RE: Only available from LTI Viewer
   IndShow = [];
   if ni>2
      IndShow = varargin{1};
   end

   %---Determine which margins are to be rendered
   if strcmp(lower(action),'showmargin')
      Property = 'StabilityMargin';
      All = 0;
   else
      Property = 'AllStabilityMargin';
      All = 1;
   end

   switch pvget(RespObj,Property)
   case 'on'
      [RespObj,StatusStr] = showmargin(RespObj,IndShow,All);
      if isempty(StatusStr)
         StatusStr = 'Left click on the dot markers for details on the margin values.';
      end
	  ViewerObj = get(get(RespObj.BackgroundAxes,'Parent'),'UserData');
	  if isa(ViewerObj,'viewgui')  
		  status(ViewerObj,StatusStr,1);
	  end
	  % Trigger limit refresh to include gain/phase crossing lines
      RespObj.RefreshAxisLimits = 1;
   case 'off'
      RespObj = LocalRemovePlotOpt(RespObj,'StabilityMarginMarker',IndShow);
   end
   
case 'showpeak',
   %---Display/Hide the Peak Response Marker
   IndShow = [];
   if ni>2,
      IndShow = varargin{1};
   end
      
   switch pvget(RespObj,'PeakResponse')
   case 'on', % Plot the Peak Response markers (should never need to be calculated)
      RespObj = LocalPlotPeak(RespObj,IndShow);
   case 'off', % Remove the Peak Response markers
      RespObj = LocalRemovePlotOpt(RespObj,'PeakResponseMarker',IndShow);
   end
   
case 'showrise',
   IndShow = [];
   if ni>2,
      IndShow = varargin{1};
   end
      
   switch pvget(RespObj,'RiseTime')
   case 'on', % Plot the Rise Time markers (should never need to be calculated)
      RespObj = LocalPlotRiseTime(RespObj,IndShow);
   case 'off', % Remove the Rise Time markers
      RespObj = LocalRemovePlotOpt(RespObj,'RiseTimeMarker',IndShow);
   end
   
case 'showsettling',
   %---Display/Hide the Settling Time Marker
   IndShow = [];
   if ni>2,
      IndShow = varargin{1};
   end
      
   switch pvget(RespObj,'SettlingTime')
   case 'on', % Plot the Settling Time markers (should never need to be calculated)
      RespObj = LocalPlotSetTime(RespObj,IndShow);
   case 'off', % Remove the Settling Time markers
      RespObj = LocalRemovePlotOpt(RespObj,'SettlingTimeMarker',IndShow);
   end
   
case 'showsteady',
   %---Display/Hide the Steady State Marker
   IndShow = [];
   if ni>2,
      IndShow = varargin{1};
   end
      
   switch pvget(RespObj,'SteadyState')
   case 'on', % Plot the Steady State markers (should never need to be calculated)
      RespObj = LocalPlotSteadyState(RespObj,IndShow);
   case 'off', % Remove the Steady State markers
      RespObj = LocalRemovePlotOpt(RespObj,'SteadyStateMarker',IndShow);
   end   
     
case 'updateselector',
   %---Callback when setting SelectedChannels, if the Selector is open
   SelectorFig = get(ContextMenu.ChannelMenu,'UserData');
   CloseButton = findobj(SelectorFig,'Tag','SelectorCloseButton');
   udClose=get(CloseButton,'UserData');
   
   %---Turn on Dots
   OnChannels = logical(RespObj.SelectedChannels);
   set(udClose.AllDots,'Color',offFaceColor,'MarkerFaceColor',offFaceColor)
   set([udClose.AllText;udClose.InputText;udClose.OutputText],'Color',[0 0 0]);
   set(udClose.AllDots(OnChannels),...
      'Color',onFaceColor,'MarkerFaceColor',onFaceColor)
   
   %---See if any text should be turned on
   Usel = any(OnChannels,1);
   Ysel = any(OnChannels,2);
   if all(OnChannels(:)),
      set(udClose.AllText,'Color',[1 0 0]);
   elseif all(all(OnChannels(:,Usel))),
      set(udClose.InputText(Usel),'Color',[1 0 0]);
   elseif all(all(OnChannels(Ysel,:))),
      set(udClose.OutputText(Ysel),'Color',[1 0 0])
   end % if/else isequal...
   
case 'viewermenus',
   %---Add LTI Viewer specific menus to Response Objects
   ResponseType = RespObj.ResponseType;
   ContextMenu = RespObj.UIContextMenu;
   set(ContextMenu.PlotTypes.Main,'Visible','on')
   SubMenus = get(ContextMenu.PlotTypes.Main,'Children');
   set(SubMenus,'Callback',@localSwitchPlot,'Checked','off')
   set(SubMenus(strcmpi(get(SubMenus,'Tag'),ResponseType)),'Checked','on')
   
   %---For SISO Frequency domain responses, add a Margins menu
   if any(strcmp(ResponseType,{'bode';'nichols';'nyquist'})) & ...
           length(RespObj.InputLabel)==1 & length(RespObj.OutputLabel)==1,
       set(ContextMenu.PlotOptions.Main,'visible','on');
       ContextMenu.PlotOptions.StabilityMargin = uimenu(ContextMenu.PlotOptions.Main,...
           'label',sprintf('Stability Margins (min)'),'Callback','menufcn(''togglemargin'')');
       ContextMenu.PlotOptions.AllStabilityMargin = uimenu(ContextMenu.PlotOptions.Main,...
           'label',sprintf('Stability Margins (all)'),'Callback','menufcn(''toggleallmargin'')');
   end
   
   RespObj.UIContextMenu = ContextMenu;
   
end % switch action


%---Turn the watch back off
if ~strcmp(action,'zoom') & ishandle(WatchFigNumber)
   watchoff(WatchFigNumber);
end

catch 
   %---Turn the watch back off
   error(lasterr)
   if ~strcmp(action,'zoom') & ishandle(WatchFigNumber)
      watchoff(WatchFigNumber);
   end
end % try/catch

%---Only return RespObj if requested (prevents writing RespObj to 'base' in callbacks)
if nargout
   varargout{1} = RespObj;
end


%------------------------------Internal Functions-------------------------


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% LocalMakeSelector %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function RespObj = LocalMakeSelector(RespObj,OnFaceColor,OffFaceColor);

%---Get other relevant data from Object
OnChannels = RespObj.SelectedChannels;
ContextMenu = RespObj.UIContextMenu;
plottype = RespObj.ResponseType;
[numOutputs,numInputs]=size(RespObj.PlotAxes);
if any(strcmp(plottype,{'bode';'margin'})),
   numOutputs = numOutputs/2;
end  

%---Can not bring up for SISO systems or for PZMAP or SIGMA responses
if (numOutputs==1) & (numInputs==1),
   warndlg('I/O channel selection is not available for SISO models','I/O selection warning');
   return
else
   if any(strcmp(plottype,{'pzmap';'sigma'})),
      warndlg('I/O channel selection is not available for the current response type',...
         'I/O selection warning');
      return
   end
end

% Get common I/O names
inNames = RespObj.InputLabel;
% Remove the inNames when opening for INITIAL or LSIM
if any(strcmpi(plottype,{'initial';'lsim'})),
   inNames={''};
end
outNames = RespObj.OutputLabel; 

% Color and units
UIColor = get(0,'DefaultUIControlBackground');
PointsToPixels = 72/get(0,'ScreenPixelsPerInch');
StdUnit = 'points';

% Set font size and weight
if isunix
   FontSize = 10;
else
   FontSize = 8;
end   

FigWidth = 150+(numInputs*20);
FigHeight = 120+(numInputs*20);

ChannelFig=figure('Units',StdUnit,...
   'Position',PointsToPixels*[0 0 FigWidth FigHeight],...
   'Number','off',...
   'IntegerHandle','off',...
   'HandleVisibility','Callback',...
   'Menu','none',...
   'Name',sprintf('I/O Selector: %s',plottype),...
   'Color',UIColor,...
   'UserData',ContextMenu.Main,...
   'Visible','off',...
   'Tag','ChannelFig');

%---Position figure within bounds of parent figure
xy = centerfig(ChannelFig,RespObj.Parent);
FigPos = [xy(1) xy(2) FigWidth FigHeight];

CloseButton = uicontrol(ChannelFig,...
   'Unit',StdUnit,...
   'Background',UIColor,...
   'Position',PointsToPixels*[FigWidth-75-60 10 60 20],...
   'Unit','normalized',...
   'Style','pushbutton',...
   'String','Close',...
   'callback',['respfcn(''closeselector'',',...
      'get(get(gcbf,''UserData''),''UserData''));'],...
   'Tag','SelectorCloseButton');   
HelpButton = uicontrol(ChannelFig,...
   'Unit',StdUnit,...
   'Background',UIColor,...
   'Position',PointsToPixels*[FigWidth-70 10 60 20],...
   'Unit','normalized',...
   'Style','pushbutton',...
   'String','Help',...
   'Callback','ctrlguihelp(''response_ioselector'');',...
   'Tag','HelpButton');
ax = axes('Parent',ChannelFig,...
   'ButtonDownFcn',['respfcn(''selectrbbox'',',...
      'get(get(gcbf,''UserData''),''UserData''));'], ...
   'XColor',[0 0 0],...
   'YColor',[0 0 0],...
   'Color',UIColor,...
   'Tag','selector',...
   'Unit',StdUnit,...
   'Position',PointsToPixels*[10 40 FigPos(3)-20 FigPos(4)-50],...
   'Box','on',...
   'Ydir','reverse',...
   'Xlim',[0 numInputs+1],...
   'Ylim',[0 numOutputs+1],...
   'Xtick',[],...
   'Ytick',[]);
set(ax,'unit','norm');

dots=zeros(numOutputs,numInputs);
%---UserData is stored as [output#,input#], to be consistent with
%----indexing into LTI objects
for i=0:numInputs,
   for j=0:numOutputs,
      if (i==0) & (j==0),
         AllText=text(i+0.5,j+0.5,'[ all ]', ...
            'Parent',ax, ...
            'Interpreter','none', ...
            'ButtonDownFcn',['respfcn(''selectall'',',...
               'get(get(gcbf,''UserData''),''UserData''));'], ...
            'Tag','AllText', ...
            'Color',[0 0 0],...
            'FontSize',FontSize, ...
            'HorizontalAlignment','center', ...
            'VerticalAlignment','middle');
      elseif j==0,
         InText(i,1)=text(i+0.5,j+0.5,inNames{i}, ...
            'Parent',ax, ...
            'Interpreter','none', ...
            'ButtonDownFcn',['respfcn(''selecttext'',',...
               'get(get(gcbf,''UserData''),''UserData''));'], ...
            'UserData',[i,2], ...
            'Color',[0 0 0],...
            'FontSize',FontSize, ...
            'Tag','InText', ...
            'HorizontalAlignment','center', ...
            'VerticalAlignment','middle');
      elseif i==0,
         OutText(j,1)=text(i+0.5,j+0.5,outNames{j}, ...
            'Parent',ax, ...
            'Interpreter','none', ...
            'ButtonDownFcn',['respfcn(''selecttext'',',...
               'get(get(gcbf,''UserData''),''UserData''));'], ...
            'UserData',[j,1], ...
            'Color',[0 0 0],...
            'FontSize',FontSize, ...
            'HorizontalAlignment','center', ...
            'Tag','OutText', ...
            'VerticalAlignment','middle');
      else
         if OnChannels(j,i),
            DotColor=OnFaceColor;
         else
            DotColor=OffFaceColor;
         end
         dots(j,i)=line(i+0.5,j+0.5,'Color',DotColor, ...
            'Parent',ax, ...
            'Marker','o', ...
            'MarkerFaceColor',DotColor, ...
            'MarkerEdgeColor','k', ...
            'MarkerSize',7, ...
            'LineStyle','none', ...
            'UserData',[j,i], ...
            'ButtonDownFcn',['respfcn(''selectcircle'',',...
               'get(get(gcbf,''UserData''),''UserData''));']);
      end % if/else i/j 
   end % for j
end % for i

%---Determine text colors based on OnChannels
[indy,indu]=find(OnChannels);
OnY=unique(indy);
OnU=unique(indu);
if isequal(length(OnY),numOutputs) & isequal(length(OnU),numInputs),
   set(AllText,'Color',[1 0 0]);
elseif isequal(length(OnY),numOutputs) & isequal(length(OnU),1);
   set(InText(OnU,1),'Color',[1 0 0]);
elseif isequal(length(OnY),1) & isequal(length(OnU),numInputs);
   set(OutText(OnY,1),'Color',[1 0 0])
end % if/else isequal...

%---Store handles in the Close Button
udClose = struct('AllDots',dots,...
   'AllText',AllText,'InputText',InText,'OutputText',OutText,...
   'SelectedDot',[],'LineHandles',[],'LineStyles',[],'TempText',[]);
set(CloseButton,'UserData',udClose)

%---Store the Selector handle in the Select I/Os menu
set(ContextMenu.ChannelMenu,'Userdata',ChannelFig)

%---Show dialog
set(ChannelFig,'Visible','on');


%%%%%%%%%%%%%%%%%%%%%
%%% LocalPlotPeak %%%
%%%%%%%%%%%%%%%%%%%%%
function RespObj = LocalPlotPeak(RespObj,IndShow);

PeakRespVals = pvget(RespObj,'PeakResponseValue');
LTIdisplayAxes = RespObj.PlotAxes;
ResponseHandles = RespObj.ResponseHandles;
ResponseType = RespObj.ResponseType;
SystemVis = RespObj.SystemVisibility;
AllOnModels = RespObj.SelectedModels;
OnChannel = RespObj.SelectedChannels;

%---IndShow is a row vector of which systems need to be plotted
%     If IndShow is empty, plot all responses
if isempty(IndShow)
   IndShow = 1:1:length(ResponseHandles);
end

%---For step plots, we will also show the % overshoot
StepFlag = strcmp(ResponseType,'step');
if StepFlag
   SteadyStateVals = pvget(RespObj,'SteadyStateValue');
end

switch ResponseType
case {'step','impulse','initial','bode','bodemag','sigma'}
   % Time or frequency is on the X axis, the peak is on the Y axis
   if any(strcmp(ResponseType,{'step','impulse','initial'}))
      sidx = substruct('.','Time');
      Xstr = sprintf('At time:');
      PeakStr = sprintf('Peak amplitude:');
   else
      sidx = substruct('.','Frequency');
      Xstr = sprintf('At frequency (%s):',pvget(RespObj,'FrequencyUnits'));
      PeakStr = sprintf('Peak gain (%s):',pvget(RespObj,'MagnitudeUnits'));
   end
   BodeFlag = strcmp(ResponseType,'bode');
   if BodeFlag
      LTIdisplayAxes = LTIdisplayAxes(1:2:end,:);
   end

   for ctSys=IndShow
      Xvals = subsref(PeakRespVals(ctSys),sidx);  % time or freq
      Yvals = PeakRespVals(ctSys).Peak;           % peak amplitude/gain
      if StepFlag
         Svals = SteadyStateVals(ctSys).Amplitude; % steady state amplitude
      end
      for ctrow=1:size(LTIdisplayAxes,1)
         for ctcol=1:size(LTIdisplayAxes,2)
            if BodeFlag
               Handles = ResponseHandles{ctSys}{2*ctrow-1,ctcol};
            else
               Handles = ResponseHandles{ctSys}{ctrow,ctcol};
            end
            Xlim = get(LTIdisplayAxes(ctrow,ctcol),'Xlim');
            Ylim = get(LTIdisplayAxes(ctrow,ctcol),'Ylim');

            for ctModel = 1:prod(size(Handles))
               ResponseLine = findobj(Handles{ctModel},'Tag','LTIresponseLines');
               ModelVis = get(ResponseLine(1),'Visible');
               CC = get(ResponseLine(1),'Color');
               LineParent = get(ResponseLine(1),'Parent');
               AC = localConnectorColor(LineParent);

               Xmarker = Xvals(ctrow,ctcol,ctModel);
               Ymarker = Yvals(ctrow,ctcol,ctModel);

               % Vertical line
               T1=line([Xmarker Xmarker],[Ylim(1),Ymarker],...
                  'Parent',LineParent,'Color',AC,...
                  'Tag','PeakResponseMarker','HitTest','off',...
                  'LineStyle','-.','HandleVisibility','off','Visible',ModelVis);
               % Horizontal line
               T2=line([Xlim(1),Xmarker],[Ymarker Ymarker],...
                  'Parent',LineParent,'Color',AC,...
                  'Tag','PeakResponseMarker','HitTest','off',...
                  'LineStyle','-.','HandleVisibility','off','Visible',ModelVis);

               % System string
               IOSize = size(OnChannel);
               ArraySize = size(Handles);
               ArrayLoc = rguihelper('ind2sub',ArraySize,ctModel);
               UdStr = rguihelper('labelsystem',PeakRespVals(ctSys).System,...
                  ctcol,ctrow,ArrayLoc,IOSize,ArraySize,ResponseType);

               % Append peak data
               if StepFlag
                  Sval = Svals(ctrow,ctcol,ctModel);
                  Yval = Yvals(ctrow,ctcol,ctModel);
                  if Sval==0
                     Oval = Inf;
                  elseif abs(Sval)>abs(Yval)
                     Oval = 0;
                  else
                     Oval = 100*(Yval-Sval)/Sval;
                  end
                  UdStr = {UdStr;...
                     sprintf('%s %0.3g',PeakStr,Yval);...
                     ['Overshoot (%%): ' sprintf('%0.3g',Oval)];...         % Note that we can't do sprintf on %% here
                     sprintf('%s %0.3g',Xstr,Xvals(ctrow,ctcol,ctModel))};
               else
                  UdStr = {UdStr;...
                     sprintf('%s %0.3g',PeakStr,Yvals(ctrow,ctcol,ctModel));...
                     sprintf('%s %0.3g',Xstr,Xvals(ctrow,ctcol,ctModel))};
               end

               % Marker
               T3=line(Xmarker,Ymarker,...
                  'Parent',LineParent,...
                  'Tag','PeakResponseMarker',...
                  'Marker','o','HandleVisibility','off',...
                  'MarkerEdgeColor',CC,'MarkerFaceColor',CC,...
                  'MarkerSize',6,'HandleVisibility','off','Visible',ModelVis,...
                  'ButtonDownFcn','rguifcn(''plotoptbuttondown'',gcbf);',...
                  'UserData',UdStr);
               Handles{ctModel} = [Handles{ctModel};T1;T2;T3];
            end % for ctModel

            if BodeFlag
               ResponseHandles{ctSys}{2*ctrow-1,ctcol} = Handles;
            else
               ResponseHandles{ctSys}{ctrow,ctcol} = Handles;
            end
         end % for ctcol
      end % for ctrow
   end % for ctSys

case 'nyquist'
   % Nyquist polar plot
   mstr = pvget(RespObj,'MagnitudeUnits');
   fstr = pvget(RespObj,'FrequencyUnits');
   for ctSys=IndShow
      PeakMag = PeakRespVals(ctSys).Peak;
      PeakResp = PeakRespVals(ctSys).ResponseAtPeak;
      Freqs = PeakRespVals(ctSys).Frequency;
      for ctrow=1:size(LTIdisplayAxes,1)
         for ctcol=1:size(LTIdisplayAxes,2)
            Handles = ResponseHandles{ctSys}{ctrow,ctcol};
            for ctModel = 1:prod(size(Handles))
               ResponseLine = findobj(Handles{ctModel},'Tag','LTIresponseLines');
               ModelVis = get(ResponseLine(1),'Visible');
               CC = get(ResponseLine(1),'Color');
               LineParent = get(ResponseLine(1),'Parent');
               AC = localConnectorColor(LineParent);

               % System string
               IOSize = size(OnChannel);
               ArraySize = size(Handles);
               ArrayLoc = rguihelper('ind2sub',ArraySize,ctModel);
               UdStr = rguihelper('labelsystem',PeakRespVals(ctSys).System,...
                  ctcol,ctrow,ArrayLoc,IOSize,ArraySize,ResponseType);

               % Append peak data
               UdStr = {UdStr;...
                     sprintf('Peak gain (%s): %0.3g',...
                        mstr,PeakMag(ctrow,ctcol,ctModel));...
                     sprintf('At frequency (%s): %0.3g',...
                        fstr,Freqs(ctrow,ctcol,ctModel))};

               Xmarker = real(PeakResp(ctrow,ctcol,ctModel));
               Ymarker = imag(PeakResp(ctrow,ctcol,ctModel));

               % Line to origin
               T1=line([0 Xmarker],[0 Ymarker],...
                  'Parent',LineParent,'Color',AC,...
                  'Tag','PeakResponseMarker','HitTest','off',...
                  'LineStyle','-.','HandleVisibility','off','Visible',ModelVis);

               % Peak marker
               T2 = line(Xmarker,Ymarker,...
                  'Parent',LineParent,...
                  'Tag','PeakResponseMarker',...
                  'Marker','o','HandleVisibility','off',...
                  'MarkerEdgeColor',CC,'MarkerFaceColor',CC,...
                  'MarkerSize',6,'HandleVisibility','off','Visible',ModelVis,...
                  'ButtonDownFcn','rguifcn(''plotoptbuttondown'',gcbf);',...
                  'UserData',UdStr);
               Handles{ctModel} = [Handles{ctModel};T1;T2];
            end % for ctModel
            ResponseHandles{ctSys}{ctrow,ctcol} = Handles;
         end % for ctcol
      end % for ctrow
   end % for ctSys

case 'nichols'
   % Nichols plot
   mstr = pvget(RespObj,'MagnitudeUnits');
   fstr = pvget(RespObj,'FrequencyUnits');
   for ctSys=IndShow
      Xvals = PeakRespVals(ctSys).PhaseAtPeak;
      Yvals = PeakRespVals(ctSys).Peak;
      Freqs = PeakRespVals(ctSys).Frequency;
      for ctrow=1:size(LTIdisplayAxes,1)
         for ctcol=1:size(LTIdisplayAxes,2)
            Handles = ResponseHandles{ctSys}{ctrow,ctcol};
            for ctModel = 1:prod(size(Handles))
               ResponseLine = findobj(Handles{ctModel},'Tag','LTIresponseLines');
               ModelVis = get(ResponseLine(1),'Visible');
               CC = get(ResponseLine(1),'Color');
               LineParent = get(ResponseLine(1),'Parent');
               AC = localConnectorColor(LineParent);

               % System string
               IOSize = size(OnChannel);
               ArraySize = size(Handles);
               ArrayLoc = rguihelper('ind2sub',ArraySize,ctModel);
               UdStr = rguihelper('labelsystem',PeakRespVals(ctSys).System,...
                  ctcol,ctrow,ArrayLoc,IOSize,ArraySize,ResponseType);

               % Append peak data
               UdStr = {UdStr;...
                     sprintf('Peak gain (%s): %0.3g',...
                        mstr,Yvals(ctrow,ctcol,ctModel));...
                     sprintf('At frequency (%s): %0.3g',...
                        fstr,Freqs(ctrow,ctcol,ctModel))};

               % Peak marker
               T=line(Xvals(ctrow,ctcol,ctModel),Yvals(ctrow,ctcol,ctModel),...
                  'Parent',LineParent,...
                  'Tag','PeakResponseMarker',...
                  'Marker','o','HandleVisibility','off',...
                  'MarkerEdgeColor',CC,'MarkerFaceColor',CC,...
                  'MarkerSize',6,'HandleVisibility','off','Visible',ModelVis,...
                  'ButtonDownFcn','rguifcn(''plotoptbuttondown'',gcbf);',...
                  'UserData',UdStr);
               Handles{ctModel} = [Handles{ctModel};T];
            end % for ctModel
            ResponseHandles{ctSys}{ctrow,ctcol} = Handles;
         end % for ctcol
      end % for ctrow
   end % for ctSys

end

RespObj.ResponseHandles = ResponseHandles;

%%%%%%%%%%%%%%%%%%%%%%%%%
%%% LocalPlotRiseTime %%%
%%%%%%%%%%%%%%%%%%%%%%%%%
function RespObj = LocalPlotRiseTime(RespObj,IndShow);

RiseTimeVals = pvget(RespObj,'RiseTimeValue');
LTIdisplayAxes = RespObj.PlotAxes;
ResponseHandles = RespObj.ResponseHandles;
SystemVis = RespObj.SystemVisibility;
AllOnModels = RespObj.SelectedModels;
OnChannel = RespObj.SelectedChannels;

%---IndShow is a row vector of which systems need to be plotted
%     If IndShow is empty, plot all responses
if isempty(IndShow),
   IndShow = [1:1:length(ResponseHandles)];
end

for ctSys = IndShow,
   Yvals = RiseTimeVals(ctSys).Amplitude;
   Xvals = RiseTimeVals(ctSys).RiseTime;
   Startvals = RiseTimeVals(ctSys).StartTime;
   
   for ctrow=1:size(LTIdisplayAxes,1),
      for ctcol=1:size(LTIdisplayAxes,2),
         Handles = ResponseHandles{ctSys}{ctrow,ctcol};
         OnModels=AllOnModels{ctSys};
         for ctModel = 1:prod(size(Handles)),
            ResponseLine = findobj(Handles{ctModel},'Tag','LTIresponseLines');
            
            %---Check visibility of Model against System
            ModelVis=SystemVis{ctSys};
            if ~OnModels(ctModel) | ~OnChannel(ctrow,ctcol),
               ModelVis='off';
            end
            
            CC=get(ResponseLine,'Color');
            LineParent = get(ResponseLine,'Parent');
            AC = localConnectorColor(LineParent);
            
            % System string
            IOSize = size(OnChannel);
            ArraySize = size(Handles);
            ArrayLoc = rguihelper('ind2sub',ArraySize,ctModel);
            SysNameStr = rguihelper('labelsystem',RiseTimeVals(ctSys).System,...
               ctcol,ctrow,ArrayLoc,IOSize,ArraySize,RespObj.ResponseType);
            
            Xs = Startvals(ctrow,ctcol,ctModel);
            Tr = Xvals(ctrow,ctcol,ctModel);
            Ar = Yvals(ctrow,ctcol,ctModel);
            Xlim=get(LTIdisplayAxes(ctrow,ctcol),'Xlim');
            Ylim=get(LTIdisplayAxes(ctrow,ctcol),'Ylim');
            
            if isinf(Xs),
               % Unstable response
               RiseStr = 'Rise Time: Inf (unstable)';
               T = line(Xlim(2),Ar,'marker','o',...
                  'Tag','RiseTimeMarker',...
                  'markersize',6,'HandleVisibility','off', ...
                  'MarkerEdgeColor',CC,'MarkerFaceColor',CC, ...
                  'ButtonDownFcn','rguifcn(''plotoptbuttondown'',gcbf);',...
                  'parent',LineParent, ...
                  'UserData',{SysNameStr;RiseStr},'visible',ModelVis);	
            else
               if isnan(Xs),
                  RiseStr = 'Rise Time: N/A';
                  Xmark = Xlim(2);
               elseif isnan(Tr)
                  RiseStr = sprintf('Rise Time > %0.3g',Xlim(2)-Xs);
                  Xmark = Xlim(2);
               else
                  RiseStr = sprintf('Rise Time: %0.3g',Tr);
                  Xmark = Xs+Tr;
               end
               T = zeros(4,1);
               T(1) = line([Xlim(1);Xmark],[Ar;Ar],...
                  'parent',LineParent,'HandleVisibility','off', ...
                  'Tag','RiseTimeMarker','HitTest','off',...
                  'color',AC,'linestyle','-.','visible',ModelVis);
               T(2) = line([Xs;Xs],[Ylim(1);Ar],...
                  'Tag','RiseTimeMarker','HitTest','off',...
                  'parent',LineParent, ...
                  'HandleVisibility','off','visible',ModelVis, ...
                  'color',AC,'linestyle','-.');
               T(3) = line(Xs+[Tr;Tr],[Ylim(1);Ar],...
                  'Tag','RiseTimeMarker','HitTest','off',...
                  'parent',LineParent, ...
                  'HandleVisibility','off','visible',ModelVis, ...
                  'color',AC,'linestyle','-.');
               T(4) = line(Xmark,Ar,'marker','o',...
                  'Tag','RiseTimeMarker',...
                  'markersize',6,'HandleVisibility','off', ...
                  'MarkerEdgeColor',CC,'MarkerFaceColor',CC, ...
                  'ButtonDownFcn','rguifcn(''plotoptbuttondown'',gcbf);',...
                  'parent',LineParent, ...
                  'UserData',{SysNameStr;RiseStr},'visible',ModelVis);	
            end
            Handles{ctModel} = [Handles{ctModel};T];
         end % for ctModel   
         ResponseHandles{ctSys}{ctrow,ctcol}=Handles;   
      end % for ctcol
   end % for ctrow
end % for ctSys

RespObj.ResponseHandles = ResponseHandles;


%%%%%%%%%%%%%%%%%%%%%%%%%
%%% LocalPlotSetTime %%%
%%%%%%%%%%%%%%%%%%%%%%%%%
function RespObj = LocalPlotSetTime(RespObj,IndShow);

LTIdisplayAxes = RespObj.PlotAxes;
ResponseHandles = RespObj.ResponseHandles;
SystemVis = RespObj.SystemVisibility;
AllOnModels = RespObj.SelectedModels;
OnChannel = RespObj.SelectedChannels;

% Compute settling time 
SetTimeVals = pvget(RespObj,'SettlingTimeValue');

% Fast access to other settling time data
RespStruct = struct(RespObj);
SetLim = RespStruct.SettlingTimeThreshold;
if isa(RespObj,'stepplot'),
   SteadyStateVal = RespStruct.SteadyStateValue;
end

%---IndShow is a row vector of which systems need to be plotted
%     If IndShow is empty, plot all responses
if isempty(IndShow),
   IndShow = [1:1:length(ResponseHandles)];
end

for ctSys = IndShow,
   Yvals = SetTimeVals(ctSys).Amplitude;
   Xvals = SetTimeVals(ctSys).SettlingTime;
   if isa(RespObj,'stepplot'),
      K = SteadyStateVal(ctSys).Amplitude;
   elseif isa(RespObj,'impplot'),
      K = zeros([size(ResponseHandles{ctSys}),size(ResponseHandles{ctSys}{1})]);
   end
   
   for ctrow=1:size(LTIdisplayAxes,1),
      for ctcol=1:size(LTIdisplayAxes,2),
         Handles = ResponseHandles{ctSys}{ctrow,ctcol};
         OnModels=AllOnModels{ctSys};
         for ctModel = 1:prod(size(Handles)),
            ResponseLine = findobj(Handles{ctModel},'Tag','LTIresponseLines');
            
            %---Check visibility of Model against System
            ModelVis=SystemVis{ctSys};
            if ~OnModels(ctModel) | ~OnChannel(ctrow,ctcol),
               ModelVis='off';
            end
            CC=get(ResponseLine,'Color');
            LineParent = get(ResponseLine,'Parent');
            AC = localConnectorColor(LineParent);
            
            TargetUp = SetTimeVals(ctSys).Amplitude(ctrow,ctcol,ctModel);
            TargetDown = 2 * K(ctrow,ctcol,ctModel) - SetTimeVals(ctSys).Amplitude(ctrow,ctcol,ctModel);
            
            % System string
            IOSize = size(OnChannel);
            ArraySize = size(Handles);
            ArrayLoc = rguihelper('ind2sub',ArraySize,ctModel);
            SysNameStr = rguihelper('labelsystem',SetTimeVals(ctSys).System,...
               ctcol,ctrow,ArrayLoc,IOSize,ArraySize,RespObj.ResponseType);
                        
            Xlim = get(LTIdisplayAxes(ctrow,ctcol),'Xlim');
            Ylim = get(LTIdisplayAxes(ctrow,ctcol),'Ylim');
            Ts = Xvals(ctrow,ctcol,ctModel);  % settling time
            As = Yvals(ctrow,ctcol,ctModel);  % settling amplitude
            
            if isinf(Ts),
               % Unstable response
               SettlingStr = 'Settling Time: Inf (unstable)';
               T = line(Xlim(2),As,...
                  'marker','o','markersize',6,'HandleVisibility','off', ...
                  'MarkerEdgeColor',CC,'MarkerFaceColor',CC, ...
                  'Tag','SettlingTimeMarker',...
                  'ButtonDownFcn','rguifcn(''plotoptbuttondown'',gcbf);',...
                  'parent',LineParent, ...
                  'UserData',{SysNameStr;SettlingStr},'visible',ModelVis);
            else
               if isnan(Ts),
                  % Not settled yet
                  SettlingStr = sprintf('Settling Time > %0.3g',Xlim(2));
                  Xmark = Xlim(2);
               else
                  % Settling time is within scope
                  SettlingStr = sprintf('Settling Time: %0.3g',Ts);
                  Xmark = Ts;
               end
               T = zeros(4,1);
               T(1) = line(Xlim,[TargetUp,TargetUp],...
                  'Tag','SettlingTimeMarker','HitTest','off',...
                  'parent',LineParent,'HandleVisibility','off', ...
                  'color',AC,'linestyle','-.','visible',ModelVis);
               T(2) = line(Xlim,[TargetDown,TargetDown],...
                  'Tag','SettlingTimeMarker','HitTest','off',...
                  'parent',LineParent,'HandleVisibility','off', ...
                  'color',AC,'linestyle','-.','visible',ModelVis);
               T(3) = line([Ts,Ts],[Ylim(1),As],...
                  'Tag','SettlingTimeMarker','HitTest','off',...
                  'parent',LineParent,'HandleVisibility','off', ...
                  'color',AC,'linestyle','-.','visible',ModelVis);
               T(4) = line(Xmark,As,...
                  'marker','o','markersize',6,'HandleVisibility','off', ...
                  'MarkerEdgeColor',CC,'MarkerFaceColor',CC, ...
                  'Tag','SettlingTimeMarker',...
                  'ButtonDownFcn','rguifcn(''plotoptbuttondown'',gcbf);',...
                  'parent',LineParent, ...
                  'UserData',{SysNameStr;SettlingStr},'visible',ModelVis);	
            end
            Handles{ctModel} = [Handles{ctModel};T];
         end % for ctModel
         ResponseHandles{ctSys}{ctrow,ctcol}=Handles;   
      end % for ctcol
   end % for ctrow
end % for ctSys

RespObj.ResponseHandles = ResponseHandles;



%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% LocalPlotSteadyState %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function RespObj = LocalPlotSteadyState(RespObj,IndShow);

SteadyStateVals = pvget(RespObj,'SteadyStateValue');
LTIdisplayAxes = RespObj.PlotAxes;
ResponseHandles = RespObj.ResponseHandles;
SystemVis = RespObj.SystemVisibility;
AllOnModels = RespObj.SelectedModels;
OnChannel = RespObj.SelectedChannels;

% Get current plot horizon (in auto mode)
if strcmp(RespObj.XlimMode,'auto')
   tmax = RespObj.Xlim{1}(2);
else
   tmax = Inf;
end

%---IndShow is a row vector of which systems need to be plotted
%     If IndShow is empty, plot all responses
if isempty(IndShow),
   IndShow = [1:1:length(ResponseHandles)];
end

for ctSys = IndShow,
   K=SteadyStateVals(ctSys).Amplitude;
   for ctrow=1:size(LTIdisplayAxes,1),
      for ctcol=1:size(LTIdisplayAxes,2),
         Handles = ResponseHandles{ctSys}{ctrow,ctcol};
         OnModels = AllOnModels{ctSys};
         for ctModel = 1:prod(size(Handles)),
            ResponseLine = findobj(Handles{ctModel},'Tag','LTIresponseLines');
            
            %---Check visibility of Model against System
            ModelVis=SystemVis{ctSys};
            if ~OnModels(ctModel) | ~OnChannel(ctrow,ctcol),
               ModelVis='off';
            end
            LineParent = get(ResponseLine,'Parent');
   
            CC=get(ResponseLine,'Color');
            t = get(ResponseLine,'Xdata');
            R = get(ResponseLine,'Ydata');
            
            % System string
            IOSize = size(OnChannel);
            ArraySize = size(Handles);
            ArrayLoc = rguihelper('ind2sub',ArraySize,ctModel);
            SysNameStr = rguihelper('labelsystem',SteadyStateVals(ctSys).System,...
               ctcol,ctrow,ArrayLoc,IOSize,ArraySize,RespObj.ResponseType);
                        
            if isinf(K(ctrow,ctcol,ctModel))
               DCStr = 'DC gain: Inf (unstable)';
               Ypos = R(end);
            else
               DCStr = sprintf('DC gain: %0.3g',K(ctrow,ctcol,ctModel));
               Ypos = K(ctrow,ctcol,ctModel);
            end
            T = line(min([t(end),tmax]),Ypos,'HandleVisibility','off', ...
                  'MarkerEdgeColor',CC,'MarkerFaceColor',CC, ...
                  'parent',LineParent,'marker','o','markersize',6, ...
                  'ButtonDownFcn','rguifcn(''plotoptbuttondown'',gcbf);',...
                  'visible',ModelVis, ...
                  'Tag','SteadyStateMarker',...
                  'UserData',{SysNameStr;DCStr});
            Handles{ctModel} = [Handles{ctModel};T];
         end % for ctModel
         ResponseHandles{ctSys}{ctrow,ctcol}=Handles;   
      end % for ctcol
   end % for ctrow
end % for ctSys

RespObj.ResponseHandles = ResponseHandles;


%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% LocalRemovePlotOpt %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%
function RespObj = LocalRemovePlotOpt(RespObj,Tag,IndRemove);

ResponseHandles = RespObj.ResponseHandles;

%---IndShow is a row vector of which systems need to be plotted
%     If IndShow is empty, plot all responses
if isempty(IndRemove),
   IndRemove = [1:1:length(ResponseHandles)];
end

for ct = IndRemove,
   AllModelLines = ResponseHandles{ct};
   AllLines = cat(2,AllModelLines{:});
   RemoveLines=findobj(cat(1,AllLines{:}),'Tag',Tag);
   delete(RemoveLines);
   for ctrow=1:size(AllModelLines,1),
      for ctcol=1:size(AllModelLines,2),
         ModelLines = AllModelLines{ctrow,ctcol};
         for ctModel=1:prod(size(ModelLines)),
            ModelLines{ctModel}=ModelLines{ctModel}(ishandle(ModelLines{ctModel}));
         end % for ctModel
         AllModelLines{ctrow,ctcol}=ModelLines;
      end % for ctcol
   end % for ctrow
   ResponseHandles{ct}=AllModelLines;
end % for ct

RespObj.ResponseHandles = ResponseHandles;


%%%%%%%%%%%%%%%%%%%%%%%
%%% localSwitchPlot %%%
%%%%%%%%%%%%%%%%%%%%%%%
function localSwitchPlot(eventSrc,eventData)
% Callback for the Plot Type menu
 PlotTypeMenu = eventSrc;
 NewPlotType  = get(PlotTypeMenu,'Tag');
 LTIviewerFig = gcbf;
 ViewerObj    = get(LTIviewerFig,'UserData');
 NewPlotString = deblank(get(PlotTypeMenu,'Label'));
 if strcmp(NewPlotString(end),'.')
    NewPlotString = NewPlotString(1:end-1);
 end
 ViewerObj = plotswitch(ViewerObj,PlotTypeMenu);
 status(ViewerObj,sprintf('Plot type changed to %s.',NewPlotString),1);
 builtin('set',LTIviewerFig,'UserData',ViewerObj)


%%%%%%%%%%%%%%%%%%%%%%%
% localConnectorColor %
%%%%%%%%%%%%%%%%%%%%%%%
function C = localConnectorColor(Ax)
%---Determine good color for connector lines in axes Ax
 AC = get(Ax,'Color');
 if isstr(AC), AC = get(get(Ax,'Parent'),'Color'); end
 if sum(AC)>1.5
    C = [0 0 0];
 else
    C = [1 1 1];
 end
