www.gusucode.com > mbctools 工具箱 matlab 源码程序 > mbctools/+xregbdrygui/Editor.m
classdef Editor < mbcgui.Application %xregbdrygui.Editor class % xregbdrygui.Editor extends mbcgui.Application % % xregbdrygui.Editor properties: % MessageService - xregbdrygui.BdryMessageService (read only) % Actions - Actions for boundary editor (read only) % Toolbar - Toolbar layout for boundary editor (read only) % View - View components (read only) % % xregbdrygui.Editor methods: % restore - Restore the boundary editor after a sleep % create - static method to start the boundary editor (Static) % Copyright 2005-2016 The MathWorks, Inc. and Ford Global Technologies, Inc. properties (Access=private, AbortSet) PointerStack = cell(0,2); end properties (SetAccess=protected, AbortSet) %MESSAGESERVICE xregbdrygui.BdryMessageService MessageService = []; %ACTIONS Actions for boundary editor Actions = []; %TOOLBAR Toolbar layout for boundary editor Toolbar = []; %VIEW View components % Card, Tree, Info, Panel, TestSelector View = []; end properties(Dependent) %Root Root of boundary tree % Root is a convenience dependent property for setting the % boundary tree in the boundary editor Root end methods (Access=protected) % constructor block function obj = Editor(varargin) %XREGBDRYGUI.EDITOR class constructor % OBJ = EDITOR(VARARGIN) obj@mbcgui.Application('Tag','BoundaryEditor',varargin{:}); end % Editor end % constructor block methods % set/get methods function broot = get.Root(obj) % root of boundary tree is stored in the MessageService broot = obj.MessageService.Root; end function set.Root(obj,broot) %set.Root update root of boundary tree in MessageService obj.MessageService.setRoot(broot) end end methods (Static) function obj = create(varargin) %create create or restore data editor % obj = xregbdrygui.Editor.create('Root',broot); Tag = 'BoundaryEditor'; obj = xregbdrygui.Editor.find(Tag); if isempty(obj) % initial default size deSize = [50 100 800 600]; obj = xregbdrygui.Editor('Tag',Tag,... 'Visible','off',... % create the figure invisible and turn on when done 'Position',deSize); obj.SleepOnClose = true; else restore(obj); end if nargin busy(obj.MessageService,'Initializing...') set(obj,'Title','Boundary Editor',varargin{:}); idle(obj.MessageService) setStatusMessage(obj,'Ready'); obj.Figure.Visible = 'on'; end end end methods % public methods function restore(obj) %RESTORE Make window visible again % RESTORE(OBJ) will re-open an application that has been put into a % "sleep" mode when closed. if strcmp(get(obj.Figure, 'Visible'), 'on') % Fake a close event before restoring the application obj.close(true); end obj.restore@mbcgui.Application(); end end methods (Access=protected) function C = createContent(obj) %CREATECONTENT Create content layout. % C = CREATECONTENT(OBJ) constructs the basic content layout for the Data % Editor. % Set-up the message service obj.MessageService = xregbdrygui.BdryMessageService; obj.Listeners = [obj.Listeners(:); event.listener(obj.MessageService,'Busy',@obj.onBusy) event.listener(obj.MessageService,'Idle',@obj.onIdle)]; % Create the view, the actions, the menus and the toolbar obj.pCreateActions; obj.pCreateView; obj.pCreateMenus; obj.pCreateToolbar; % Create the layout lyt = obj.pCreateLayout; % Link the visible components together C = xreggridbaglayout(obj.Figure,... 'dimension', [2 1],... 'elements', {obj.Toolbar.Layout lyt},... 'rowsizes', [31 -1],... 'gapy', 2); end function onBusy(obj,~,evt) %onBusy listen for MessageService.Busy and change the figure pointer ptrID = setPointer(obj,'watch'); msgID = setStatusMessage(obj,evt.Data.Message); obj.PointerStack(end+1,:) = {ptrID,msgID}; end function onIdle(obj,~,~) %onIdle listen for MessageService.Idle and change the figure pointer if ~isempty(obj.PointerStack) removePointer(obj,obj.PointerStack{end,1}) removeStatusMessage(obj,obj.PointerStack{end,2}) obj.PointerStack(end,:) = []; end end %---------------------------------------- function onClose(obj,evt) %CLOSE Close method for boundary editor % CLOSE(OBJ) sets the boundary editor to invisible % Before setting the editor invisible, a check is performed to see if % there is a best constraint set, i.e., if there is a constraint from at % root node. If there is not, then the user is presented with the % opportunity to return to the editor and set a best constraint. If there % is only one xregbdrydev node in the whole tree, then this can be set at % best automagically. However, in this case the user is asked if this is % what they want. % % See also mbcgui.Application.close % If there is no best contsraint, then ask the user if they really want to % close things down state = 'on'; if obj.MessageService.hasData, root = obj.MessageService.Root; if isvalid(root) && root.isa('xregbdryroot') bestConstraint = root.getconstraint; if isempty( bestConstraint ), leaves = root.leaves; if length( leaves ) == 1 && isa( leaves, 'xregbdrydev' ) i_BringFigureToFront( obj ); state = i_AskAboutTheOneAndOnlyNode( root.info, leaves ); else i_BringFigureToFront( obj ); state = i_AskAboutLackOfBestConstraint( root.info ); end end end end if strcmpi(state,'off') evt.CancelClose = true; end end % close %---------------------------------------- function pAddListener(obj, varargin) %PADDLISTENER Add a listener to the list held by the boundary editor % PADDLISTENER(OBJ, LISTENER) adds the given LISTENER to the list of % listeners held by the Editor (OBJ). % % if you want PADDLISTENER( OBJ, handle.listener( <arguments> ) ), then use % PADDLISTENER( OBJ, <arguments> ). obj.Listeners = cat(1,obj.Listeners, varargin{:} ); end % pAddListener %---------------------------------------- function pCreateActions(obj) %PCREATEACTIONS Create the actions for a Boundary Editor % PCREATEACTIONS(OBJ) % Set the Actions property of the editor (object) obj.Actions = xregbdrygui.Actions(obj.MessageService); end % pCreateActions %---------------------------------------- function lyt = pCreateLayout(obj) %PCREATELAYOUT Create the layout for a Boundary Editor % PCREATELAYOUT(OBJ) SC = mbcgui.util.SystemColorsDbl; figh = obj.Figure; % The layout is something like this % +-------++--------------------+ % | || | % | tree || | % | || multi | % +=======++ | % | info || panel | % | || | % +-------++ | % | test || | % +-------++--------------------+ % The double lines, i.e., = and || are the adjustable splits % The first layout is the adjustable split between the tree view and the % info view lyt = xregsplitlayout( figh,... 'Orientation', 'ud',... 'Top', obj.View.Tree,... 'Bottom', obj.View.Info,... 'Split', [0.7, 0.3],... 'DividerStyle', 'flat',... 'DividerWidth', 4 ); % The second layout is the non-adjustable split between tree+info and the % test selector. % -- We need a oblong that forms the fake split between thw two % sub-layouts. hFakeSplitPanel = uicontrol('Parent', figh, ... 'Visible', 'off', ... 'Style', 'text', ... 'BackgroundColor', SC.CTRL_BG, ... 'HitTest', 'off', ... 'Enable', 'inactive'); lyt = xreggridbaglayout( figh, ... 'Dimension', [3, 1], ... 'rowsizes', [-1, 2, 130], ... 'elements', {lyt, hFakeSplitPanel, obj.View.TestSelector} ); % The adjustable split between the tree+info+test and the multi-panel lyt = xregsplitlayout( figh,... 'Left', lyt,... 'Right', obj.View.Card,... 'Split', [0.2, 0.8],... 'MinWidth', [30, 30], ... 'DividerStyle', 'flat',... 'DividerWidth', 4 ); set( obj.Toolbar.Layout, ... 'ToolBarDraw', 'on', ... 'packstatus', 'on', ... 'Visible', 'on'); end % pCreateLayout %---------------------------------------- function pCreateMenus(obj) %PCREATEMENUS Create the menus for a Boundary Editor % PCREATEMENUS(OBJ) figh = obj.Figure; % Top level menus menuFile = uimenu( 'Parent', figh, 'Label', '&File' ); menuEdit = uimenu( 'Parent', figh, 'Label', '&Edit' ); menuView = uimenu( 'Parent', figh, 'Label', '&View' ); % add window menu xregwinlist( figh ); createFileMenu(obj.Actions,menuFile) uimenu('Parent',menuFile,... 'Label','&Close',... 'Separator','on',... 'Accelerator','w',... 'Callback', @( src, evt ) obj.close,... 'Interruptible','off'); createEditMenu(obj.Actions,menuEdit) % View Menu items obj.View.Panel.addViewMenuItems( menuView ); % Tools menu items % --- Search for additional tools ext = mbcextensions.Extensions.Model; bdryTools = ext.BoundaryEditorTools; if length( bdryTools ) >= 1, menuTools = uimenu( 'Parent', figh, 'Label', '&Tools' ); mbccreateaddonmenus( bdryTools, menuTools, obj ); end % Add help menu mv_helpmenu( figh, {'&Boundary Editor Help', 'xreg_bdrymodeleditor'} ); end % pCreateMenus %---------------------------------------- function pCreateToolbar(obj) %PCREATETOOLBAR Create the toolbar for a Boundary Editor % PCREATETOOLBAR(OBJ) tblyt = xregtoolbarlayout( obj.Figure, ... 'toolbardraw', 'off', ... 'ResourceLocation', xregrespath, ... 'spacerwidth', 2 ); tb.Layout = tblyt; toolbar = get( tblyt, 'ToolBar' ); toolbarGroup = mbcgui.actions.ActionGroup; toolbarGroup.Actions = [obj.Actions.FileActionGroup obj.Actions.EditActionGroup obj.Actions.BestActionGroup obj.View.Panel.Actions.ChangeView obj.Actions.AllViewGroup ]; tb.handles = toolbarGroup.createToolbutton( toolbar ); % Help mv_helptoolbutton( tblyt, 'xreg_bdrymodeleditor' ); % Store in object obj.Toolbar = tb; end % pCreateToolbar %---------------------------------------- function pCreateView(obj) %PCREATEVIEW Create the views for a Boundary Editor % PCREATEVIEW(OBJ) % Create a MultiViewPanel that is setup for the boundary editor views obj.View.Panel = mbcgui.multiview.MultiViewPanel( ... 'Parent', obj.Figure, ... 'MessageService', obj.MessageService, ... 'ViewLayoutName', 'BoundaryEditor', ... 'StatusBar', obj.StatusBar, ... 'GlobalViewOptions', obj.Actions.AllViewGroup, ... 'ViewList', xregbdrygui.BdryViewList, ... 'AlwaysAllowPrintToFigure', false); % Set up a "card" object so we can display a nice nothing in the "null" case sc = mbcgui.util.SystemColorsDbl; obj.View.Card = xregcardlayout( obj.Figure, 'numcards', 2 ); noview = uipanel('Parent', obj.Figure, ... 'Units', 'pixels', ... 'BorderType', 'beveledin', ... 'BackgroundColor', sc.CTRL_SHADOW); attach( obj.View.Card, noview, 1 ); attach( obj.View.Card, obj.View.Panel, 2 ); % If the constraint changes then we might want to switch cards, i.e., % display the "null" view if there is no constraint and the proper view if % there is a constraint. Thus we listen to the "ConstraintChange" event. obj.pAddListener( event.listener( obj.MessageService, 'ConstraintChange', ... @( s, e ) i_cardSwitcher ) ); function i_cardSwitcher if isempty( obj.MessageService ) || ~obj.MessageService.hasData, % No view set( obj.View.Card, 'currentcard', 1 ); set( obj.Actions.AllViewGroup, 'Enabled', false ); else % There is something to see, so turn on the view set( obj.View.Card, 'currentcard', 2 ); end end % Create a TreeView to display the tree of constraints obj.View.Tree = xregbdrygui.TreeView( ... 'Parent', obj.Figure, ... 'MessageService', obj.MessageService ); % Create an InfoView to display information about the current constraint obj.View.Info = xregbdrygui.InfoView( ... 'Parent', obj.Figure, ... 'MessageService', obj.MessageService ); % Create an InfoView to display information about the current constraint obj.View.TestSelector = xregbdrygui.TestSelector( ... 'Parent', obj.Figure, ... 'MessageService', obj.MessageService ); end end % protected methods end % classdef %------------------------------------------------------------------------------| function i_BringFigureToFront( obj ) figure( obj.Figure ); end % i_BringFigureToFront %------------------------------------------------------------------------------| function state = i_AskAboutTheOneAndOnlyNode( root, leaf ) question = { sprintf( 'There is no boundary model set as best for the %s test plan.', name( root ) ) sprintf( 'Do you want to set %s as the best boundary model for this test plan?', name( leaf ) ) }; answer = questdlg( question, 'Boundary Model', 'Yes', 'No', 'Cancel', 'Yes' ); switch lower( answer ), case 'yes', % "Yes" means set the leaf node as best and proceed, i.e., close the % editor state = 'off'; pParent = Parent( leaf ); pParent.setbest( leaf ); % It could be that there is an extra layer between the leaf and the % root if pParent ~= address( root ), setbest( root, pParent ); end case 'no', % "No" means proceed without a best constraint, i.e., don't set a % best but close the editor state = 'off'; case 'cancel', state = 'on'; otherwise % Probably managed to "cancel" the dialog. This is a "no" state = 'on'; end end % i_AskAboutTheOneAndOnlyNode %------------------------------------------------------------------------------| function state = i_AskAboutLackOfBestConstraint( root ) question = { sprintf( 'There is no boundary model set as best for the %s test plan.', name( root ) ) 'Do you want to proceed without a boundary model for this test plan?' }; answer = questdlg( question, 'Boundary Model', 'Yes', 'No', 'Yes' ); switch lower( answer ), case 'yes', % "Yes" means proceed without a best constraint, i.e., close the % editor state = 'off'; case 'no', % "No" means don't proceed, i.e., keep the editor open state = 'on'; otherwise % Probably managed to "cancel" the dialog. This is a "no" state = 'on'; end end % i_AskAboutLackOfBestConstraint