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