%% Design Human-Machine Interface Logic by Using Stateflow Charts
% This example shows how to model the logic of a graphical user interface
% in a standalone Stateflow(R) chart. Standalone charts implement classic
% chart semantics with MATLAB(R) as the action language. You can program
% the chart by using the full functionality of MATLAB, including those
% functions that are restricted for code generation in Simulink(R). For
% more information, see
% <docid:stateflow_ug#mw_d580cbaa-5437-4e23-a9b5-d7fd4fc42ff7>.
%
% You can execute a standalone Stateflow chart by invoking its input events
% and using temporal operators. The event- and timer-driven execution
% workflow is suitable for designing the logic underlying human-machine
% interfaces (HMIs) and graphical user interfaces (UIs).
%
% * When you use the MATLAB App Designer, callback functions from the
% interface widgets invoke events in the chart.
% * In the Stateflow chart, temporal operators and local data control the
% properties of the user interface.
% 
% For more information on how to use MATLAB to create graphical user
% interfaces, see <docid:matlab_doccenter#bu6q9n8>.

% Copyright 2018-2020 The MathWorks, Inc.

%% Control an App Designer User Interface
% This user interface contains an On-Off switch that controls a lamp. When
% the switch is in the On position, the lamp lights up in one of two
% modes, solid or blinking, depending on the position of the Mode option
% button. You control the rate of blinking by moving the Blink Rate slider.
%
% <<../sf_lamp_ui.png>>

%%
% The file |sf_lamp_logic.sfx| defines a standalone Stateflow chart that
% implements the logic for the user interface. The chart has input events
% (|ON|, |OFF|, |BLINKING|, and |SOLID|) and local data (|delay| and
% |app|). The actions in the chart control which widgets are accessible
% from each state. For instance, the actions in the |Off| state cause the
% Lamp widget, the Mode option buttons, and the Blink Rate slider in the
% user interface to appear dimmed.

set_param(0,'ExportBackgroundColorMode','white');
edit sf_lamp_logic.sfx

%% 
% In the |On| state, the substates |Solid| and |Blinking| denote the two
% modes of operation. To implement a blinking lamp, the chart relies on the
% temporal logic operator |<docid:stateflow_ref#after after>|. When the
% chart enters the state |Blinking.Off|, the expression |after(delay,sec)|
% on the outgoing transition creates a MATLAB timer object that executes
% the chart after a number of seconds. The chart then transitions to the
% state |Blinking.On| and creates another timer object to trigger the
% transition back to |Blinking.Off|. While the chart continually
% transitions between the two states, you can adjust the rate of blinking
% by changing the value of the local data delay or transition out of
% blinking mode by invoking the input events |SOLID| or |OFF|.
%
% The history junction in the |On| state preserves information on the most
% recently active substate so that the user interface returns to the
% previous mode of operation when you turn on the lamp.

%% Execute Standalone Chart by Using Events
% You can execute the standalone chart by calling its input event functions
% in the MATLAB Command Window. The Stateflow Editor shows the effects of
% each of these commands by highlighting active states and transitions
% through chart animation.
% 
% 1. Open the standalone chart in the Stateflow Editor.
% 
%   edit sf_lamp_logic.sfx
%
% 2. Create the chart object |L| and initialize the value of |delay| to
% 0.5. This value corresponds to a blinking rate of one flash per second.
% 
%   L = sf_lamp_logic('delay',0.5);
%
% 3. Turn on the lamp.
% 
%   ON(L)
%
% 4. Switch to blinking mode.
% 
%   BLINKING(L)
%
% 5. Set the value of |delay| to 0.25. This value corresponds to a blinking
% rate of two flashes per second.
% 
%   L.delay = 0.25;
%
% 6. Switch to solid mode.
% 
%   SOLID(L)
%
% 7. Turn off the lamp.
% 
%   OFF(L)
% 
% 8. Delete the chart object |L| from the MATLAB workspace.
% 
%   delete(L)
% 

%% Connect Standalone Chart to User Interface
% To establish a bidirectional connection between the user interface and
% the standalone Stateflow chart, open the App Designer window and select
% *Code View*.
%
% 1. In the App Designer window, create a private property |lampLogic| to
% store the handle to the Stateflow chart object.
% 
%   properties (Access = private)
%       lampLogic
%   end
%
% 2. Create a |StartupFcn| callback function that creates the chart object
% and sets its local data |app| to the user interface handle. Assign the
% chart object handle to the |lampLogic| private property.
%
%   % Code that executes after component creation
%   function StartupFcn(app)
%       app.lampLogic = sf_lamp_logic('delay',0.5,'app',app);
%   end
%
% 3. Create a |CloseRequestFcn| callback function that deletes the chart
% object when you close the user interface.
% 
%   % Close request function: UIFigure
%   function UIFigureCloseRequest(app, event)
%       delete(app.lampLogic);
%       delete(app);
%   end
%
% 4. For each one of the user interface widgets, add a callback function
% that invokes the appropriate event on the standalone chart.
% 
% * |ValueChangedFcn| callback function for Switch widget:
%
%   function SwitchValueChanged(app,event)
%       value = app.Switch.Value;
%       switch lower(value)
%           case 'off'    
%               OFF(app.lampLogic);
%           case 'on'
%               ON(app.lampLogic);    
%       end
%   end
%
% * |SelectionChangedFcn| callback function for Mode Button widget:
%
%   function ModeButtonGroupSelectionChanged(app,event)
%       selectedButton = app.ModeButtonGroup.SelectedObject;
%       if app.SolidButton == selectedButton
%           SOLID(app.lampLogic);
%       else
%           BLINKING(app.lampLogic);
%       end
%   end
%
% * |ValueChangedFcn| callback function for Blink Rate Slider widget:
%
%   function BlinkRateSliderValueChanged(app,event)
%       app.lampLogic.delay = round(0.5/app.BlinkRateSlider.Value,2);
%   end
%
% When you run the user interface, you can observe the effects of adjusting
% the control widgets on the chart canvas and on the lamp widget.