www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/xregwizard.m

    function [OK, outputUD] = xregwizard(hParent, wizardName, firstCardFcn, varargin)
%XREGWIZARD Wizard creation tool
%
%  [OK, outputUD] = XREGWIZARD(hParent, wizardName, firstCardFcn, varargin)

%  Copyright 2000-2014 The MathWorks, Inc. and Ford Global Technologies, Inc.


f = xregdialog('visible','off',...
    'units','pixels',...
    'Name', wizardName,...
    'color',get(0,'DefaultUicontrolBackgroundColor'));

% Get callbacks and interface function handles
[Callbacks, iFace] = NestedCallbacks(f);

% Add a property to define the close action
mbcgui.hgclassesutil.addprop(f, 'closeAction');
f.closeAction = 'cancel';

% Center the figure on the parent figure
xregcenterfigure(f, [600 250], hParent);

% Create the wizard control buttons
btCancel = uicontrol('Parent', f,...
    'Style', 'pushbutton', ...
    'String', 'Cancel',...
    'Callback', @(s,e) set(f, 'Visible', 'off'));

btPrev = uicontrol('Parent', f,...
    'Style', 'pushbutton', ...
    'String', '< Back',...
    'Enable', 'off',...
    'Callback', Callbacks.Back);

btNext = uicontrol('Parent', f,...
    'Style', 'pushbutton', ...
    'String', 'Next >',...
    'Enable', 'off',...
    'Callback', Callbacks.Next);

btFinish = uicontrol('Parent', f,...
    'Style', 'pushbutton', ...
    'String', 'Finish',...
    'Enable', 'off',...
    'Callback', Callbacks.Finish);

buttonLayout = xreggridbaglayout(f, ...
    'packstatus', 'off', ...
    'dimension', [1 5],...
    'elements', {[] btCancel btPrev btNext btFinish},...
    'gapx', 7,...
    'border', [0 0 7 0],...
    'colsizes', [-1 65 65 65 65],...
    'rowsizes', 25);

ud.cardLayout = xregcardlayout(f, 'numcards', 1);

% For wizard use only
ud.navButton.next   = btNext;
ud.navButton.prev   = btPrev;
ud.navButton.cancel = btCancel;
ud.navButton.finish = btFinish;
ud.cardIDs          = {};
ud.prevIDs          = [];
ud.Parent           = hParent;
ud.UserData         = [];

% Attach interface to userdata
ud.iFace = iFace;

% Final output arguments
ud.outputUD           = [];

layout = xreggridbaglayout(f,...
    'dimension', [2 1],...
    'elements', {ud.cardLayout buttonLayout},...
    'gapy', 7,...
    'border', [0 7 0 0], ...
    'rowsizes', [-1 25]);

f.UserData = ud;

% Create the first card in the wizard
Callbacks.Init(firstCardFcn, varargin{:});

f.LayoutManager = layout;
set(layout, 'packstatus', 'on');



% Set the window modal waiting for the visibility to change
f.showDialog();

switch f.closeAction
    case 'ok'
        ud = f.UserData;
        outputUD = ud.outputUD;
        OK = 1;
    otherwise
        % Execute cancel 
        Callbacks.Cancel(btCancel, []);
        outputUD = [];
        OK = 0;
end
delete(f);
end


%------------------------------------------------------------------------
% WIZARD API FUNCTIONS BELOW
%------------------------------------------------------------------------

function [Callbacks, iFace] = NestedCallbacks(fig)

% Internal callbacks
Callbacks = struct( ...
    'Cancel', @n_cancel, ...
    'Back', @n_prev, ...
    'Next', @n_next, ...
    'Finish', @n_finish, ...
    'Init', @n_openCard);

% Define the wizard API interface
iFace = struct( ...
    'getCardUserdata', @n_getCurrentCardUserdata, ...
    'setCardUserdata', @n_setCurrentCardUserdata, ...
    'setNextButton', @n_setNextButton, ...
    'setPrevButton', @n_setPrevButton, ...
    'setFinishButton', @n_setFinishButton, ...
    'setOutputData', @n_setOutputData, ...
    'setWizardSize', @n_setWizardSize, ...
    'setUserData', @n_setUserData, ...
    'getUserData', @n_getUserData);


    function n_cancel(~, ~)
        [ud, f] = n_getThisHandle;
                  
        % Check that next button is actually currently enabled.  Callbacks
        % may happen when disabled if the user queues many button clicks and
        % an earlier callback has disabled the button.
        if strcmp(get(ud.navButton.cancel, 'Enable'), 'on')

            % Give the card a chance to respond to the cancel button
            layoutUD = n_getCurrentCardUserdata;
            if isfield(layoutUD,'cancelFcn')
                % the cancel function is an optional interface
                feval(layoutUD.cancelFcn, layoutUD, ud.iFace);
            end

            f.closeAction = 'cancel';
            f.Visible = 'off';
        end
    end

%------------------------------------------------------------------------
    function n_finish(~, ~)
        [ud, f] = n_getThisHandle;
        
        % Check that next button is actually currently enabled.  Callbacks
        % may happen when disabled if the user queues many button clicks and
        % an earlier callback has disabled the button.
        if strcmp(get(ud.navButton.finish, 'Enable'), 'on')
            % Give the card a chance to respond to the finish button
            layoutUD = n_getCurrentCardUserdata;
            feval(layoutUD.finishFcn, layoutUD, ud.iFace);

            f.closeAction = 'ok';
            f.Visible = 'off';
        end
    end

%------------------------------------------------------------------------
    function n_prev(~, ~)
        ud = n_getThisHandle;
        
        % Check that next button is actually currently enabled.  Callbacks
        % may happen when disabled if the user queues many button clicks and
        % an earlier callback has disabled the button.
        if strcmp(get(ud.navButton.prev, 'Enable'), 'on')

            layoutUD = n_getCurrentCardUserdata;
            if (isfield(layoutUD,'prevFcn') || ~isstruct(layoutUD) && ~isempty(findprop(layoutUD,'prevFcn'))) && ~isempty(layoutUD.prevFcn)
                feval(layoutUD.prevFcn, layoutUD, ud.iFace);
            end

            % Get the previous card ID
            currID = get(ud.cardLayout, 'current');
            cardID = ud.cardIDs{ud.prevIDs(currID)};
            n_openCard(cardID);
            if ud.prevIDs(currID) == 1
                n_setPrevButton('off');
            end
        end
    end

%------------------------------------------------------------------------
    function n_next(~, ~)
        [ud, f] = n_getThisHandle;
        
        % Check that next button is actually currently enabled.  Callbacks
        % may happen when disabled if the user queues many button clicks and
        % an earlier callback has disabled the button.
        if strcmp(get(ud.navButton.next, 'Enable'), 'on')
            layoutUD = n_getCurrentCardUserdata;
            [nextCardID, localData] = feval(layoutUD.nextFcn, layoutUD, ud.iFace);
            if ~isempty(nextCardID)
                currID = get(ud.cardLayout, 'current');
                [ID, ud] = n_openCard(nextCardID, localData);
                ud.prevIDs(ID) = currID;
                n_setPrevButton('on');
                f.UserData = ud;
            end
        end
    end

%------------------------------------------------------------------------
    function [ID, ud] = n_openCard(cardID, varargin)
        [ud, f] = n_getThisHandle;
        % Ensure cardID is a cell array for feval purpose
        if ~iscell(cardID)
            cardID = {cardID};
        end

        % Does cardID exist already?
        FOUND = 0;
        for i = 1:length(ud.cardIDs)
            if isequal(cardID, ud.cardIDs{i})
                FOUND = 1;
                break;
            end
        end

        if FOUND
            % Reuse the existing layout
            ID = i;
            layout = getcard(ud.cardLayout, ID);
            f = layout{1};
        else
            % Turn packstatus off in figure before new card is created
            setBoolPackstatus(ud.cardLayout, false);
        end

        % Create or open the card
        layout = feval(cardID{:}, f, ud.iFace, varargin{:});

        % If this is create we need to add this to the cardLayout
        if ~FOUND
            % Make sure packstatus is turned on
            if isa(layout, 'xregcontainer')
                setBoolPackstatus(layout, true);
            end

            nextID = length(ud.cardIDs) + 1;

            % Does the cardLayout have enough cards?
            if get(ud.cardLayout, 'numcards') < nextID
                set(ud.cardLayout, 'numcards', nextID);
            end
            ID = attach(ud.cardLayout, layout, nextID);

            % Add this cardID on to the end of the list
            [ud, f] = n_getThisHandle;
            ud.cardIDs{ID} = cardID;
            f.UserData = ud;
        end

        % Set the currentcard
        set(ud.cardLayout, 'currentCard', ID);
    end

%------------------------------------------------------------------------
    function n_setNextButton(enable)
        ud = n_getThisHandle;
        if isnumeric(enable) || islogical(enable)
            states = {'off' 'on'};
            enable = states{sign(abs(enable))+1};
        end
        set(ud.navButton.next, 'Enable', enable);
    end

%------------------------------------------------------------------------
    function n_setPrevButton(enable)
        ud = n_getThisHandle;
        if get(ud.cardLayout, 'current') == 1
            enable = 'off';
        end
        if isnumeric(enable) || islogical(enable)
            states = {'off' 'on'};
            enable = states{sign(abs(enable))+1};
        end
        set(ud.navButton.prev, 'Enable', enable);
    end

%------------------------------------------------------------------------
    function n_setFinishButton(enable)
        ud = n_getThisHandle;
        if isnumeric(enable) || islogical(enable)
            states = {'off' 'on'};
            enable = states{sign(abs(enable))+1};
        end
        set(ud.navButton.finish, 'Enable', enable);
    end

%------------------------------------------------------------------------
    function n_setOutputData(outputUD)
        [ud, f] = n_getThisHandle;
        ud.outputUD = outputUD;
        f.UserData = ud;
    end

%------------------------------------------------------------------------
    function layoutUD = n_getCurrentCardUserdata
        ud = n_getThisHandle;
        layout = getcard(ud.cardLayout);
        layoutUD = get(layout{1}, 'UserData');
    end

%------------------------------------------------------------------------
%
%------------------------------------------------------------------------
    function n_setCurrentCardUserdata(layoutUD)
        ud = n_getThisHandle;
        layout = getcard(ud.cardLayout);
        set(layout{1}, 'UserData', layoutUD);
    end

%------------------------------------------------------------------------
    function n_setWizardSize(Size)
        [ud, f] = n_getThisHandle;
        if isempty(ud.cardIDs)
            % Only set size if card one is creating
            xregcenterfigure(f, Size, ud.Parent);
        end
    end

%------------------------------------------------------------------------
    function n_setUserData(UD)
        [ud, f] = n_getThisHandle;
        ud.UserData = UD;
        f.UserData = ud;
    end

%------------------------------------------------------------------------
    function UD = n_getUserData
        ud = n_getThisHandle;
        UD = ud.UserData;
    end

%------------------------------------------------------------------------
    function [ud, f] = n_getThisHandle
        f = fig;
        ud = f.UserData;
    end

end