www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/cgcalmanager.m
function varargout = cgcalmanager(Action,varargin) %CGCALMANAGER GUI to manage importing cal files % % CGCALMANAGER(action,varargin) starts the calibration manager. % Copyright 2000-2015 The MathWorks, Inc. and Ford Global Technologies, Inc. switch lower(Action) case 'gethandle' varargout{1} = i_GetHandle; case 'precreate' varargout{1} = i_CreateFigure(true); % modal dialog case 'create' i_StartNoAction(varargin{:}); case 'choosefile' i_StartChooseFile(varargin{:}); case 'loadcal' i_StartLoadCalData(varargin{:}); % ---------------- Test functions ------------- case 'numnodes' fh = i_GetHandle; ud = get(fh,'UserData'); num(1) = length(ud.Hand.BlockList.findAllNodes)-1; num(2) = ud.Hand.ParamContents.getRowCount; varargout{1} = num; case 'testshow' fh = i_CreateFigure(false); % not modal, for test purposes set(fh,'Visible','on'); varargout{1}=fh; case 'testrun' fh = i_CreateFigure(false); % not modal, for test purposes c = cgbrowser; proj = c.RootNode; if nargin>1 % Select a given item i_StartNoAction(proj,'selectitem',varargin{1}); else i_StartNoAction(proj); end set(fh,'Visible','on'); end end % ---------------------------------------------- function h = i_GetHandle % ---------------------------------------------- h = findall(0,'Tag','CalManager'); if isempty(h) h = []; end h = mbcgui.hgclassesutil.toHandle(h); end % ---------------------------------------------- function fh = i_CreateFigure(modal) % ---------------------------------------------- % just incase we have a Calibration Manager hanging around somewhere fh=i_GetHandle; delete(fh); c = cgbrowser; fhWidth = 700; fhHeight = 600; if modal fh= xregdialog('visible','off',... 'renderer','painters',... 'Tag','CalManager',... 'name','Calibration Manager',... 'pointer','watch'); else fh= xregfigure('Visible','off',... 'Renderer','painters',... 'Tag','CalManager',... 'Name','Calibration Manager',... 'Pointer','watch'); end if c.GUIExists % Center on the browser window xregcenterfigure(fh, [fhWidth fhHeight], c.Figure); else set(fh, 'Position', [100 100 fhWidth fhHeight]); end % Hook into figure position persistence xregpersistfigpos(fh,'key','CalManager'); % Fields used to hold cal file contents and information ud.cal = []; ud.calfile = {}; % Field to track the source of current view: cal file or project item (or % neither). ud.displaysource = ''; ud.displayitem = null(xregpointer,0); % Fields for undo information ud.Undo.ptr = []; ud.Undo.obj = []; % GUI close callback function ud.closecallback = ''; % create the various panels [toolbar,ud]=i_CreateToolbar(fh,ud); [bottom,ud] = i_CreateBottomPanel(fh,ud); [link,ud] = i_CreateLinkPanel(fh,ud); [blocklist,ud] = i_CreateBlockListPanel(fh,ud); [calfile,ud] = i_CreateCalfilePanel(fh,ud); [display,ud] = i_CreateDisplayPanel(fh,ud); g = xreggridbaglayout(fh, 'dimension', [1 3], ... 'colsizes', [-1 70 -1], ... 'elements', {blocklist, link, calfile}); sp = xregsplitlayout(fh, ... 'dividerstyle', 'flat', ... 'dividerwidth', 4, ... 'orientation', 'ud', ... 'minwidth', [135 25], ... 'top', g, ... 'bottom', display); % create the main layout g2 = xreggridbaglayout(fh,'dimension',[3 1], ... 'rowsizes',[31 -1 25],... 'gapy',2, ... 'elements',{toolbar, sp, bottom}); fh.LayoutManager = g2; % Finish up set(g2,'packstatus','on','visible','on'); set(fh,'UserData',ud,'Pointer','arrow'); end %--------------------------- function [toolbarlayout,ud]=i_CreateToolbar(fh,ud) toolbarlayout = mbcgui.container.layoutpanel(... 'Parent', fh, ... 'BorderType', 'beveledin'); tb = xregGui.uitoolbar('Parent',toolbarlayout,... 'ResourceLocation',cgrespath); set(toolbarlayout, 'LayoutComponent', tb); tb.setRedraw(false); ud.Hand.ClearMenu = xregGui.uipushtool(tb,'ImageFile','new.bmp',... 'transparentcolor',[0 255 0], ... 'ClickedCallback',@i_Clear, ... 'Enable','off', ... 'TooltipString','Clear Calibration File'); xregGui.uipushtool(tb,'ImageFile','open.bmp',... 'transparentcolor',[0 255 0], ... 'ClickedCallback' , @i_LoadFile, ... 'TooltipString','Open Calibration File'); ud.Hand.PasteMenu = xregGui.uipushtool(tb,'ImageFile','paste.bmp',... 'transparentcolor',[0 255 0], ... 'TooltipString','Paste into Table', ... 'ClickedCallback',{@i_ApplyData, 'pastedata'}, ... 'Enable','off'); ud.Hand.InitMenu = xregGui.uipushtool(tb,'ImageFile','cgdsfilltable.bmp',... 'transparentcolor',[0 255 0], ... 'TooltipString','Set Up from Ascii File', ... 'ClickedCallback',{@i_ApplyData, 'asciifile'}, ... 'Enable','off'); ud.Hand.UndoMenu = xregGui.uipushtool(tb,'ImageFile','undo.bmp',... 'transparentcolor',[0 255 0], ... 'TooltipString','Undo', ... 'ClickedCallback',@i_Undo, ... 'Enable','off'); ud.Hand.RedoMenu = xregGui.uipushtool(tb,'ImageFile','redo.bmp',... 'transparentcolor',[0 255 0], ... 'TooltipString','Redo', ... 'ClickedCallback',@i_Redo, ... 'Enable','off'); cghelptoolbutton(tb,'CGCALMANAGER','tooltip','Calibration Manager Help'); tb.setRedraw(true); end %-------------------------------- function [panel,ud] = i_CreateBlockListPanel(fh,ud) panel = mbcgui.container.titlebarpanel(... 'Parent', fh, ... 'BarTitle', 'Project Calibration Items', ... 'FocusAppearance', 'off'); % tree control tree = mbctreeadapter.CageTree('Parent',panel,... 'SelectionChangedCallback',@i_TreeCallback,... 'Editable',false); ud.Hand.BlockList = tree; % Table initialisation controls below the tree SizePanel = mbcgui.container.layoutpanel(... 'Parent', panel, ... 'BorderType', 'beveledout'); ud.Hand.EditXSize = mbcgui.widget.Spinner('Parent', SizePanel, ... 'Min', 0, ... 'Rule', 'int', ... 'Callback',@i_EditSize, ... 'Enable','off'); ud.Hand.ManTextX = xregGui.labelcontrol('parent',SizePanel, ... 'string','Rows: ',... 'LabelAlignment','left', ... 'LabelSizeMode', 'Absolute', ... 'LabelSize', 50, ... 'gap',5,... 'ControlSize',50, ... 'control', ud.Hand.EditXSize); ud.Hand.EditYSize = mbcgui.widget.Spinner('Parent', SizePanel, ... 'Min', 0, ... 'Rule', 'int', ... 'Callback',@i_EditSize, ... 'Enable','off'); ud.Hand.ManTextY = xregGui.labelcontrol('parent',SizePanel, ... 'string','Columns: ',... 'LabelAlignment','left', ... 'LabelSizeMode', 'Absolute', ... 'LabelSize', 50, ... 'gap',5,... 'ControlSize',50, ... 'control', ud.Hand.EditYSize); ud.Hand.EditValue = mbcgui.widget.Spinner('Parent', SizePanel, ... 'Enable','off'); ud.Hand.ValueLabel = xregGui.labelcontrol('parent',SizePanel, ... 'string', 'Value:',... 'LabelAlignment','left', ... 'LabelSizeMode', 'Absolute', ... 'LabelSize', 35, ... 'gap',5,... 'ControlSize',70, ... 'control', ud.Hand.EditValue); ud.Hand.SetSizeButton = uicontrol('Parent', SizePanel, ... 'Style','pushbutton',... 'String','Apply',... 'Callback',@i_ApplySize,'Enable','off'); PrecPanel = mbcgui.container.layoutpanel(... 'Parent', panel, ... 'BorderType', 'beveledout'); ud.Hand.PrecisionLabel = uicontrol('Parent', PrecPanel,... 'Style','text',... 'HorizontalAlignment','left',... 'String','Precision: '); ud.Hand.SetPropsButton = uicontrol('Parent', PrecPanel, ... 'Style','pushbutton',... 'String','Edit Precision...',... 'Callback',@i_PrecEdit,'Enable','off'); grd1 = xreggridbaglayout(SizePanel, ... 'dimension', [5 4], ... 'rowsizes', [20 5 2 20 3], ... 'colsizes', [105 90 -1 65], ... 'gapx', 10, ... 'border', [5 5 5 5], ... 'mergeblock', {[3 5], [4 4]}, ... 'mergeblock', {[1 1], [2 4]}, ... 'elements', {ud.Hand.ManTextX, [], [], ud.Hand.ManTextY, [], ... ud.Hand.ValueLabel, [], [], [], [], ... [], [], [], [], [], ... [], [], ud.Hand.SetSizeButton}); set(SizePanel, 'LayoutComponent', {grd1}); grd2 = xreggridbaglayout(PrecPanel, ... 'dimension', [2 2], ... 'gapy', 5, ... 'gapx', 5, ... 'border', [5 5 5 3], ... 'rowsizes', [-1 25], ... 'colsizes', [-1 85], ... 'mergeblock',{[1 2], [1 1]}, ... 'elements', {ud.Hand.PrecisionLabel, [], [], ud.Hand.SetPropsButton}); set(PrecPanel, 'LayoutComponent', {grd2}); grid = xreggridbaglayout(panel, ... 'dimension',[3,1], ... 'rowsizes',[-1 62 48], ... 'elements', {ud.Hand.BlockList, SizePanel, PrecPanel}); set(panel,'ContentHandle',{grid}); ud.Hand.ProjectPanel = panel; end %------------------------------ function [g1,ud] = i_CreateLinkPanel(fh,ud) ud.Hand.LinkButton = uicontrol('Parent', fh, ... 'Style','pushbutton',... 'Callback',@i_Link,... 'Enable', 'off', ... 'String','<-----------',... 'TooltipString','Set Up from Selected Calibration File Item'); ud.Hand.AutoLinkButton = uicontrol('Parent', fh, ... 'Style','pushbutton',... 'Callback',@i_AutoLink,... 'Enable', 'off', ... 'String',' <-- Auto --',... 'TooltipString','Set Up All Matching Calibration File Items'); g1 = xreggridlayout(fh, ... 'dimension',[4 1], ... 'correctalg','on',... 'rowsizes',[-1 25 25 -1], ... 'rowratios', [1 0 0 2], ... 'gap',10, ... 'border', [2 0 2 0], ... 'elements',{[],ud.Hand.LinkButton,ud.Hand.AutoLinkButton}); end %------------------------------- function [bottom,ud] = i_CreateBottomPanel(fh,ud) ud.Hand.Close = uicontrol('Parent', fh,... 'Style','push',... 'Callback','close(gcbf)',... 'String','Close'); MessagePanel = mbcgui.container.layoutpanel( ... 'Parent', fh, ... 'BorderType', 'beveledin', ... 'LayoutBorder', [2 0 2 4]); ud.Hand.Message = uicontrol('Parent', MessagePanel,... 'Style','text',... 'HorizontalAlignment','left',... 'Enable', 'inactive', ... 'String',''); set(MessagePanel, 'LayoutComponent', ud.Hand.Message); bottom= xreggridbaglayout(fh, ... 'dimension',[1 2],... 'colsizes',[-1 65], ... 'gapx', 7, ... 'elements',{MessagePanel, ud.Hand.Close}); end %--------------------------------- function [display,ud] = i_CreateDisplayPanel(fh,ud) display = mbcgui.container.titlebarpanel(... 'Parent', fh,... 'BarTitle','Display'); ud.Hand.TableWrapper = mbcwidgets.Table2D('numeric', ... 'parent', display); ud.Hand.TableWrapper.Peer.setBorder([]); set(display,'ContentHandle',ud.Hand.TableWrapper); ud.Hand.TableTitle = display; end %--------------------------------- function [grid,ud] = i_CreateCalfilePanel(fh,ud) %draw listview control toppanel = mbcgui.container.titlebarpanel(... 'Parent', fh, ... 'BarTitle', 'Calibration File Contents', ... 'FocusAppearance', 'off'); h = mbcwidgets.List( 'Parent', toppanel,... 'Editable', false, ... 'SelectionChangedCallback',@i_ListCallback,... 'SelectionMode', 'SingleRow'); h.Peer.setColumnData({'Name','Size'}); h.Peer.setColumnWidths([180,60]); h.Peer.setBorder([]) ud.Hand.ParamContents = h; set(toppanel,'ContentHandle', h); bottompanel = mbcgui.container.titlebarpanel(... 'Parent', fh, ... 'BarTitle','Calibration File Information'); % Info pane for displaying file information ud.Hand.CalFileInfo = mbcgui.table.InfoPane('Parent', bottompanel); set(bottompanel,'ContentHandle', ud.Hand.CalFileInfo); grid = xreggridbaglayout(fh, ... 'dimension',[2 1], ... 'gapy', 2, ... 'rowsizes',[-1 110],... 'elements', {toppanel, bottompanel}); ud.Hand.FilePanel = toppanel; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % FINISH % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_Finish(src,evt) % Pass notification on fh = i_GetHandle; set(fh, 'Visible', 'off'); drawnow('expose'); ud = get(fh, 'UserData'); xregcallback(ud.closecallback, fh, []); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % i_FillValuePane % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_FillValuePane % Update the information in the table fh = i_GetHandle; ud = get(fh,'UserData'); tw = ud.Hand.TableWrapper; if isempty(ud.displaysource) % No valid object selected tw.Peer.clearTable; set(ud.Hand.TableTitle,'BarTitle','No item selected'); i_Message('Please select an item'); set(ud.Hand.ProjectPanel, 'FocusAppearance', 'off'); set(ud.Hand.FilePanel, 'FocusAppearance', 'off'); else if strcmp(ud.displaysource, 'project') % Calibratable object obj = ud.displayitem; mtableview(obj.info,tw); set(ud.Hand.TableTitle,'BarTitle',['Project item: ',obj.getname]); set(ud.Hand.ProjectPanel, 'FocusAppearance', 'on'); set(ud.Hand.FilePanel, 'FocusAppearance', 'off'); else obj = ud.displayitem; if length(obj) > 1 obj = obj(1); end N = obj.name; set(ud.Hand.TableTitle,'BarTitle',['Calibration File: ',N]); switch obj.numaxes case 3 S = size(obj.data.Z); if isfield(obj.data,'X') X = obj.data.X; Y = obj.data.Y; else X = 0:S(2)-1; Y = 0:S(1)-1; end tw.Peer.setData(obj.data.Z, X, Y); tw.Peer.setCornerAsBlank; tw.ShowColumnHeader = true; tw.ShowRowHeader = true; tw.ShowHeaderSelection = true; case 2 tw.Peer.setData([obj.data.X(:) obj.data.Y(:)], {'Input','Output'}); tw.ShowColumnHeader = true; tw.ShowRowHeader = false; tw.ShowHeaderSelection = false; case 1 tw.Peer.setData(obj.data.X, {obj.name}); tw.ShowColumnHeader = true; tw.ShowRowHeader = false; tw.ShowHeaderSelection = false; otherwise tw.Peer.clearTable; end set(ud.Hand.ProjectPanel, 'FocusAppearance', 'off'); set(ud.Hand.FilePanel, 'FocusAppearance', 'on'); end i_Message(''); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Make Cal file contents window % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_FillCalFilePane fh = i_GetHandle; ud = get(fh,'UserData'); list_data = {'Calibration files';... 'Total number of items'; ... 'Number of 2D tables'; ... 'Number of 1D tables'; ... 'Number of scalar items'}; if isempty(ud.cal) % clear listbox and all text fields list_str = cell(length(list_data),2); list_str(:,1) = list_data; list_str(:,2) = {''}; ud.Hand.CalFileInfo.ListText = list_str; set(ud.Hand.ClearMenu, 'Enable', 'off'); set([ud.Hand.AutoLinkButton; ud.Hand.LinkButton], 'Enable', 'off'); % clear table ud.Hand.ParamContents.Peer.setData([]); else set(fh,'Pointer','watch'); % Add items to list and count each type at the same time nScalar = 0; n1D = 0; n2D = 0; Data = cell(length(ud.cal),2); Icon = cell(length(ud.cal),1); for n = 1:length(ud.cal) Data{n,1} = ud.cal(n).name; switch ud.cal(n).numaxes case 3 Icon{n} = cgrespath('cgfulltable.bmp'); n2D = n2D + 1; sizestr = sprintf('%d x %d', ud.cal(n).numrows, ud.cal(n).numcols); case 2 Icon{n} = cgrespath('cgfullfunction.bmp'); n1D = n1D + 1; sizestr = sprintf('%d', ud.cal(n).numrows); case 1 Icon{n} = cgrespath('cgcontconst.bmp'); nScalar = nScalar + 1; sizestr = ''; end Data{n,2} = sizestr; end ud.Hand.ParamContents.Peer.setData(Data,Icon); % Generate information strings Nfiles = length(ud.calfile); list_str = cell(length(list_data)+Nfiles-1,2); list_str(1,1) = list_data(1); list_str((end-length(list_data)+2):end,1) = list_data(2:end); for n = 1:Nfiles [unused, file, ext] = fileparts(ud.calfile{n}); list_str{n,2} = [file ext]; end list_str{Nfiles+1,2} = sprintf('%d', nScalar + n1D + n2D); list_str{Nfiles+2,2} = sprintf('%d', n2D); list_str{Nfiles+3,2} = sprintf('%d', n1D); list_str{Nfiles+4,2} = sprintf('%d', nScalar); ud.Hand.CalFileInfo.ListText = list_str; % Enable the clear menu button set(ud.Hand.ClearMenu, 'Enable', 'on'); set([ud.Hand.AutoLinkButton; ud.Hand.LinkButton], 'Enable', 'on'); set(fh,'Pointer','arrow'); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Set up Cal item tree % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_RefreshTree(pPROJ) fh = i_GetHandle; ud = get(fh,'UserData'); h = ud.Hand; PROJ = pPROJ.info; % Compile block list and disable manual set (there will be no selected item) h.BlockList.TypeFilter = cgtypes.cgtabletype; refresh( h.BlockList, pPROJ ); % Explicitly add any cgconstants to the tree. We only expect to find these in % featurenodes. F = filterbytype(PROJ, cgtypes.cgfeaturetype); for n = 1:length(F) F{n} = getconstants(F{n})'; end C = unique([F{:}]); if ~isempty(C) add( h.BlockList, C, pPROJ,0 ); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Set up Cal item size pane % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_FillCalItemPane fh = i_GetHandle; ud = get(fh,'UserData'); if ~strcmp(ud.displaysource, 'project') % Disable all table property editing devices editEn = {'off';'off';'off'}; applyEn = 'off'; % Disable precision panel precEn = 'off'; precStr = ''; % Set editors to zeros xyMin = {0; 0}; xyzVals = {0; 0; 0}; else obj = ud.displayitem; item = obj.info; precEn = 'on'; precStr = char(get(item, 'precision')); if isa(item, 'cgconstant') editEn = {'off';'off';'on'}; applyEn = 'on'; xyMin = {1; 1}; xyzVals = {1; 1; getvalue(item)}; else editEn = {'off';'off';'off'}; applyEn = 'off'; xyMin = {0; 0}; xyzVals = {0; 0; 0}; % Work out whether sizes can be altered if ~issizelocked(item) if isa(item, 'cglookuptwo') editEn{1} = 'on'; editEn{2} = 'on'; elseif isa(item, 'cgnormfunction') editEn{1} = 'on'; elseif isa(item, 'cgnormaliser') % Need to check whether the parent is a lookupone (no % changes allowed in this case parents = get(item, 'flist'); if ~(length(parents)==1 && parents(1).isa('cglookupone')) editEn{1} = 'on'; end end end % Get actual sizes and min values % Also get default init value and whether value editor is enabled V = get(item, 'values'); sz = size(V); if isa(item, 'cglookuptwo') if ~isempty(V) xyzVals = {sz(1); sz(2); round(mean(V(:)))}; xyMin = {2; 2}; applyEn = 'on'; end editEn{3} = 'on'; elseif isa(item, 'cgnormfunction') if ~isempty(V) xyzVals = {sz(1); 2; round(mean(V(:)))}; xyMin = {2; 0}; applyEn = 'on'; else xyzVals{2} = 2; end editEn{3} = 'on'; elseif isa(item, 'cgnormaliser') if ~isempty(V) xyzVals{1} = sz(1); xyzVals{2} = 2; xyMin = {2; 0}; applyEn = 'on'; else xyzVals{2} = 2; end end end end % Disable Apply button if no editing is allowed or if a zero size is % currently set set(ud.Hand.SetSizeButton, 'Enable', applyEn); % Set size/value editors to appropriate state set([ud.Hand.EditXSize; ud.Hand.EditYSize], {'Min'}, xyMin); set([ud.Hand.EditXSize; ud.Hand.EditYSize; ud.Hand.EditValue], {'Value'}, xyzVals); set([ud.Hand.ManTextX; ud.Hand.ManTextY; ud.Hand.ValueLabel] , {'Enable'}, editEn); % Set precision panel to appropriate state set([ud.Hand.PrecisionLabel; ud.Hand.SetPropsButton], 'Enable', precEn); set(ud.Hand.PrecisionLabel, 'String', ['Precision: ' precStr]); % Set clipboard/ascii enable state off if no editors are enabled if all(strcmp(editEn, 'off')) set([ud.Hand.PasteMenu, ud.Hand.InitMenu], 'Enable', 'off'); else set([ud.Hand.PasteMenu, ud.Hand.InitMenu], 'Enable', 'on'); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Load calibration info from a file % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function OK = i_ChooseFile OK = true; % Let the user choose what to import inputObj = cgcalinput; [inputObj, calinfo] = gui_import( inputObj ); % calinfo is empty if the user aborted etc if isempty(calinfo) OK = false; else i_LoadCalData(inputObj, calinfo); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Load calibration data into the tool % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_LoadCalData(calobj, calinfo) fh = i_GetHandle; set(fh,'Pointer','watch'); ud = get(fh,'UserData'); calfile = get(calobj, 'SourceString'); if isempty(ud.cal) ud.cal = calinfo; ud.calfile = {calfile}; else % Check for name matches and if there are any then keep new info L = length(calinfo); names = lower({ud.cal.name}); NewNames = lower({calinfo.name}); % Replacements [unused, iNew, iOld] = intersect(NewNames, names); ud.cal(iOld) = calinfo(iNew); % Additions iNew = setdiff(1:L, iNew); ud.cal = [ud.cal, calinfo(iNew)]; ud.calfile = [ud.calfile, {calfile}]; end set(fh,'UserData',ud); set(fh,'Pointer','arrow'); figure(fh) end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Programmatically select a tree node % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function NODE_FOUND = i_SelectTreeNode(pItem) % Attempt to find the tree node corresponding to the pointer pItem fh = i_GetHandle; ud = get(fh,'UserData'); if nargin % Look for a node corresponding to the given item select(ud.Hand.BlockList,pItem,false) NODE_FOUND = isequal(pItem,ud.Hand.BlockList.Selected); else % Select the first node on tree ch = ud.Hand.BlockList.getChildren(ud.Hand.BlockList.Root); NODE_FOUND=~isempty(ch); if NODE_FOUND select(ud.Hand.BlockList,ch(1),false) end end if NODE_FOUND pItem = ud.Hand.BlockList.Selected; if pItem.isa('cgcontainer') pItem = pItem.getdata; end ud.displaysource = 'project'; ud.displayitem = pItem; set([ud.Hand.PasteMenu, ud.Hand.InitMenu], 'Enable', 'on'); else ud.displaysource = ''; ud.displayitem = null(xregpointer, 0); set([ud.Hand.PasteMenu, ud.Hand.InitMenu], 'Enable', 'off'); end set(fh, 'UserData', ud); i_FillCalItemPane; i_FillValuePane; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Message % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_setCloseCallback(cb) fh = i_GetHandle; ud = get(fh,'UserData'); ud.closecallback = cb; set(fh, 'UserData', ud); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Message % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_Message(str) fh = i_GetHandle; ud = get(fh,'UserData'); if isempty(str) % Construct a default string giving the user some info on the selected % object if strcmp(ud.displaysource, 'project') if ud.displayitem.isa('cglookuptwo') NR = size(ud.displayitem.get('values'), 1); NC = size(ud.displayitem.get('values'), 2); str = sprintf('(%d x %d) 2D table', NR, NC); if ud.displayitem.issizelocked str = [str '. The size of this item has been locked.']; end elseif ud.displayitem.isa('cgconstant') str = 'Scalar item'; else NR = size(ud.displayitem.get('values'), 1); str = sprintf('%d element 1D table', NR); if ud.displayitem.issizelocked str = [str '. The size has been locked.']; end end elseif strcmp(ud.displaysource, 'calfile') switch ud.displayitem.numaxes case 3 str = sprintf('(%d x %d) 2D table', ud.displayitem.numrows, ud.displayitem.numcols); case 2 str = sprintf('%d element 1D table', ud.displayitem.numrows); otherwise str = 'Scalar item'; end end end set(ud.Hand.Message,'String',str); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Set up undo store % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_SetForUndo(ptr) fh = i_GetHandle; ud = get(fh,'UserData'); if isempty(ptr) % Clear the undo buffer ud.Undo.obj = []; ud.Undo.ptr = []; set([ud.Hand.UndoMenu ud.Hand.RedoMenu],'Enable','off'); else % Setup the undo buffer ud.Undo.ptr = ptr; if length(ptr)==1 ud.Undo.obj = {info(ptr)}; else ud.Undo.obj = info(ptr); end set([ud.Hand.UndoMenu ud.Hand.RedoMenu],{'Enable'},{'on'; 'off'}); end set(fh,'UserData',ud); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Undo % % The Undo store is also used as the redo store % % There is only one level of undo but more than % % one object may need undo'ing hence the loop % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_PerformUndo fh = i_GetHandle; ud = get(fh,'UserData'); if ~isempty(ud.Undo.ptr) && (length(ud.Undo.ptr) == length(ud.Undo.obj)) for n = 1:length(ud.Undo.ptr) obj = ud.Undo.obj{n}; ud.Undo.obj{n} = ud.Undo.ptr(n).info; % store redo/undo object ud.Undo.ptr(n).info = obj; % Perform the undo/redo end set(fh,'UserData',ud); i_RefreshIcons; i_FillValuePane; else i_SetForUndo([]); set([ud.Hand.RedoMenu ud.Hand.UndoMenu],'Enable','off'); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Only refresh the icons, not the structure % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function i_RefreshIcons fh = i_GetHandle; ud = get(fh,'UserData'); h = ud.Hand; updateAll(h.BlockList); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Transfer data from a load structure % % to a calibration item % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [status, msg] = i_TransferToTable(pItem, Vstruct) % Vstruct is a structure containing the fields: % name % description % info % data % numaxes % numrows % numcols % % The data field may contain a combination of X/Y/Z fields. This structure % is the same as that used by cgcalinput. (X is the column normaliser % breakpoints, Y the row ones) % % status is a numeric code indicating the outcome of the operation: % 0 means the operation was successful % 1 means the data didn't match the type of object in pItem % 2 means the size of the data caused a problem % 3 means that the expression object rejected the data for % some reason (e.g. because of non-increasing breakpoints) % % If the inputs are vectors then the status and msg outputs will be a % vector and cell array respectively. Nitems = length(Vstruct); status = zeros(1, Nitems); msg = repmat({''}, 1, Nitems); pItem = pItem(:)'; LUobj = infoarray(pItem); % vectors to hold undo information for any other objects that are altered % (normalisers, for example) pAdditional = null(xregpointer, 0); objAdditional = {}; function chk = isInMainList(ptr) % Check whether pointer is in main transfer list chk = ismember(ptr, pItem); end function obj = i_getObjectForPtr(ptr) % Return the object for a pointer. idx = findptrs(ptr, pItem); if idx==0 idx = findptrs(ptr, pAdditional); if idx==0 obj = ptr.info; pAdditional(end+1) = ptr; objAdditional{end+1} = obj; else obj = objAdditional{idx}; end else obj = LUobj{idx}; end end function i_setObjectForPtr(ptr, obj) % Save the updated object for a pointer idx = findptrs(ptr, pItem); if idx==0 idx = findptrs(ptr, pAdditional); if idx==0 pAdditional(end+1) = ptr; objAdditional{end+1} = obj; else objAdditional{idx} = obj; end else LUobj{idx} = obj; end end for n = 1:Nitems % Check that the data in Vstruct matches the type of object in pItem itemAxes = 2; if isa(LUobj{n}, 'cglookuptwo') itemAxes = 3; elseif isa(LUobj{n}, 'cgconstant') itemAxes = 1; end if itemAxes~=Vstruct(n).numaxes status(n) = 1; msg{n} = 'Incorrect data type for object.'; continue end % Size checking is rolled together with actually changing the data as % they are both dependent on the type of object being used if isa(LUobj{n}, 'cgconstant') if Vstruct(n).numrows==1 && Vstruct(n).numcols==1 LUobj{n} = setvalue(LUobj{n}, Vstruct(n).data.X); else status(n) = 2; msg{n} = 'Calibration constants can only be filled with a scalar value.'; end else if isa(LUobj{n}, 'cglookuptwo') objSize = size(get(LUobj{n}, 'values')); if all(size(Vstruct(n).data.Z)>=2) ok = i_sizecheck(objSize, size(Vstruct(n).data.Z), issizelocked(LUobj{n}), getname(LUobj{n})); if ok try LUobj{n} = set(LUobj{n},'matrix',{Vstruct(n).data.Z Vstruct(n).info}); % Check whether normalisers should be set up if length(Vstruct(n).data.X)>=2 pX = get(LUobj{n}, 'x'); if ~isInMainList(pX) X = i_getObjectForPtr(pX); ok = i_sizecheck(length(get(X,'values')), length(Vstruct(n).data.X), issizelocked(X), getname(X)); if ok nBP = length(Vstruct(n).data.X); NewMat = [Vstruct(n).data.X(:) (0:nBP-1)']; X = set(X, 'matrix',{NewMat Vstruct(n).info},... 'description',''); i_setObjectForPtr(pX, X); end end end if length(Vstruct(n).data.Y)>=2 pY = get(LUobj{n}, 'y'); if ~isInMainList(pY) Y = i_getObjectForPtr(pY); ok = i_sizecheck(length(get(Y,'values')), length(Vstruct(n).data.Y), issizelocked(Y), getname(Y)); if ok nBP = length(Vstruct(n).data.Y); NewMat = [Vstruct(n).data.Y(:) (0:nBP-1)']; Y = set(Y, 'matrix',{NewMat Vstruct(n).info},... 'description',''); i_setObjectForPtr(pY, Y); end end end catch ME [unused, unused, x] = mbcGetLastError(ME,'MessageFormat', 'singleline'); status(n) = 3; msg{n} = ['Error copying values: ' x]; end end else status(n) = 2; msg{n} = 'Table must be at least (2x2) elements.'; end elseif isa(LUobj{n}, 'cglookupone') objSize = size(get(LUobj{n}, 'values')); if length(Vstruct(n).data.X) == length(Vstruct(n).data.Y) ... && length(Vstruct(n).data.X)>=2 ok = i_sizecheck(objSize(1), length(Vstruct(n).data.X), issizelocked(LUobj{n}), getname(LUobj{n})); if ok try LUobj{n} = set(LUobj{n}, 'matrix', {[Vstruct(n).data.X(:) Vstruct(n).data.Y(:)] Vstruct(n).info}); catch ME [unused, unused, x] = mbcGetLastError(ME,'MessageFormat', 'singleline'); status(n) = 3; msg{n} = ['Error copying values: ' x]; end else status(n) = 2; msg{n} = 'Unable to change size of table.'; end else status(n) = 2; msg{n} = 'X and Y columns must be the same length and have at least 2 elements.'; end elseif isa(LUobj{n}, 'cgnormfunction') objSize = size(get(LUobj{n}, 'values')); if length(Vstruct(n).data.Y)>=2 ok = i_sizecheck(objSize(1), length(Vstruct(n).data.Y), issizelocked(LUobj{n}), getname(LUobj{n})); if ok try LUobj{n} = set(LUobj{n},'matrix',{Vstruct(n).data.Y(:) Vstruct(n).info}); % Check whether normalisers should be set up if length(Vstruct(n).data.X)>=2 pX = get(LUobj{n}, 'x'); if ~isInMainList(pX) X = i_getObjectForPtr(pX); ok = i_sizecheck(length(get(X,'values')), length(Vstruct(n).data.X), issizelocked(X), getname(X)); if ok nBP = length(Vstruct(n).data.Y); NewMat = [Vstruct(n).data.X(:) (0:nBP-1)']; X = set(X, 'matrix',{NewMat Vstruct(n).info},... 'description',''); i_setObjectForPtr(pX, X); end end end catch ME [unused, unused, x] = mbcGetLastError(ME,'MessageFormat', 'singleline'); status(n) = 3; msg{n} = ['Error copying values: ' x]; end end else status(n) = 2; msg{n} = 'Table must be at least 2 elements long.'; end elseif isa(LUobj{n}, 'cgnormaliser') objSize = size(get(LUobj{n}, 'values')); if isempty(Vstruct(n).data.Y) Vstruct(n).data.Y = (0:Vstruct(n).numrows-1)'; end if length(Vstruct(n).data.X) == length(Vstruct(n).data.Y) ... && length(Vstruct(n).data.X)>=2 ok = i_sizecheck(objSize(1), length(Vstruct(n).data.X), issizelocked(LUobj{n}), getname(LUobj{n})); if ok try LUobj{n} = set(LUobj{n}, 'matrix', {[Vstruct(n).data.X(:) Vstruct(n).data.Y(:)] Vstruct(n).info}); catch ME [unused, unused, x] = mbcGetLastError(ME,'MessageFormat', 'singleline'); status(n) = 3; msg{n} = ['Error copying values: ' x]; end else status(n) = 2; msg{n} = 'Unable to change size of normalizer.'; end else status(n) = 2; msg{n} = 'X and Y columns must be the same length and have at least 2 elements.'; end end if ~any(strcmp(Vstruct(n).name, {'asciifile', 'pastedata', 'manualreset'})) % Set new description if data is from a calfile LUobj{n} = set(LUobj{n}, 'description', Vstruct(n).description); end end end % Place the items that worked into the undo store, then update the pointers % with the new copies itemsUpdated = (status==0); i_SetForUndo([pItem(itemsUpdated), pAdditional]); passign([pItem(itemsUpdated), pAdditional], [LUobj(itemsUpdated), objAdditional]); end function ok = i_sizecheck(oldSize, newSize, islocked, name) if all(oldSize==newSize) || all(oldSize==0) ok = true; else if islocked h = errordlg(sprintf('The size of %s has been locked and cannot be altered.', name), ... 'MBC Toolbox', 'modal'); waitfor(h); ok = false; else x = questdlg(sprintf('This operation will change the size of %s. Do you want to continue?', name), ... 'MBC toolbox', 'Continue', 'Cancel', 'Continue'); if strcmp(x, 'Continue') ok = true; else ok = false; end end end end %-------------------------------------- % Callback from clicking item on the tree %-------------------------------------- function i_TreeCallback(C, evt) %-------------------------------------- % Retrieve pointer to object from the node's key pNode = evt.Data.NewNode; if pNode.isa('cgnode') if pNode==pNode.root if ~isempty(evt.Data.OldNode) select(C,evt.Data.OldNode); end return end if pNode.isa('cgcontainer') pNode = pNode.getdata; end end fh = i_GetHandle; ud = get(fh,'UserData'); if ~strcmp(ud.displaysource, 'project') ... || isempty(ud.displaysource) ... || ud.displayitem~=pNode ud.displaysource = 'project'; ud.displayitem = pNode; set(fh, 'UserData', ud); i_FillCalItemPane; i_FillValuePane; end end %-------------------------------------- % Callback from clicking item on the list %-------------------------------------- function i_ListCallback(src, evt) %-------------------------------------- % Retrieve index to information from the item's key idx = src.getSelectedRows; fh = i_GetHandle; ud = get(fh,'UserData'); if ~isempty(idx) && (~strcmp(ud.displaysource, 'calfile') ... || isempty(ud.displaysource) ... || ~strcmp(ud.displayitem.name, ud.cal(idx).name)) ud.displaysource = 'calfile'; ud.displayitem = ud.cal(idx); set(fh, 'UserData', ud); i_FillCalItemPane; i_FillValuePane; % Disable value import from ascii file and clipboard set([ud.Hand.PasteMenu, ud.Hand.InitMenu], 'Enable', 'off'); end end %-------------------------------------- % Callback from changing size value %-------------------------------------- function i_EditSize(src,evt) %-------------------------------------- % Make sure the min of an edited size is 2 src.Min = 2; % Enable apply if it was disabled fh = i_GetHandle; ud = get(fh, 'UserData'); if get(ud.Hand.EditXSize, 'Value')>0 && get(ud.Hand.EditYSize, 'Value')>0 set(ud.Hand.SetSizeButton, 'Enable', 'on'); end end %-------------------------------------- % Callback from Precision button %-------------------------------------- function i_PrecEdit(src, evt) %-------------------------------------- %Handles clicks on tree fh = i_GetHandle; ud = get(fh,'UserData'); if strcmp(ud.displaysource, 'project') obj = ud.displayitem; prec = obj.get('precision'); [prec, ok] = guiChooserEditor(prec, 'Parent', fh); if ok obj.info = obj.set('Precision', prec); i_FillCalItemPane; i_FillValuePane; end end end %-------------------------------------- % Callback from File loading button %-------------------------------------- function i_LoadFile(src, evt) %-------------------------------------- OK = i_ChooseFile; if OK i_FillCalFilePane; end end %-------------------------------------- % Clear Cal File %-------------------------------------- function i_Clear(src,evt) %-------------------------------------- fh = i_GetHandle; ud = get(fh,'UserData'); ud.cal = []; ud.calfile = {}; if strcmp(ud.displaysource, 'calfile') ud.displaysource = ''; ud.displayitem = null(xregpointer, 0); end set(fh,'UserData',ud); % Update the cal file info pane i_FillCalFilePane; % Update rest of gui i_FillCalItemPane; i_FillValuePane; end %-------------------------------------- % Undo operation %-------------------------------------- function i_Undo(src,evt) %-------------------------------------- fh = i_GetHandle; ud = get(fh,'UserData'); set([ud.Hand.UndoMenu ud.Hand.RedoMenu],{'Enable'},{'off'; 'on'}); i_PerformUndo end %-------------------------------------- % Redo operation %-------------------------------------- function i_Redo(src,evt) %-------------------------------------- fh = i_GetHandle; ud = get(fh,'UserData'); set([ud.Hand.UndoMenu ud.Hand.RedoMenu],{'Enable'},{'on'; 'off'}); i_PerformUndo end %-------------------------------------- % Apply size/value to table %-------------------------------------- function i_ApplySize(src,evt) %-------------------------------------- fh = i_GetHandle; ud = get(fh,'UserData'); if strcmp(ud.displaysource, 'project') % Set up an appropriate data structure according to the type of object % selected and then use subfunction to perform copy V = struct('name', 'manualreset', ... 'description', '', ... 'info', 'Manually initialised from Calibration Manager', ... 'data',[], ... 'numaxes',[], ... 'numrows',[], ... 'numcols',[]); obj = ud.displayitem.info; if isa(obj, 'cglookuptwo') V.numrows = ud.Hand.EditXSize.Value; V.numcols = ud.Hand.EditYSize.Value; V.data.Z = ud.Hand.EditValue.Value*ones(V.numrows, V.numcols); V.numaxes = 3; % Look to see whether both normalisers are empty - if they are then % we'll initialise them too pX = get(obj, 'x'); pY = get(obj, 'y'); if pX.isempty && pY.isempty V.data.X = 0:V.numcols-1; V.data.Y = 0:V.numrows-1; else V.data.X = []; V.data.Y = []; end elseif isa(obj, 'cglookupone') V.numcols = 1; V.numrows = ud.Hand.EditXSize.Value; V.numaxes = 2; V.data.Y = ud.Hand.EditValue.Value*ones(V.numrows, 1); V.data.X = (0:V.numrows-1)'; elseif isa(obj, 'cgnormfunction') V.numrows = ud.Hand.EditXSize.Value; V.numcols = 1; V.data.Y = ud.Hand.EditValue.Value*ones(V.numrows, 1); V.numaxes = 2; % Look to see whether the normaliser is empty - if it is then we'll % initialise it too pX = get(obj, 'x'); if pX.isempty V.data.X = 0:V.numrows-1; else V.data.X = []; end elseif isa(obj, 'cgnormaliser') V.numcols = 1; V.numrows = ud.Hand.EditXSize.Value; V.numaxes = 2; V.data.X = (0:V.numrows-1)'; V.data.Y = []; % Look to see if the normaliser is only used by a single table; in % this case we'll kindly initialise it so the output range matches % the size of the table FL = get(obj, 'Flist'); if length(FL)==1 && FL.isa('cglookup') if FL.isa('cglookuptwo') if FL.get('x')==ud.displayitem szInd = 2; else szInd = 1; end else szInd = 1; end L = size(FL.get('values'), szInd); if L>=2 if V.numrows<=L V.data.Y = round(linspace(0, L-1, V.numrows)); else % Need to pad out ends with repeated breakpoints V.data.Y = [0:(L-1), repmat(L-1, 1, V.numrows-L)]; end end end elseif isa(obj, 'cgconstant') V.data.X = ud.Hand.EditValue.Value; V.numaxes = 1; V.numrows = 1; V.numcols = 1; end status = i_TransferToTable(ud.displayitem, V); if status==0 % update GUI i_RefreshIcons; i_FillValuePane; end end end %-------------------------------------- % Apply pasted data/ascii file data to table %-------------------------------------- function i_ApplyData(src, evt, source) %-------------------------------------- fh = i_GetHandle; ud = get(fh,'UserData'); if strcmp(ud.displaysource, 'project') if strcmp(source, 'pastedata') if mbcutils.Clipboard.isNumeric() data = mbcutils.Clipboard.paste(); else data = []; end info = 'Initialised from clipboard data'; elseif strcmp(source, 'asciifile'); [filename, pathname] = uigetfile({'*.txt;*.csv', 'Ascii data file (*.csv, *.txt)'}, ... 'Select data file', mbcGetPath('cage', 'Data')); if filename==0 return end data = cgcalreadtxt(fullfile(pathname,filename)); info = 'Initialised from ascii file'; else error(message('mbc:cgcalmanager:InvalidArgument')); end if isempty(data) h = errordlg('No data was found for importing.', 'MBC Toolbox', 'modal'); waitfor(h); return end % Set up an appropriate data structure according to the type of object % selected and then use subfunction to perform copy V = struct('name', source, ... 'description', '', ... 'info', info, ... 'data',[], ... 'numaxes',[], ... 'numrows',[], ... 'numcols',[]); obj = ud.displayitem.info; if isa(obj, 'cglookuptwo') V.numaxes = 3; if isnan(data(1)) && all(size(data)>=2) V.data.X = data(1, 2:end); V.data.Y = data(2:end, 1); V.data.Z = data(2:end, 2:end); [V.numrows V.numcols] = size(V.data.Z); else V.data.X = []; V.data.Y = []; V.data.Z = data; [V.numrows V.numcols] = size(data); end elseif isa(obj, 'cgnormfunction') || isa(obj, 'cgnormaliser') V.numaxes = 2; V.numcols = 2; if size(data, 2)==1 V.data.X = []; V.data.Y = data(:,1); else V.data.X = data(:,1); V.data.Y = data(:,2); end V.numrows = length(V.data.Y); elseif isa(obj, 'cgconstant') V.numaxes = 1; V.data.X = data; [V.numrows V.numcols] = size(data); end [status, msg] = i_TransferToTable(ud.displayitem, V); if status==0 % update GUI i_RefreshIcons; i_FillValuePane; i_FillCalItemPane; else h = errordlg(['Incorrect data for this calibration item.' msg{1}], 'MBC Toolbox', 'modal'); waitfor(h); end end end %-------------------------------------- % Apply calibration data to an item %-------------------------------------- function i_Link(src,evt) %-------------------------------------- fh = i_GetHandle; ud = get(fh,'UserData'); try FileItem = ud.Hand.ParamContents.getSelectedRows; ProjectItem = ud.Hand.BlockList.Selected; catch E return end if isempty(FileItem) || isempty(ProjectItem) return end calIdx = FileItem; if ProjectItem.isa('cgcontainer') ProjectItem = ProjectItem.getdata; end [status, msg] = i_TransferToTable(ProjectItem, ud.cal(calIdx)); if status==0 % update GUI i_RefreshIcons; i_FillValuePane; i_FillCalItemPane; else h = errordlg(['Incorrect data for this calibration item. ' msg{1}], 'MBC Toolbox', 'modal'); waitfor(h); end end %-------------------------------------- % Apply calibration data for as many % items as can be matched by name %-------------------------------------- function i_AutoLink(src,evt) %-------------------------------------- fh = i_GetHandle; ud = get(fh,'UserData'); % Generate a list of cal item names nds = ud.Hand.BlockList.findAllNodes; projnames = get(nds,{'Name'}); % Loop over the Cal file data, locate blocks with matching names and % collect the matches up. They will be processed in one go at the end ptrProjItems = null(xregpointer,0); idxCalFileItems = []; calnames = {ud.cal.name}; for n = 1:length(calnames) matchedidx = find(strcmpi(calnames{n},projnames)); if isscalar(matchedidx) % Get Project item node by index pItem = nds(matchedidx).Pointer; if pItem.isa('cgcontainer') pItem = pItem.getdata; end ptrProjItems = [ptrProjItems, pItem]; idxCalFileItems = [idxCalFileItems, n]; end end if ~isempty(ptrProjItems) status = i_TransferToTable(ptrProjItems, ud.cal(idxCalFileItems)); if any(status==0) % update GUI i_RefreshIcons; i_FillValuePane; i_FillCalItemPane; end if any(status~=0) % Warn user that some matches failed h = warndlg(['The new data could not be applied to some of the matched items.', ... 'These items have not been updated.'], 'MBC Toolbox', 'modal'); waitfor(h); end else % Warn user that there were no matches h = warndlg('No matches were found.', 'MBC Toolbox', 'modal'); waitfor(h); end end %-------------------------- function fh = i_Create fh = i_GetHandle; if isempty(fh) fh = i_CreateFigure(true); % modal dialog end end %-------------------------- function i_PrepareToShow(fh, pPROJ, varargin) pStartItem = []; if nargin>2 % Process prop/value pairs for other inputs for n = 1:2:(length(varargin)-1) switch lower(varargin{n}) case 'selectitem' pStartItem = varargin{n+1}; case 'closecallback' i_setCloseCallback(varargin{n+1}); end end end % Always update the cal file pane because new data might be loaded i_FillCalFilePane; % Update the display of project contents i_RefreshTree(pPROJ); found = false; if ~isempty(pStartItem) % Select a given item found = i_SelectTreeNode(pStartItem); end if ~found % Select the first node i_SelectTreeNode; end end %-------------------------- function i_StartNoAction(pPROJ, varargin) fh = i_Create; i_PrepareToShow(fh, pPROJ, varargin{:}); fh.showDialog(); i_Finish; end %-------------------------- function i_StartChooseFile(pPROJ, varargin) fh = i_Create; % Load in new cal data before refreshing the gui OK = i_ChooseFile; if OK i_PrepareToShow(fh, pPROJ, varargin{:}); fh.showDialog(); i_Finish; end end %-------------------------- function i_StartLoadCalData(pPROJ, calobj, caldata, varargin) fh = i_Create; % Load in new cal data before refreshing the gui i_LoadCalData(calobj, caldata); i_PrepareToShow(fh, pPROJ, varargin{:}); fh.showDialog(); i_Finish; end