www.gusucode.com > mbcdesign 工具箱 matlab 源码程序 > mbcdesign/+xregdesgui/SliceControl.m
classdef SliceControl < mbcgui.widget.BasicContainer %xregdesgui.SliceControl class % xregdesgui.SliceControl extends mbcgui.widget.BasicContainer % % xregdesgui.SliceControl properties: % Parent - Property is of type 'MATLAB array' % Position - Property is of type 'rect' % Enable - Property is of type 'on/off' % Visible - Property is of type 'on/off' % UserData - Property is of type 'MATLAB array' % Tag - Property is of type 'string' % Design - Property is of type 'MATLAB array' % NumAxes - Property is of type 'int' % Axes - Property is of type 'MATLAB array' % SlicePoint - Property is of type 'MATLAB array' % % xregdesgui.SliceControl methods: % canPrint - Check whether component can be printed % hasSlice - Check whether there is a valid slice defined % Copyright 2015-2016 The MathWorks, Inc. properties (AbortSet, SetObservable) %DESIGN Property is of type 'MATLAB array' Design = []; %NUMAXES Property is of type 'int' NumAxes = 2; %AXES Property is of type 'MATLAB array' Axes = [ 1, 2 ]; %SLICEPOINT Property is of type 'MATLAB array' SlicePoint = []; end properties (Access=protected, AbortSet) %HTABLE Property is of type 'handle' hTable = []; %HAXISCONTROLS Property is of type 'handle vector' hAxisControls = []; end events AxisChanged PointChanged end % events methods % constructor block function obj = SliceControl(varargin) %SLICECONTROL Constructor for slicecontrol object % SLICECONTROL(PROP, VALUE, ...) constructs a new slicecontrol object. obj@mbcgui.widget.BasicContainer(varargin{ : }); % converted super class constructor call hTopPanel = mbcgui.container.layoutpanel(... 'Parent', obj.Parent, ... 'BorderType', 'beveledout', ... 'LayoutBorder', [5 5 5 5]); hBottomPanel = mbcgui.container.layoutpanel(... 'Parent', obj.Parent, ... 'BorderType', 'beveledout', ... 'LayoutBorder', [5 5 5 5]); obj.hTable = mbcwidgets.VariableEditorTable( ... 'Parent', hTopPanel, ... 'ValueChangedCallback', @i_tableedited, ... 'ValueConstraint', 'plot'); obj.hAxisControls = i_makeaxislabels; % Create the layout hBottomGrid = xreggridbaglayout(hBottomPanel, ... 'packgroup', 'XREG_PERM_ON', ... 'dimension', [obj.NumAxes 1], ... 'rowsizes', repmat(21, 1, obj.NumAxes), ... 'gapy', 5, ... 'elements', num2cell(obj.hAxisControls)); set(hBottomPanel, 'LayoutComponent', {hBottomGrid}); set(hTopPanel, 'LayoutComponent', obj.hTable); obj.ContentHandle = xreggridbaglayout(obj.Parent, ... 'packgroup', 'XREG_PERM_ON', ... 'Dimension', [3 1], ... 'rowsizes', [50 -1 obj.NumAxes*26+7], ... 'mergeblock', {[1 2], [1 1]}, ... 'elements', {hTopPanel, [], hBottomPanel}, ... 'packstatus', 'on'); % Force update to match current settings obj.pCheckAxes; obj.pCheckPoint; obj.pDrawTable; obj.pDrawAxisSel; % Add listeners to properties obj.addPropertyListeners({'Design', 'NumAxes', 'Axes', 'SlicePoint'}, ... {@i_setdesign, @i_setnumaxes, @i_setaxes, @i_setpoint}); % Flag that controls whether listener events should execute any action DO_EVENT_CODE = true; function ctrl = i_makeaxislabels SC = mbcgui.util.SystemColorsDbl; AxisNames = {'X', 'Y', 'Z'}; ctrl = cell( 1, obj.NumAxes); for n = 1:obj.NumAxes hEdit = uicontrol('Parent', hBottomPanel, ... 'Style', 'popupmenu', ... 'String', {}, ... 'Value', 0, ... 'Tag',sprintf('SliceControl%d',n),... 'BackgroundColor', SC.WINDOW_BG, ... 'Callback', {@i_editaxis, n}); ctrl{n} = xregGui.labelcontrol('Parent', hBottomPanel, ... 'String', sprintf('%s-axis:', AxisNames{n}), ... 'LabelSize', 40, ... 'LabelSizeMode', 'absolute', ... 'ControlSize', 1, ... 'ControlSizeMode', 'relative', ... 'Control', hEdit); end ctrl = [ctrl{:}]; end function i_setdesign(src, evt) %#ok<INUSD> DO_EVENT_CODE = false; obj.pCheckAxes; obj.pCheckPoint; obj.pDrawTable; obj.pDrawAxisSel; DO_EVENT_CODE = true; end function i_setnumaxes(src, evt) %#ok<INUSD> % Reset to old value warning(message('mbc:xregdesgui:slicecontrol:InvalidPropertyValue1')); obj.NumAxes = length(obj.Axes); end function i_setaxes(src, evt) %#ok<INUSD> if DO_EVENT_CODE obj.pCheckAxes; obj.pDrawAxisSel; obj.pDrawTable; end end function i_setpoint(src, evt) %#ok<INUSD> if DO_EVENT_CODE obj.pCheckPoint; obj.pDrawTable; end end function i_tableedited(src, evt) %#ok<INUSL> row = evt.data.Rows; newval = zeros(length(row), 1); for n = 1:length(newval) newval(:) = evt.data.NewValue(n).getValue; end % Transform row so it is the correct factor index editfact = setdiff(1:length(obj.SlicePoint), obj.Axes); row = editfact(row); % Save change without causing a table redraw DO_EVENT_CODE = false; obj.SlicePoint(row) = newval; DO_EVENT_CODE = true; % Send a value change event data = struct('FactorIndex', row, 'NewValue', newval); obj.notify('PointChanged', xregEventData(data)); end function i_editaxis(src, evt, axis) %#ok<INUSL> NewAxisFactor = get(src, 'Value'); ax = obj.Axes; % Unset any axes that are already set to this factor. They will be % fixed by the Axes set listener. ax(ax==NewAxisFactor) = 0; ax(axis) = NewAxisFactor; obj.Axes = ax; % Send axis change event % Send a value change event data = struct('Axis', axis, 'NewFactor', NewAxisFactor); obj.notify('AxisChanged', xregEventData(data)); end end end % constructor block methods function set.NumAxes(obj,value) % DataType = 'int' validateattributes(value,{'numeric'},{'scalar'},'','NumAxes') value = round(value); % round to obtain an integer obj.NumAxes = i_checknumaxes(obj,value); end function set.hTable(obj,value) % DataType = 'handle' validateattributes(value,{'handle'}, {'scalar'},'','hTable') obj.hTable = value; end function set.hAxisControls(obj,value) % DataType = 'handle vector' validateattributes(value,{'handle'}, {'vector'},'','hAxisControls') obj.hAxisControls = value; end end % set and get functions methods % public methods %---------------------------------------- function out = canPrint(obj) %#ok<MANU> %CANPRINT Check whether component can be printed % CANPRINT(OBJ) returns true for slicecontrol objects. out = true; end % canPrint %---------------------------------------- function out = hasSlice(obj) %HASSLICE Check whether there is a valid slice defined % HASSLICE(OBJ) returns true if the control is defining a valid slice. % For this to be true the control must be displaying a design with enough % factors to have one per axis. out = ~isempty(obj.Design) && nfactors(obj.Design)>=obj.NumAxes; end % hasSlice %---------------------------------------- function pCheckAxes(obj) %PCHECKAXES Check that axis selection matches the number of axes % PCHECKAXES(OBJ) checks that the length of the Axes property matches the % setting of NumAxes and that all axes are different numbers. ax = obj.Axes; nAx = obj.NumAxes; if ~isempty(obj.Design) nF = nfactors(obj.Design); if nF<nAx ax = 1:nAx; else % Sort out length if length(ax)<nAx ax = [ax zeros(1, nAx-length(ax))]; elseif length(ax)>nAx ax = ax(1:nAx); end % Check all are unique. Used = false(1, nF); for n = 1:length(ax) if ax(n)~=0 if Used(ax(n)) % Find an unused axis number ax(n) = find(~Used, 1, 'first'); end % Mark as used Used(ax(n)) = true; end end % Find axes for any zeros nMissing = sum(ax==0); if nMissing>0 ax(ax==0) = find(~Used, nMissing, 'first'); end end else ax = 1:nAx; end obj.Axes = ax; end % pCheckAxes %---------------------------------------- function pCheckPoint(obj) %PCHECKPOINT Check that slice point value is valid % PCHECKPOINT(OBJ) checks that the slice point value is valid. If there % are too few values it will be reset to match the number of factors in % the design. if ~isempty(obj.Design) nf = nfactors(obj.Design); if nf~=length(obj.SlicePoint) obj.SlicePoint = invcode(model(obj.Design), midpoint(obj.Design)); end else obj.SlicePoint = []; end end % pCheckPoint %---------------------------------------- function pDrawAxisSel(obj) %PDRAWAXISSEL Update the axis selection gui elements % PDRAWAXISSEL(OBJ) updates the axis selection popups to display the % current axis settings and design factors. nf = length(obj.SlicePoint); if nf<obj.NumAxes % Set all controls to empty for n=1:obj.NumAxes set(obj.hAxisControls(n).Control, 'String', {''}, 'Value', 1); end set(obj.hAxisControls, 'Enable', 'off'); else names = factors(obj.Design); ax = obj.Axes; for n=1:obj.NumAxes set(obj.hAxisControls(n).Control, 'String', names, 'Value', ax(n)); end set(obj.hAxisControls, 'Enable', 'on'); end end % pDrawAxisSel %---------------------------------------- function pDrawTable(obj) %PDRAWTABLE Update the table of evaluation point numbers % PDRAWTABLE(OBJ) updates the table that contains the current evaluation % point. if ~isempty(obj.Design) vals = obj.SlicePoint; names = factors(obj.Design); if length(names)<length(obj.Axes) obj.hTable.setVariables({}, [], {}); else vals(obj.Axes) = []; names(obj.Axes) = []; obj.hTable.setVariables(names, ones(size(names)), num2cell(vals)); end else obj.hTable.setVariables({}, [], {}); end end % pDrawTable %---------------------------------------- function sz = printSize(obj) %PRINTSIZE Returns the preferred printing size for the component % SZ = PRINTSIZE(OBJ) returns a two element vector containing the % preferred width and height for printing the component. % Want enough height to print out the table values, no more. if isempty(obj.Design) n = 1; else nf = nfactors(obj.Design); n = max(1, nf-obj.NumAxes); end sz = [obj.Position(3), n*17+10]; end % printSize %---------------------------------------- function newobj = printCopy(obj, fig) %PRINTCOPY Create a new component for printing the component display % NEWOBJ = PRINTCOPY(OBJ, FIG) creates and returns a handle to a new % component, NEWOBJ, parented by the specified figure, FIG. The new % object will be used for printing a copy of the component OBJ. % Create a box containing details of non-axis variable values axwrap = mbcgui.widget.AxesContainer(... 'Parent',fig); axvar = axwrap.AxesHandle; set(axvar,... 'Color','none',... 'XLim',[0 1],... 'YLim',[-1 0],... 'XTick',[],... 'YTick',[],... 'Box','on',... 'Units','pixels', ... 'HandleVisibility', 'off'); if isempty(obj.Design) hExtObj = text('Parent',axvar,'Position',[0.5 0],... 'VerticalAlignment','top',... 'HorizontalAlignment','center',... 'FontAngle', 'italic', ... 'String','No design factors',... 'Clipping','on'); else nf = nfactors(obj.Design); numValues = nf-obj.NumAxes; if numValues==0 hExtObj = text('Parent',axvar,'Position',[0.5 0],... 'VerticalAlignment','top',... 'HorizontalAlignment','center',... 'FontAngle', 'italic', ... 'String','No additional factors',... 'Clipping','on'); else factind = setdiff(1:nf, obj.Axes); names = factors(obj.Design); values = obj.SlicePoint; valstr = cell(numValues,1); for n = 1:numValues valstr{n} = sprintf('%g', values(factind(n))); end text('Parent',axvar,'Position',[0.05 0],... 'VerticalAlignment','top',... 'HorizontalAlignment','left',... 'String',names(factind),... 'Clipping','on'); hExtObj = text('Parent',axvar,'Position',[0.5 0],... 'VerticalAlignment','top',... 'HorizontalAlignment','left',... 'String',repmat({':'}, numValues, 1),... 'Clipping','on'); text('Parent',axvar,'Position',[0.55 0],... 'VerticalAlignment','top',... 'HorizontalAlignment','left',... 'String',valstr,... 'Clipping','on'); end end oldunits = get(hExtObj, 'Units'); set(hExtObj, 'Units', 'pixels'); ext = get(hExtObj, 'Extent'); set(hExtObj, 'Units', oldunits); % Need to add a border to make the box properly visible newobj = xreggridbaglayout(fig, ... 'dimension', [1 1], ... 'rowsizes', ext(4)+2, ... 'elements', {axwrap}, ... 'border', [1 1 1 1]); end % printcopy end % public methods end % classdef function val = i_checknumaxes(obj, val) %#ok<INUSL> if val<2 || val>3 error(message('mbc:xregdesgui:slicecontrol:InvalidPropertyValue')); end end % i_checknumaxes