www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/+mbcgui/+dialog/MultiObjectDialog.m
classdef MultiObjectDialog < mbcgui.dialog.StandardDialog %mbcgui.dialog.MultiObjectDialog class % mbcgui.dialog.MultiObjectDialog extends mbcgui.dialog.StandardDialog. % % mbcgui.dialog.MultiObjectDialog properties: % Parent - Property is of type 'MATLAB array' % Figure - Property is of type 'MATLAB array' (read only) % Title - Property is of type 'ustring' % Object - Property is of type 'MATLAB array' (read only) % HasObjectChanged - Property is of type 'bool' (read only) % HelpHandler - Property is of type 'string' % HelpCode - Property is of type 'string' % DisplayHelp - Property is of type 'bool' % UserData - Property is of type 'MATLAB array' % PageInfoFunction - Property is of type 'MATLAB array' % DisplaySinglePageAsTab - Property is of type 'bool' % ChooserLabel - Property is of type 'string' % ChooserLabelWidth - Property is of type 'int' % OptionStrings - Property is of type 'MATLAB array' % OptionFunctions - Property is of type 'MATLAB array' % OptionDestructors - Property is of type 'MATLAB array' % OptionPageFunctions - Property is of type 'MATLAB array' % CurrentOption - Property is of type 'int' % DialogPanelSize - Property is of type 'MATLAB array' % LayoutFunction - Property is of type 'MATLAB array' % % mbcgui.dialog.MultiObjectDialog methods: % getDialogPanelSize - Return the desired size of the display panel % getOptionObject - Get the object for a specific option. % isOptionCreated - Check whether an option has been created yet. % updateOptionObject - Set a new object for a specific option. % Copyright 2000-2015 The MathWorks, Inc. and Ford Global Technologies, Inc. properties (AbortSet) %OPTIONSTRINGS Property is of type 'MATLAB array' OptionStrings = { }; %OPTIONFUNCTIONS Property is of type 'MATLAB array' OptionFunctions = { }; %OPTIONDESTRUCTORS Property is of type 'MATLAB array' OptionDestructors = { }; %OPTIONPAGEFUNCTIONS Property is of type 'MATLAB array' OptionPageFunctions = { }; end properties (AbortSet, SetObservable) %CHOOSERLABEL Property is of type 'string' ChooserLabel = 'Select item:'; %CHOOSERLABELWIDTH Property is of type 'int' ChooserLabelWidth = 150; %CURRENTOPTION Property is of type 'int' CurrentOption %DIALOGPANELSIZE Property is of type 'MATLAB array' DialogPanelSize = [ 380, 400 ]; %LAYOUTFUNCTION Property is of type 'MATLAB array' LayoutFunction = []; end properties (Access=protected, AbortSet) %HCARDLAYOUT Property is of type 'MATLAB array' hCardLayout = []; %HMODLAYOUT Property is of type 'MATLAB array' hMODLayout = []; %OPTIONOBJECTS Property is of type 'MATLAB array' OptionObjects = { }; %OPTIONGROUPS Property is of type 'MATLAB array' OptionGroups = []; %OPTIONSMADE Property is of type 'MATLAB array' OptionsMade = false( 0 ); %MOD_LISTENERS Property is of type 'handle vector' MOD_Listeners = []; end events OptionChanged end % events methods % constructor block function obj = MultiObjectDialog(varargin) %MULTIOBJECTDIALOG Constructor for MultiObjectDialog object % OBJ = MULTIOBJECTDIALOG(Prop, Value, ...) creates a new % MultiObjectDialog object for selecting from a series of objects. % % During creation you should specify values for the OptionStrings and % OptionFunctions properties. Each object option corresponds to a string % in the OptionStrings cell array. The OptionFunctions property is a cell % array the same size as OptionStrings where each cell must contain either % (a) a function handle that can generate a particular option's object on % demand or (b) an actual instance of an object to use for that option. % % The functions specified for OptionFunctions should have the signature: % % obj = FUNC(hDialog) % % Each object can provide multiple pages of information for the dialog. % If the OptionPageFunctions property is empty, the PageInfoFunction % property is called to generate the DialogPageInfo objects for each % option object. % % If the OptionPageFunctions property is non-empty, it must be a cell % array of function handles that is the same length as the OptionStrings % property. The function handle corresponding to the current option is % then automatically set as the PageInfoFunction. obj@mbcgui.dialog.StandardDialog(varargin{: }); % converted super class constructor call if length(obj.OptionStrings)~=length(obj.OptionFunctions) error(message('mbc:xregGui:MultiObjectDialog:InvalidArgument')); end % Set up container for objects to be edited obj.OptionObjects = cell(size(obj.OptionStrings)); % Set up array of handles to page groups obj.OptionGroups = mbcgui.dialog.PageGroup.empty; % Set up boolean flags that indicate which pages have been made obj.OptionsMade = false(size(obj.OptionStrings)); Nopts = length(obj.OptionStrings); % Make basic UI SC = xregGui.SystemColorsDbl; hChooser = uicontrol('Parent', obj.Figure, ... 'Tag', 'ObjectChooserPopup',... 'Style', 'popupmenu', ... 'BackgroundColor', SC.WINDOW_BG, ... 'Visible', 'off', ... 'String', obj.OptionStrings, ... 'Value', obj.CurrentOption, ... 'Callback', @i_changeOption); hLabel = xregGui.labelcontrol('parent', obj.Figure, ... 'Visible', 'off', ... 'String', obj.ChooserLabel, ... 'LabelSize', obj.ChooserLabelWidth, ... 'LabelSizeMode', 'absolute', ... 'ControlSize', 1, ... 'ControlSizeMode', 'relative', ... 'Gap', 5, ... 'Control', hChooser); hCards = xregcardlayout(obj.Figure, ... 'packstatus', 'off', ... 'visible', 'off', ... 'numcards', Nopts+1, ... 'CurrentCard', Nopts+1); obj.hCardLayout = hCards; % Call a method to create the layout. This allows subclasses to overload % the basic look obj.hMODLayout = obj.pCreateChooserLayout(hLabel, hCards); % Functions that destroy the appropriate option objects when the dialog is % destroyed KeepCurrent = false; % Hook up listeners obj.MOD_Listeners = [ ... event.proplistener(obj, obj.findprop('ChooserLabel'), 'PostSet', @i_setLabel); ... event.proplistener(obj, obj.findprop('CurrentOption'), 'PostSet', @i_setOption); ... event.listener(obj, 'ObjectBeingDestroyed', @i_destroyobj); ... event.listener(obj, 'Finalize', @(h,evt) i_setkeepcurrent(h,evt,true)); ... event.listener(obj, 'Cancel', @(h,evt) i_setkeepcurrent(h,evt,false)); ... ]; % Create the first object and switch to it. obj.pSelectOption; function i_changeOption(src, ~) obj.CurrentOption = get(src, 'Value'); end function i_setLabel(~, ~) hLabel.String = obj.ChooserLabel; end function i_setOption(~, evt) set(hChooser, 'Value', obj.CurrentOption); obj.pSelectOption; end function i_setkeepcurrent(~, ~, setting) KeepCurrent = setting; end function i_destroyobj(~, ~) if KeepCurrent obj.pDestroyOptions(obj.CurrentOption); else obj.pDestroyOptions; end end end end % constructor block methods % public methods %---------------------------------------- function sz = getDialogPanelSize(obj) %GETDIALOGPANELSIZE Return the desired size of the display panel % SZ = GETDIALOGPANELSIZE(OBJ) returns a 2-element vector containing the % width and height of the dialog panel. This is taken as the maximum % values from all of the preferred widths and heights of the % DialogPageInfo objects. sz = obj.DialogPanelSize; end % getDialogPanelSize %---------------------------------------- function OptObj = getOptionObject(obj, OptionIdx) %GETOPTIONOBJECT Get the object for a specific option. % OPTOBJ = GETOPTIONOBJECT(OBJ, OPTIONIDX) returns the current object for % the specified index. If the option has not yet been created then this % function will return an empty. if obj.isOptionCreated(OptionIdx) OptObj = obj.OptionGroups(OptionIdx).getObject; else OptObj = []; end end % getOptionObject %---------------------------------------- function ret = isOptionCreated(obj, OptionIdx) %ISOPTIONCREATED Check whether an option has been created yet. % ISOPTIONCREATED(OBJ, OPTIONIDX) returns true if the option specified % has been created for the user. Options are only created when a user % first selects them from the list. ret = obj.OptionsMade(OptionIdx); end % isOptionCreated %---------------------------------------- function updateOptionObject(obj, OptionIdx, OptObj) %UPDATEOPTIONOBJECT Set a new object for a specific option. % UPDATEOPTIONOBJECT(OBJ, OPTIONIDX, OPTOBJ) update the specified option % to use the new object OPTOBJ. If the specified option has not yet been % created then this will set the initial object for an option. if obj.isOptionCreated(OptionIdx) obj.OptionGroups(OptionIdx).updateObject(OptObj); else obj.OptionObjects{OptionIdx} = OptObj; end end % updateOptionObject end % public methods methods (Access=protected) %---------------------------------------- function pCancel(obj, ~) %PCANCEL Cancel the dialog % PCANCEL(OBJ, EVT) is called in response to the cancel event in the % dialog. The contained DialogPageGroup is cancelled. % Cancel all DialogPageGroups for n = 1:length(obj.OptionGroups) if iscomponent(obj.OptionGroups(n)) obj.OptionGroups(n).cancel; end end obj.updateObject(obj.OptionGroups(obj.CurrentOption).Object); end % pCancel %---------------------------------------- function lyt = pCreateChooserLayout(obj, hLabel, hCards) %PCREATECHOOSERLAYOUT Create the layout for the object chooser controls % LYT = PCREATECHOOSERLAYOUT(OBJ, HLABEL, HCARDS) creates a layout % that contains the labelcontrol HLABEL and the cardlayout HCARDS. % Subclasses may override this method to provide customized layout. The % layout that is returned should contain HLABEL and HCARDS. if ~isempty(obj.LayoutFunction) % Defer layout generation to provided function lyt = obj.LayoutFunction(obj, hLabel, hCards); else lyt = xreggridbaglayout(obj.Figure, ... 'dimension', [2 1], ... 'rowsizes', [20 -1], ... 'gapy', 10, ... 'elements', {hLabel, hCards}); end end % pCreateChooserLayout %---------------------------------------- function hPanel = pCreateDialogPanel(obj) %PCREATEDIALOGPANEL Create and return a display object % HPANEL = PCREATEDIALOGPANEL(OBJ) creates and returns a handle to an % object that is used as the gui for displaying and/or editing the % dialog's object. if ~isobject(obj.Object) && isempty(obj.Object) set(obj.hCardLayout, 'CurrentCard', get(obj.hCardLayout, 'NumCards')); else if ~obj.OptionsMade(obj.CurrentOption) % Get the layout to embed from the superclass. We need to always do this % to make sure that the superclass links things up correctly for the % current object. hGroup = pCreateDialogPanel@mbcgui.dialog.StandardDialog(obj); obj.OptionGroups(obj.CurrentOption) = hGroup; attach(obj.hCardLayout, hGroup, obj.CurrentOption); obj.OptionsMade(obj.CurrentOption) = true; else hGroup = obj.OptionGroups(obj.CurrentOption); obj.pAttachToPanel(hGroup); end % Switch to the correct card set(obj.hCardLayout, 'CurrentCard', obj.CurrentOption); end hPanel = obj.hMODLayout; end % pCreateDialogPanel %---------------------------------------- function pDestroyDialogPanel(obj, hPanel) %PDESTROYDIALOGPANEL Destroys the specified display object % PDESTROYDIALOGPANEL(OBJ, HPANEL) destroys the display object HPANEL. % This method is called if the display object is swapped for a different % one and the display needs to be re-created. % Shift the card to the blank one and do not destroy the panel set(obj.hCardLayout, 'CurrentCard', get(obj.hCardLayout, 'NumCards')); end % pDestroyDialogPanel %---------------------------------------- function pDestroyOptions(obj, KeepIdx) %PDESTROYOPTIONS Destroy the options that are no longer needed % PDESTROYOPTIONS(OBJ, SELIDX) destroys the objects for the options that % are not specified in SELIDX and that were created by the dialog. If % destructor functions have been provided then these are called on the % objects before they are cleared from the store of visited options. If % SELIDX is omitted then all objects are destroyed. if nargin<2 KeepIdx = []; end dfun = obj.OptionDestructors; optobj = obj.OptionObjects; if isempty(dfun) || length(dfun)~=length(optobj) % No actions to perform return end cfun = obj.OptionFunctions; for n = setdiff(1:length(optobj), KeepIdx) if isobject(optobj{n}) && ~isempty(dfun{n}) && isa(cfun{n}, 'function_handle') dfun{n}(optobj{n}); end end end % pDestroyOptions %---------------------------------------- function pFinalize(obj, evt) %PFINALIZE Finalize the dialog % PFINALIZE(OBJ, EVT) is called in response to the finalize event in the % dialog. The contained DialogPageGroup is finalized. % Cancel all DialogPageGroups except for the curent one, which is finalized for n = 1:length(obj.OptionGroups) if iscomponent(obj.OptionGroups(n)) if n==obj.CurrentOption obj.OptionGroups(n).finalize; else obj.OptionGroups(n).cancel; end end end obj.updateObject(obj.OptionGroups(obj.CurrentOption).Object); end % pFinalize %---------------------------------------- function pSelectOption(obj) %PSELECTOPTION Implements the selection of a new object option % PSELECTOPTION(OBJ) switches the dialog to display the currently selected % option. If the object is not already created, this method will first % create it. PR = xregGui.PointerRepository; ptrID = PR.stackSetPointer(obj.Figure, 'watch'); index = obj.CurrentOption; if isempty(obj.OptionObjects{index}) % Need to create the object if isa(obj.OptionFunctions{index}, 'function_handle') obj.OptionObjects{index} = obj.OptionFunctions{index}(obj); else obj.OptionObjects{index} = obj.OptionFunctions{index}; end NewOptionObj = obj.OptionObjects{index}; else NewOptionObj = obj.OptionGroups(index).Object; end % Set page creation function if required if ~isempty(obj.OptionPageFunctions) obj.PageInfoFunction = obj.OptionPageFunctions{index}; end % Switch dialog to new object display obj.switchObject(NewOptionObj); % Send event to notify users of change obj.notify('OptionChanged'); PR.stackRemovePointer(obj.Figure, ptrID); end % pSelectOption end end % classdef