www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/+mbcgui/+actions/Action.m
classdef Action < matlab.mixin.SetGet & matlab.mixin.Copyable & matlab.mixin.Heterogeneous %mbcgui.actions.Action class % mbcgui.actions.Action properties: % Command - Property is of type 'MATLAB callback' % Label - Property is of type 'string' % Description - Property is of type 'string' % IconFile - Property is of type 'string' % % mbcgui.actions.Action methods: % attachToMenu - Take over a menu item for the action % createButton - Create a uicontrol button for the action % createMenuItem - Create a menu item for the action % createToolbutton - Create a toolbar button for the action % enableStateChange - Enable state change checking on properties % execute - Perform the action command % numRequiredMenus - Get the number of menus that this action requires % setButtonProperties - Set button properties to match the action % setMenuProperties - Set menu item properties to match the action % setToolbuttonProperties - Set toolbar button properties to match the action % shouldSeparate - Return true if action should be separated in menus/toolbars % Copyright 2005-2016 The MathWorks, Inc. and Ford Global Technologies, Inc. properties (AbortSet, SetObservable) %COMMAND Property is of type 'MATLAB callback' Command = []; %LABEL Property is of type 'string' Label = ''; %DESCRIPTION Property is of type 'string' Description = ''; %ICONFILE Property is of type 'string' IconFile = ''; %TransparentColor transparency color for icons TransparentColor = [0 255 0] %ActiveLabel active form of label. % For example, Create Optimization instead of Optimization. % Defaults to Label if undefined. ActiveLabel = '' end properties (Access=protected, AbortSet) %STATECHANGELISTENERS Property is of type 'handle vector' StateChangeListeners = []; end events (NotifyAccess=protected) StateChanged end % events methods % constructor block function obj = Action(varargin) %ACTION Construct a new Action object % % OBJ = ACTION(COMMAND, LABEL, DESCRIPTION, ICONFILE) creates a new % Action object for the specified COMMAND. If any arguments are omitted % the action will be created with them unset. % % An Action encapsulates a command to run, in the form of a callback, and % an associated label and longer description. numArgs = length(varargin); if numArgs>3 obj.IconFile = varargin{4}; end if numArgs>2 obj.Description = varargin{3}; end if numArgs>1 obj.Label = varargin{2}; end if numArgs obj.Command = varargin{1}; end end % Action end % constructor block methods function set.Command(obj,value) % DataType = 'MATLAB callback' % no MATLAB callback checks yet' obj.Command = value; end function set.Label(obj,value) % DataType = 'string' validateattributes(value,{'char'}, {'row'},'','Label') obj.Label = value; end function set.Description(obj,value) % DataType = 'string' validateattributes(value,{'char'}, {'row'},'','Description') obj.Description = value; end function set.IconFile(obj,value) % DataType = 'string' validateattributes(value,{'char'}, {'row'},'','IconFile') obj.IconFile = value; end function set.StateChangeListeners(obj,value) % DataType = 'handle vector' validateattributes(value,{'handle'}, {'vector'},'','StateChangeListeners') obj.StateChangeListeners = value; end function a = get.ActiveLabel(obj) if isempty(obj.ActiveLabel) % use label if ActiveLabel not defined a = obj.Label; else a = obj.ActiveLabel; end end end % set and get functions methods(Sealed) % matlab.mixin.Heterogeneous requires set and get to be sealed % to work with Heterogeneous arrays function varargout = set(varargin) if nargout [varargout{1:nargout}]=set@matlab.mixin.SetGet(varargin{:}); else set@matlab.mixin.SetGet(varargin{:}); end end function varargout = get(varargin) if nargout [varargout{1:nargout}]=get@matlab.mixin.SetGet(varargin{:}); else get@matlab.mixin.SetGet(varargin{:}); end end function OK = eq(varargin) OK = eq@matlab.mixin.SetGet(varargin{:}); end function OK = ne(varargin) OK = ne@matlab.mixin.SetGet(varargin{:}); end function h = findobj(obj,varargin) h = findobj@matlab.mixin.SetGet(obj,varargin{:}); end end methods % public methods %---------------------------------------- function attachToMenu(obj, hMenu) %ATTACHTOMENU Take over a menu item for the action % % ATTACHTOMENU(OBJ, HMENU) sets the properties of HMENU to reflect the % action OBJ. set(hMenu, 'Callback', @obj.onExecute); obj.setMenuProperties(hMenu); % Attach a listener to keep menu state matching the action StateList = event.listener(obj, 'StateChanged', @(h,evt) obj.onResetMenu(hMenu)); set(hMenu, 'UserData', StateList); end % attachToMenu %---------------------------------------- function hButton = createButton(obj, hParent) %CREATEBUTTON Create a uicontrol button for the action % % HBUTTON = CREATEBUTTON(OBJ, HPARENT) creates a new button for the % action in the given parent. When the button is clicked the action will % execute. hButton = uicontrol('Parent', hParent, ... 'Style', 'pushbutton', ... 'Callback', @obj.onExecute); obj.setButtonProperties(hButton); % Attach a listener to keep state matching the action StateList = event.listener(obj, 'StateChanged', @(h,evt) obj.onResetButton(hButton)); set(hButton, 'UserData', StateList); end % createButton %---------------------------------------- function hMenu = createMenuItem(obj, hParent) %CREATEMENUITEM Create a menu item for the action % % HMENU = CREATEMENUITEM(OBJ, HPARENT) creates a new uimenu object with % HPARENT as a parent. When the menu item is selected it will execute the % action. nMenus = obj.numRequiredMenus; hMenu = gobjects(1,nMenus); for n = 1:nMenus hMenu(n) = uimenu('Parent', hParent); end obj.attachToMenu(hMenu); end % createMenuItem function wf = createWorkflowItems(obj,hWorkflow) %createWorkflowItems create items on Common Task pane % hWorkflow is a mbcWorkflowPanel object nMenus = obj.numRequiredMenus; wf = addItem( hWorkflow,nMenus ); attachToWorkfow(obj,wf) end function attachToWorkfow(obj,wf) %attachToWorkfow attach action to mbcWorkflowItem set(wf, 'Callback', @obj.onExecute); obj.setWorkflowProperties(wf); % Attach a listener to keep menu state matching the action StateList = event.listener(obj, 'StateChanged', @(h,evt) obj.onResetWorkflow(wf)); set(wf, 'UserData', StateList); end function setWorkflowProperties(obj,wf) %setWorkflowProperties set properties of workflow panel lbl = obj.pRemoveMnemonic(obj.Label); set(wf,... 'TransparentColor', obj.TransparentColor,... 'IconFile',obj.IconFile,... 'Label',lbl,... 'Enable', 'on', ... 'Visible', 'on'); end %---------------------------------------- function hButton = createToolbutton(obj, hParent) %CREATETOOLBUTTON Create a toolbar button for the action % % HBUTTON = CREATETOOLBUTTON(OBJ, HPARENT) creates a new toolbar button % for the action. When the button is clicked the action will execute. hButton = xregGui.uipushtool(hParent, ... 'ClickedCallback', @obj.onExecute, ... 'TransparentColor', obj.TransparentColor); obj.setToolbuttonProperties(hButton); % Attach a listener to keep menu state matching the action StateList = event.listener(obj, 'StateChanged', @(h,evt) obj.onResetToolbar(hButton)); set(hButton, 'UserData', StateList); end % createToolbutton %---------------------------------------- function enableStateChange(obj, props) %ENABLESTATECHANGE Enable state change checking on properties % % ENABLESTATECHANGE(OBJ, PROPS) adds listeners that will fire the state % change event when any one of the properties listed in the cell array % PROPS is altered. if ischar(props) props = {props}; end hList = obj.StateChangeListeners; % Remove properties that are already being listened to pDone = []; if ~isempty(hList) pDone = [hList.Source]; pDone = [pDone{:}]; end for n = 1:length(props) hProp = obj.findprop(props{n}); if ~any(hProp==pDone) newList = event.proplistener(obj, hProp, 'PostSet', @obj.onSendState); hList = [hList; newList]; %#ok<AGROW> pDone = [pDone, hProp]; %#ok<AGROW> end end obj.StateChangeListeners = hList; end % enableStateChange %---------------------------------------- function execute(obj) %EXECUTE Perform the action command % % EXECUTE(OBJ) evaluates the action's callback command. xregcallback(obj.Command,obj,[]) end % execute %---------------------------------------- function N = numRequiredMenus(obj) %#ok<MANU> %NUMREQUIREDMENUS Get the number of menus that this action requires % % N = NUMREQUIREDMENUS(OBJ) returns an integer that is the number of menus % that an action will make when createMenuItem is called. N = 1; end % numRequiredMenus %---------------------------------------- function setButtonProperties(obj, hButton) %SETBUTTONPROPERTIES Set button properties to match the action % % SETBUTTONPROPERTIES(OBJ, HBUTTON) is called when the uicontrol button's % properties need to be set up to match the action's state. set(hButton, ... 'Enable', 'on', ... 'Visible', 'on'); xregGui.iconuicontrol(hButton,'ImageFile',obj.IconFile,... 'TransparentColor',obj.TransparentColor); if isempty(hButton.CData) lbl = obj.pRemoveMnemonic(obj.Label); set(hButton,'String',lbl) else set(hButton,'TooltipString',obj.Description) end end % setButtonProperties %---------------------------------------- function setMenuProperties(obj, hMenu) %SETMENUPROPERTIES Set menu item properties to match the action % % SETMENUPROPERTIES(OBJ, HMENU) is called when the menu item's properties % need to be set up to match the action's state. hP = get(hMenu, 'Parent'); if ~isempty(hP) hCh = get(hP, 'Children'); hCh(hCh==hMenu) = []; OtherLabels = get(hCh, {'Label'}); lbl = obj.pUniqueMnemonic(obj.Label, OtherLabels); else lbl = obj.Label; end set(hMenu, ... 'Enable', 'on', ... 'Visible', 'on', ... 'Checked', 'off', ... 'Label', lbl); end % setMenuProperties %---------------------------------------- function setToolbuttonProperties(obj, hButton) %SETTOOLBUTTONPROPERTIES Set toolbar button properties to match the action % % SETTOOLBUTTONPROPERTIES(OBJ, HBUTTON) is called when the menu item's % properties need to be set up to match the action's state. set(hButton, ... 'Enable', 'on', ... 'Visible', 'on', ... 'ImageFile', obj.IconFile, ... 'ToolTipString', obj.Description); end % setToolbuttonProperties %---------------------------------------- function ret = shouldSeparate(obj) %#ok<MANU> %SHOULDSEPARATE Return true if action should be separated in menus/toolbars % % RET = SHOULDSEPARATE(OBJ) returns true if the action should have % separators placed before and after it. ret = false; end % shouldSeparate end % public methods methods(Access=protected) % protected methods %---------------------------------------- function str = pRemoveMnemonic(obj, str) %#ok<INUSL> %PREMOVEMNEMONIC Remove the mnemonic mark from a label % % STR = PREMOVEMNEMONIC(OBJ, STR) removes the first '&' from the string % STR. This allows use of labels on objects that do not support % mnemonics. MnemonicIdx = strfind(str, '&'); if ~isempty(MnemonicIdx) str(MnemonicIdx(1)) = []; end end % pRemoveMnemonic %---------------------------------------- function str = pUniqueMnemonic(obj, str, PreStr) %#ok<INUSL> %PUNIQUEMNEMONIC Ensure that the mnemonic in a string is unique % % STR = PUNIQUEMNEMONIC(OBJ, STR, PRESTR) ensures that the mnemonic % character in the string STR is unique to those in the strings in the % cell array PRESTR. MnemonicIdx = strfind(str, '&'); if ~isempty(MnemonicIdx) MnemonicIdx = MnemonicIdx(1); MnemonicChar = str(MnemonicIdx+1); PreChars = cell(size(PreStr)); PreIdx = strfind(PreStr, '&'); for n = 1:length(PreIdx) if ~isempty(PreIdx{n}) PreChars{n} = PreStr{n}(PreIdx{n}+1); else PreChars{n} = ''; end end if any(strcmpi(MnemonicChar, PreChars)) % Remove current mnemonic str(MnemonicIdx) = []; % Split into words and look for new mnemonic places Wstart = regexp(str, '\<\w'); Wend = regexp(str, '\w\>'); Wlength = Wend-Wstart+1; LetterOffset = 0; NewMnemonicIdx = 0; while any(LetterOffset<Wlength) && NewMnemonicIdx==0 for n = 1:length(Wstart) Idx = Wstart(n)+LetterOffset; if LetterOffset<Wlength(n) && ~any(strcmpi(str(Idx), PreChars)) NewMnemonicIdx = Idx; break end end LetterOffset = LetterOffset+1; end if NewMnemonicIdx>0 str = [str(1:NewMnemonicIdx-1), '&', str(NewMnemonicIdx:end)]; end end end end % pUniqueMnemonic %---------------------------------------- function onResetMenu(obj, hMenu,~) obj.setMenuProperties(hMenu); end % i_resetmenu function onResetWorkflow(obj, hMenu,~) obj.setWorkflowProperties(hMenu); end % i_resetmenu %---------------------------------------- function onResetButton(obj, hButton,~) obj.setButtonProperties(hButton); end % i_resetbutton %---------------------------------------- function onResetToolbar(obj, hButton,~) obj.setToolbuttonProperties(hButton); end % i_resetbutton %---------------------------------------- function onExecute(obj, ~,~) obj.execute; end % i_resetbutton %---------------------------------------- function onSendState(obj,~,~) obj.notify('StateChanged'); end end % protected methods end % classdef