function GUOdemo(Action);

persistent GUOdemoFig1 GUOdemoFig2 GUO1 GUO2 GUO1TextPos GUO2SmallPos GUO1Ready;

% function GUOdemo(Action);
% 
% Demonstrates the graphicuserobject class.
% The Action argument selects the button callback code
% and should not be supplied from the command line.
%
% Copyright (c) SINUS Messtechnik GmbH 2002
% www.sinusmess.de - Sound & Vibration Instrumentation
%                  - PCB Services
%                  - Electronic Design & Production

if nargin == 0
   % No Action parameter supplied:  create figures, GUOs and other controls
   
   % Create figures
   GUO1Ready = 0;
   GUOdemoFig1 = figure('Position', [50 300 600 400], ...
                        'ResizeFcn', 'GUOdemo(''ResizeFig1'')');
   GUOdemoFig2 = figure('Position', [350 50 600 400]);
   
   % Create GUO1:  graphicuserobject with visible frame (default units=normalized)
   GUO1 = graphicuserobject(GUOdemoFig1, 'Position', [1/12 0.7 7/12 0.2], ...
                                         'Visible', 'on');
   GUO1 = uicontrol(GUO1, 'Tag', 'GUO1TextNormalized', ...
                          'Style', 'text', ...
                          'Position', [0.1 0.6 0.8 0.3], ...
                          'String', 'This text and this GUO have units=normalized');
   GUO1TextPos = [10 10 250 20];
   GUO1 = uicontrol(GUO1, 'Tag', 'GUO1TextPixels', ...
                          'Style', 'text', ...
                          'Units', 'pixels', ...
                          'Position', GUO1TextPos, ...
                          'String', 'This text and the other GUO have units=pixels');
   
   % Create child GUOs within GUO1
   GUOPB1N = PlaybackButtons('Tag', 'PBBinGUO1N', ...
                             'Position', [0.45 0.35 0.25 0.3], ...
                             'Visible', 'on');
   GUOPB1N = SetPBBCallbacks(GUOPB1N);  % SetPBBCallbacks is a subfunction of GUOdemo
   GUO1 = addchildguo(GUO1, GUOPB1N);   % Add GUOPB1N within GUO1
   GUOPB1P = PlaybackButtons('Tag', 'PBBinGUO1P', ...
                             'Units', 'pixels', ...
                             'Position', [260 10 80 20], ...
                             'Visible', 'on');
   GUOPB1P = SetPBBCallbacks(GUOPB1P);  % SetPBBCallbacks is a subfunction of GUOdemo
   GUO1 = addchildguo(GUO1, GUOPB1P);   % Add GUOPB1P within GUO1
   GUO1Ready = 1;  % Avoid "Child not found" error from initial resize (see below)
   
   % Create GUO2:  graphicuserobject with visible frame (units=pixels)
   GUO2SmallPos = [100 60 350 200];
   GUO2 = graphicuserobject(GUOdemoFig1, 'Units', 'Pixels', ...
                                         'Position', GUO2SmallPos, ...
                                         'Visible', 'on');
   % Pushbuttons are normalized relative to graphicuserobject (default units=normalized)
   GUO2 = uicontrol(GUO2, 'Style', 'pushbutton', ...
                          'Position', [0.1 0.8 0.15 0.1], ...
                          'String', 'Big', ...
                          'Callback', 'GUOdemo(''Big'')');
   GUO2 = uicontrol(GUO2, 'Style', 'pushbutton', ...
                          'Position', [0.1 0.7 0.15 0.1], ...
                          'String', 'Small', ...
                          'Callback', 'GUOdemo(''Small'')');
   GUO2 = uicontrol(GUO2, 'Style', 'pushbutton', ...
                          'Position', [0.1 0.6 0.15 0.1], ...
                          'String', 'Edit', ...
                          'Callback', 'GUOdemo(''Edit'')');
   GUO2 = uicontrol(GUO2, 'Style', 'pushbutton', ...
                          'Position', [0.1 0.5 0.15 0.1], ...
                          'String', 'Plot', ...
                          'Callback', 'GUOdemo(''Plot'')');
   GUO2 = uicontrol(GUO2, 'Style', 'pushbutton', ...
                          'Position', [0.1 0.4 0.15 0.1], ...
                          'String', 'Figure 1', ...
                          'Callback', 'GUOdemo(''Fig1'')');
   GUO2 = uicontrol(GUO2, 'Style', 'pushbutton', ...
                          'Position', [0.1 0.3 0.15 0.1], ...
                          'String', 'Figure 2', ...
                          'Callback', 'GUOdemo(''Fig2'')');
   GUO2 = uicontrol(GUO2, 'Style', 'pushbutton', ...
                          'Position', [0.1 0.2 0.15 0.1], ...
                          'String', 'Close', ...
                          'Callback', 'GUOdemo(''Close'')');
   % Axes are normalized relative to graphicuserobject (default units=normalized)
   GUO2 = axes(GUO2, 'Tag', 'PlotAxes', ...
                     'Position', [0.45 0.5 0.25 0.4], ...
                     'XLim', [0 100], ...
                     'YLim', [0 100]);
   axes(GUO2, '');  % Make GUO2 frame the current axes for rectangle
   rectangle('Position', [0.075 0.175 0.2 0.75], ...
             'Curvature', [0.1]);
   
   % Create child GUOs within GUO2
   GUOPB2N = PlaybackButtons('Tag', 'PBBinGUO2N', ...
                             'Position', [0.45 0.2 0.25 0.14], ...
                             'Visible', 'on');
   GUOPB2N = SetPBBCallbacks(GUOPB2N);  % SetPBBCallbacks is a subfunction of GUOdemo
   GUO2 = addchildguo(GUO2, GUOPB2N);   % Add GUOPB2N within GUO2
   GUOPB2P = PlaybackButtons('Tag', 'PBBinGUO2P', ...
                             'Units', 'pixels', ...
                             'Position', [260 10 80 20], ...
                             'Visible', 'on');
   GUOPB2P = SetPBBCallbacks(GUOPB2P);  % SetPBBCallbacks is a subfunction of GUOdemo
   GUO2 = addchildguo(GUO2, GUOPB2P);   % Add GUOPB2P within GUO2
   
   % Create and initialise text at fixed position relative to GUO2
   GUO2 = uicontrol(GUO2, 'Tag', 'FixedText', ...
                          'Style', 'text', ...
                          'Units', 'pixels', ...
                          'Position', [10 10 130 20]);
   GUOdemo('SetText');  % Update displayed position of GUO2 (pixels)
   
   % Demonstrate Display function
   GUO1
   GUO2
   
   % Create pushbuttons on figure GUOdemoFig1 (not in GUO)
   figure(GUOdemoFig1);
   uicontrol('Style', 'pushbutton', ...
             'Position', [100 25 100 20], ...
             'String', 'Hide GUO1', ...
             'Callback', 'GUOdemo(''HideGUO1'')');
   uicontrol('Style', 'pushbutton', ...
             'Position', [200 25 100 20], ...
             'String', 'Show GUO1', ...
             'Callback', 'GUOdemo(''ShowGUO1'')');
   uicontrol('Style', 'pushbutton', ...
             'Position', [300 25 100 20], ...
             'String', 'Hide Controls 1', ...
             'Callback', 'GUOdemo(''HideControls1'')');
   uicontrol('Style', 'pushbutton', ...
             'Position', [400 25 100 20], ...
             'String', 'Show Controls 1', ...
             'Callback', 'GUOdemo(''ShowControls1'')');
   uicontrol('Style', 'pushbutton', ...
             'Position', [100  5 100 20], ...
             'String', 'Hide GUO2', ...
             'Callback', 'GUOdemo(''HideGUO2'')');
   uicontrol('Style', 'pushbutton', ...
             'Position', [200  5 100 20], ...
             'String', 'Show GUO2', ...
             'Callback', 'GUOdemo(''ShowGUO2'')');
   uicontrol('Style', 'pushbutton', ...
             'Position', [300  5 100 20], ...
             'String', 'Hide Controls 2', ...
             'Callback', 'GUOdemo(''HideControls2'')');
   uicontrol('Style', 'pushbutton', ...
             'Position', [400  5 100 20], ...
             'String', 'Show Controls 2', ...
             'Callback', 'GUOdemo(''ShowControls2'')');

else
   % Action argument supplied (selects callback function)
   
   switch Action
   case 'ResizeFig1'  % ResizeFcn for GUOdemoFig1
      if GUO1Ready    % GUO1Ready avoids "Child not found" error from initial resize.
         GUO1 = resizefcn(GUO1);  % resizefcn necessary because GUO1 is normalized
      end                         % but has children with Units=pixels
   case 'Big'         % "Big" pushbutton in GUO2 resizes GUO2 and normalized children
      GUO2 = set(GUO2, 'Position', [50 60 500 300]);
      GUOdemo('SetText');  % Update displayed position of GUO2 (pixels)
   case 'Small'       % "Small" pushbutton in GUO2 resizes GUO2 and normalized children
      GUO2 = set(GUO2, 'Position', GUO2SmallPos);
      GUOdemo('SetText');  % Update displayed position of GUO2 (pixels)
   case 'Edit'        % "Edit" pushbutton in GUO2 demonstrates access to child uicontrol
      try             % "EditText":  creation, getting child properties and deletion
         MsgText = getchild(GUO2, 'EditText', 'String');
      catch
         MsgText = [];
         GUO2 = uicontrol(GUO2, 'Tag', 'EditText', ...
                                'Style', 'edit', ...
                                'Position', [0.2 0.85 0.6 0.1], ...
                                'HorizontalAlignment', 'left');
      end
      if length(MsgText) > 0
         GUO2 = deletechild(GUO2, 'EditText');
         msgbox(['EditText contained: ' MsgText], 'GUOdemo');
      end
   case 'Plot'        % "Plot" pushbutton in GUO2 demonstrates access to child axes
      % Demonstrate indexing by number instead of Tag...
      axes(GUO2, 8);  % ... but "axes(GUO2, 'PlotAxes')" would normally be better
      plot([0:100], [0:100], 'r');
      text(50, 50, 'XYZ');  % Create text relative to PlotAxes
   case 'Fig1'        % "Fig1" pushbutton in GUO2 moves GUO2 to GUOdemoFig1
      GUO2 = set(GUO2, 'Parent', GUOdemoFig1);
   case 'Fig2'        % "Fig2" pushbutton in GUO2 moves GUO2 to GUOdemoFig2
      GUO2 = set(GUO2, 'Parent', GUOdemoFig2);
   case 'Close'       % "Close" pushbutton in GUO2 ends demonstration
      GUO2 = delete(GUO2);  % Demonstrate GUO deletion
      close(GUOdemoFig1);
      close(GUOdemoFig2);
   case 'SetText'     % Update displayed position of GUO2 (pixels)
      PosText = ['Pos:  ' num2str(get(GUO2, 'Position'))];
      GUO2 = setchild(GUO2, 'FixedText', 'String', PosText);
   case {'PBBnormalized', 'PBBpixels'}  % Callback for all pushbuttons in
      Tag = get(gcbo, 'Tag');           % PlaybackButttons GUOs - see SetPBBCallbacks
      msgbox(['"' Tag '" button in child GUO with units = ' Action(4:end)], 'GUOdemo');
      
   % The remaining Actions are for the pushbuttons on figure GUOdemoFig1,
   % which demonstrate the hiding and showing of GUOs and their children.
   case 'HideGUO1'       % Hide GUO1
      GUO1 = hide(GUO1);
   case 'ShowGUO1'       % Show GUO1
      GUO1 = show(GUO1);
   case 'HideControls1'  % Hide normalized child GUO & control in GUO1
      GUO1 = guoeval(GUO1, 'PBBinGUO1N', 'hide');
      GUO1 = setchild(GUO1, 'GUO1TextNormalized', 'Visible', 'off');
   case 'ShowControls1'  % Show normalized child GUO & control in GUO1
      GUO1 = guoeval(GUO1, 'PBBinGUO1N', 'show');
      GUO1 = setchild(GUO1, 'GUO1TextNormalized', 'Visible', 'on');
   case 'HideGUO2'       % Hide GUO2
      GUO2 = hide(GUO2);
   case 'ShowGUO2'       % Show GUO2
      GUO2 = show(GUO2);
   case 'HideControls2'  % Hide normalized child GUO & control in GUO2
      GUO2 = guoeval(GUO2, 'PBBinGUO2N', 'hide');
      GUO2 = setchild(GUO2, 'PlotAxes', 'Visible', 'off');
      % Line and text are children of PlotAxes
      set(getchild(GUO2, 'PlotAxes', 'Children'), 'Visible', 'off');
   case 'ShowControls2'  % Show normalized child GUO & control in GUO2
      GUO2 = guoeval(GUO2, 'PBBinGUO2N', 'show');
      GUO2 = setchild(GUO2, 'PlotAxes', 'Visible', 'on');
      % Line and text are children of PlotAxes
      set(getchild(GUO2, 'PlotAxes', 'Children'), 'Visible', 'on');
      
   otherwise  % This should never happen...
      msgbox(['Unknown Action: ' Action], 'GUOdemo', 'error');
   end
end


function  GUOPBB = SetPBBCallbacks(GUOPBB);

% Subfunction of GUOdemo:  sets the same callback function for each of 
% the four pushbuttons within GUOPBB (which is a PlaybackButtons GUO).

PBBunits = get(GUOPBB, 'Units');
for Tag = {'First', 'Previous', 'Next', 'Last'}
   GUOPBB = setchild(GUOPBB, Tag{:}, 'Callback', ['GUOdemo(''PBB' PBBunits ''')']);
end
