Code covered by the BSD License  

Highlights from
SigPlot

SigPlot

by

 

An advanced interface for 1-D signal visualization & editing.

ParamEditor(param)
% paramOut = ParamEditor(param)
%
% a GUI that simplifies the construction of Property windows.
% The program pops up a window that displays all parameters in structure
% <param> using a tabbed interface. Complicated hierarchies of parameters
% can be build using a two-level tabbed interface.
%
% In detail, <param> has the following structure:
%
%       param.highTab*.lowTab*.Parameter*
%       param.highTab*_.InfoTxt
%       param.highTab*_.lowTab*.InfoTxt
%       param.highTab*_.lowTab*.Parameter*.InfoTxt
%       param.highTab*_.lowTab*.Parameter*.Range
%   
% where <highTab*> are the names of the high-level tabs and <lowTab*>
% are the names of the low-level tabs associated with the corresponding
% high-level tabs. For example, we could generate a result like the following
% ('highTab1'->'lowTab2' tabs are selected):
%
% ||=[highTab1][highTab2]=============={highTab1_.InfoTxt}=============||
% ||                                                                   ||
% ||  |-------------------------------------------------------------|  ||
% ||  |                                                             |  ||
% ||  |                                                             |  ||
% ||  |    Order: [______]                                          |  ||
% ||  |                                                             |  ||
% ||  |    WindowType: [_________]                                  |  ||
% ||  |                                                             |  ||
% ||  |                                                             |  ||
% ||  |---{highTab1_.lowTab2.InfoTxt}---------[lowTab1][lowTab2]----|  ||
% ||                                                                   ||
% ||===================================================================||
%
% Additionaly to the fields 'highTab*', there are the so-called hidden
% fields 'highTab*_' which are not displayed, and which contain the following
% additional information:
%
% param.highTab*_.InfoTxt : 
%                 [string] a small description text of 'highTab*'. The string 
%                 is displayed at the right of the high-level tab.
% param.highTab*_.lowTab*.InfoTxt : 
%                 [string] a small description text of 'highTab*.lowtab*'. 
%                 The string is displayed at the left of the low-level tab.
% param.highTab*_.lowTab*.Parameter*.InfoTxt :
%                 [string] the text that will be displayed on the GUI. This
%                 is to avoid displaying quirky parameter names. 
%                 The string is displayed at the left of the low-level tab.
% param.highTab*_.lowTab*.Parameter*.Range :
%                 [2x1] the minimum and the maximum accepted value (the
%                       range of these values). This is when the parameter
%                       value is a number. Use [ -Inf Inf ] to disable
%                       range checking.
%                 [cell array] of strings, doubles, integers, etc. This is
%                       used when the the parameter picks up it's value
%                       from a set of acceptable values. The cell array
%                       contains the acceptable values.
%
%  Examples: an example can be found in: sigplot\test\test_ParamEditor.m
%
%   Input Arguments:
%     param: [struct] special structure that contains the parameters
%            under definition plus extra information for their range of
%            values.
%
%   Output Arguments:
%     paramOut: [struct] the modified structure
%     cancel_flag: [boolean] true if the editor was closed using cancel, false if closed using ok
%
function [paramOut, cancel_flag] = ParamEditor(param)

paramOut  = param;
cancel_flag = true; % Default value if the editor is closed using window controls.
paramDefault = param;
all_params = struct('Name',[],'hcontrol',[]);

tabStyle = 'lefttop';
subtabStyle = 'rightbottom';

width = 0;
hfig = figure(...
    'Name','Properties',...
    'NumberTitle','off', ...
    'Resize','on',...
    'Menubar','none',...
    'Toolbar','none',...
    'WindowStyle','normal'); %TEST%

tabNames = fieldnames(param);
Ntab = length(tabNames);
% remove hidden entries
I = [];
for n = 1:Ntab
    name = char(tabNames(n));
    if name(end)~='_'
        I = [ I n ];
    end
end
tabNames = tabNames(I);

%--------------------------------------------------------------------------
% Creating the tabs
%--------------------------------------------------------------------------
htab = uitabpanel(...
    'Parent',hfig,...
    'Style',tabStyle,...
    'Units','normalized',...
    'Position',[0 ,0.1 ,1, 0.9],...
    'Margins',{[0,-1,1,0],'pixels'},...
    'PanelBorderType','line',...
    'Title', tabNames,...
    'CreateFcn',@CreateTabs);
%--------------------------------------------------------------------------
% Creating the buttons: OK, DEFAULT, CANCEL
%--------------------------------------------------------------------------
buttonWidth = 0.25;
buttonHeight = 0.06;
buttonDist = (1 - 3*buttonWidth)/4;
hbutton = uicontrol(...
    'Parent',hfig,...
    'Units','normalized',...
    'Position',[buttonDist,0.02,buttonWidth,buttonHeight],...
    'BackgroundColor',get(htab,'BackgroundColor'),...
    'ForegroundColor','k',...
    'HitTest','off',...
    'Style','pushbutton',...
    'Callback',@button_OK_Callback,...
    'String','OK');
hbutton(2) = uicontrol(...
    'Parent',hfig,...
    'Units','normalized',...
    'Position',[2*buttonDist+buttonWidth,0.02,buttonWidth,buttonHeight],...
    'BackgroundColor',get(htab,'BackgroundColor'),...
    'ForegroundColor','k',...
    'HitTest','off',...
    'Style','pushbutton',...
    'Callback',@button_DEFAULT_Callback,...
    'String','DEFAULT');
hbutton(3) = uicontrol(...
    'Parent',hfig,...
    'Units','normalized',...
    'Position',[3*buttonDist+2*buttonWidth,0.02,buttonWidth,buttonHeight],...
    'BackgroundColor',get(htab,'BackgroundColor'),...
    'ForegroundColor','k',...
    'HitTest','off',...
    'Style','pushbutton',...
    'Callback',@button_CANCEL_Callback,...
    'String','CANCEL');

updateParam();

uiwait(hfig);

%--------------------------------------------------------------------------

    function CreateTabs(htab,evdt,hpanel,hstatus)
        
        Ntab = length(tabNames);
        hsubtab = [];
        %
        % create UI for each tab
        %
        for tabInd = 1:Ntab
            %
            % create the internal tab-panel (sub-tab)
            %
            subtabNames = eval(sprintf('fieldnames(param.%s);',char(tabNames(tabInd))));
            hsubtab(tabInd) = uitabpanel(...
                'Parent',hpanel(tabInd),...
                'TabPosition',subtabStyle,...
                'Units','normalized',...
                'Position',[0.01 ,0.01 , 0.98, 0.98],...
                'Margins',{[0,-1,1,0],'pixels'},...
                'PanelBorderType','line',...
                'Title', subtabNames,...
                'CreateFcn',@CreateSubTabs);
            setappdata(hsubtab(tabInd),'TabIndex',tabInd);
            setappdata(hsubtab(tabInd),'TabName',char(tabNames(tabInd)));
            %
            % create & initialize the associated status text
            %
            hstatus_sub = getappdata(hsubtab(tabInd),'hstatus');
            try
                if isfield(param,[ char(tabNames(tabInd)) '_' ])
                    InfoTxt = eval(sprintf('param.%s_.%s.InfoTxt;',char(tabNames(tabInd)),char(subtabNames(1))));
                else
                    InfoTxt = char(subtabNames(1));
                end
            catch
                error('tab <%s>, subtab <%s>: InfoTxt is not found ',char(tabNames(tabInd)),char(subtabNames(1))); 
            end
            uicontrol(...
                'Parent',hstatus_sub,...
                'Units','normalized',...
                'Position',[0,0.1,1,.68],...
                'BackgroundColor',get(hstatus_sub,'BackgroundColor'),...
                'ForegroundColor','k',...
                'HitTest','off',...
                'Style','text',...
                'String',InfoTxt);
            %
            % create UI for each sub-tab
            %
            hsubpanel = getappdata(hsubtab(tabInd),'panels');
            for subtabInd = 1:length(hsubpanel)
                subtabParamNames = eval(sprintf('fieldnames(param.%s.%s);',char(tabNames(tabInd)),char(subtabNames(subtabInd))));
                charLen = 0.019;
                charHeight = 0.06;
                N = length(subtabParamNames);
                htxt = [];
                hinput = [];
                %
                % create UI items for each entry of the 'param'
                % structure
                %
                for n = 1:N
                    if isfield(param,[ char(tabNames(tabInd)) '_' ])
                        txt = eval(sprintf('param.%s_.%s.%s.InfoTxt;',char(tabNames(tabInd)),char(subtabNames(subtabInd)),char(subtabParamNames(n))));
                    else
                        txt = char(subtabParamNames(n));
                    end
                    htxt(n) = uicontrol(...
                        'Parent',hsubpanel(subtabInd),...
                        'Units','normalized',...
                        'Position',[0,n/(N+1),length(txt)*charLen,charHeight],...
                        'BackgroundColor',get(hsubpanel(subtabInd),'BackgroundColor'),...
                        'HorizontalAlignment','left',...
                        'ForegroundColor','k',...
                        'HitTest','off',...
                        'Style','text',...
                        'FontSize',12,...
                        'String', [ txt ':' ]);
                    if isfield(param,[ char(tabNames(tabInd)) '_' ])
                        Range = eval(sprintf('param.%s_.%s.%s.Range;',char(tabNames(tabInd)),char(subtabNames(subtabInd)),char(subtabParamNames(n))));
                    else
                        Range = [ -Inf Inf ];
                    end
                    Value = eval(sprintf('param.%s.%s.%s;',char(tabNames(tabInd)),char(subtabNames(subtabInd)),char(subtabParamNames(n))));
                    if iscell(Range)
                        hinput(n) = uicontrol(...
                            'Parent',hsubpanel(subtabInd),...
                            'Units','normalized',...
                            'Position',[length(txt)*charLen, n/(N+1)+0.01, 20*charLen, charHeight],...
                            'BackgroundColor','white',...
                            'HorizontalAlignment','left',...
                            'ForegroundColor','k',...
                            'HitTest','off',...
                            'Style','popupmenu',...
                            'FontSize',12,...
                            'Callback',@popupmenu_Callback,...
                            'FontName','FixedWidth',...
                            'String', Range);
                    elseif strcmp(Range,'multiline_script')
                        tooltip_string = eval(sprintf('param.%s_.%s.%s.TooltipString;',char(tabNames(tabInd)),char(subtabNames(subtabInd)),char(subtabParamNames(n))));
                        hinput(n) = uicontrol(...
                            'Parent',hsubpanel(subtabInd),...
                            'Units','normalized',...
                            'Position',[length(txt)*charLen,(n-1)/(N+1)+1.5*charHeight,1.0-(length(txt)+1)*charLen,2/(N+1)-3*charHeight],...
                            'BackgroundColor','white',...
                            'HorizontalAlignment','left',...
                            'ForegroundColor','k',...
                            'HitTest','off',...
                            'Style','edit',...
                            'FontSize',12,...
                            'Callback',@edit_Callback,...
                            'FontName','FixedWidth',...
                            'Max',10,...
                            'Min',1,...
                            'TooltipString',tooltip_string,...
                            'String', Value);
                    else
                        hinput(n) = uicontrol(...
                            'Parent',hsubpanel(subtabInd),...
                            'Units','normalized',...
                            'Position',[length(txt)*charLen,n/(N+1),15*charLen,charHeight],...
                            'BackgroundColor','white',...
                            'HorizontalAlignment','left',...
                            'ForegroundColor','k',...
                            'HitTest','off',...
                            'Style','edit',...
                            'FontSize',12,...
                            'Callback',@edit_Callback,...
                            'FontName','FixedWidth',...
                            'String', Value);
                    end
                    setappdata(hinput(n),'ParamName',sprintf('param.%s.%s.%s',char(tabNames(tabInd)),char(subtabNames(subtabInd)),char(subtabParamNames(n))));
                    setappdata(hinput(n),'RangeName',sprintf('param.%s_.%s.%s.Range',char(tabNames(tabInd)),char(subtabNames(subtabInd)),char(subtabParamNames(n))));
                    Nparam = length(all_params);
                    all_params(Nparam+1).Name = sprintf('param.%s.%s.%s',char(tabNames(tabInd)),char(subtabNames(subtabInd)),char(subtabParamNames(n)));
                    all_params(Nparam+1).hcontrol = hinput(n);
                end
            end
        end
        
        if isfield(param,[ char(tabNames(1)) '_' ])
            InfoTxt = eval(sprintf('param.%s_.InfoTxt;',char(tabNames(1))));
        else
            InfoTxt = '';
        end
        uicontrol(...
            'Parent',hstatus,...
            'Units','normalized',...
            'Position',[0,0.1,1,.68],...
            'BackgroundColor',get(hstatus,'BackgroundColor'),...
            'ForegroundColor','k',...
            'HitTest','off',...
            'Style','text',...
            'String',InfoTxt);
        setappdata(htab,'SelectionChangeFcn',@TabStatus);
        
        %TEST%set(htab,'ResizeFcn',{@TabResize,[0.5,0.5]});
        set(htab,'Units','normalized'); %TEST%
        
        all_params = all_params(2:end);
        
    end

%--------------------------------------------------------------------------

    function CreateSubTabs(htab,evdt,hpanel,hstatus)
        setappdata(htab,'SelectionChangeFcn',@SubTabStatus);
        setappdata(htab,'hstatus',hstatus);
    end

%--------------------------------------------------------------------------

    function TabResize(hobj,evdt,ysiz)
        figpos = get(hfig,'Position');
        tabpos = get(hobj,'Position');
        tabpos([1,3]) = [width,1-width]*figpos(3)+[1,0];
        tabpos([2,4]) = ysiz*figpos(4)+[1,0];
        set(hobj,'Position',tabpos);
    end

%--------------------------------------------------------------------------

    function TabStatus(hobj,evdt)
        if isfield(param,[ char(tabNames(1)) '_' ])
            InfoTxt = eval(sprintf('param.%s_.InfoTxt;',char(tabNames(evdt.NewValue))));
        else
            InfoTxt = '';
        end
        set(get(evdt.Status,'Children'),'String',InfoTxt);
    end

%--------------------------------------------------------------------------

    function SubTabStatus(hobj,evdt)
        htab = get(hobj,'Parent');
        tabInd = getappdata(htab,'TabIndex');
        subtabInd = evdt.NewValue;
        subtabNames = eval(sprintf('fieldnames(param.%s);',char(tabNames(tabInd))));
        if isfield(param,[ char(tabNames(tabInd)) '_' ])
            InfoTxt = eval(sprintf('param.%s_.%s.InfoTxt;',char(tabNames(tabInd)),char(subtabNames(subtabInd))));
        else
            InfoTxt = char(subtabNames(subtabInd));
        end
        set(get(evdt.Status,'Children'),'String',InfoTxt);
    end

%--------------------------------------------------------------------------

    function popupmenu_Callback(hObject, eventdata, handles)
        % hObject    handle to popupmenu (see GCBO)
        % eventdata  reserved - to be defined in a future version of MATLAB
        % handles    structure with handles and user data (see GUIDATA)
        
        % Hints: contents = get(hObject,'String') returns popupmenu contents as cell array
        %        contents{get(hObject,'Value')} returns selected item from
        %        popupmenu
        contents = get(hObject,'String');
        val = contents{get(hObject,'Value')};
        paramName = getappdata(hObject,'ParamName');
        valclass = eval(sprintf('class(%s);',paramName));
        eval(sprintf('%s = %s(val);',paramName,valclass));
    end

%--------------------------------------------------------------------------

    function edit_Callback(hObject, eventdata, handles)
        % hObject    handle to edit1 (see GCBO)
        % eventdata  reserved - to be defined in a future version of MATLAB
        % handles    structure with handles and user data (see GUIDATA)
        % Hints: get(hObject,'String') returns contents of edit1 as text
        %        str2double(get(hObject,'String')) returns contents of edit1 as a double
        contents = get(hObject,'String');
        paramName = getappdata(hObject,'ParamName');
        rangeName = getappdata(hObject,'RangeName');
        valclass = eval(sprintf('class(%s);',paramName));
        Range = eval(sprintf('%s(%s);',valclass,rangeName));
        switch valclass
            case { 'double', 'single' }
                cmd = 'sscanf(contents,''%f'',[ 1 1 ]);';
                val = eval(cmd);
                val = max(Range(1),min(val,Range(2)));
                txt = sprintf('%g',val);
            case { 'int32', 'int16', 'int8', 'uint32', 'uint16', 'uint8', 'boolean' }
                cmd = 'sscanf(contents,''%d'',[ 1 1 ]);';
                val = eval(cmd);
                val = max(Range(1),min(val,Range(2)));
                txt = sprintf('%d',val);
            case { 'char' }
                val = contents;
                txt = char(val);
            otherwise
                warning('unknown type of values');
        end
        eval(sprintf('%s = val;',paramName));
        set(hObject,'String',txt);
    end

%--------------------------------------------------------------------------

    function button_OK_Callback(hObject, eventdata, handles)
        paramOut = param;
        cancel_flag = false;
        hfig = get(hObject,'Parent');
        close(hfig);
    end

%--------------------------------------------------------------------------

    function button_DEFAULT_Callback(hObject, eventdata, handles)
        param = paramDefault;
        updateParam();
    end

%--------------------------------------------------------------------------

    function button_CANCEL_Callback(hObject, eventdata, handles)
        cancel_flag = true;
        close(hfig);
    end

%--------------------------------------------------------------------------

    function updateParam()
        Nparam = length(all_params);
        for n=1:Nparam
            hObject = all_params(n).hcontrol;
            val = eval(sprintf('%s;',all_params(n).Name));
            valclass = eval(sprintf('class(%s);',all_params(n).Name));
            switch valclass
                case { 'double', 'single' }
                    txt = sprintf('%g',val);
                case { 'int32', 'int16', 'int8', 'uint32', 'uint16', 'uint8', 'boolean' }
                    txt = sprintf('%d',val);
                case { 'char' }
                    txt = val;
                otherwise
                    warning('unknown type of values');
            end         
            Style = get(hObject,'Style');
            switch Style
                case 'popupmenu'
                    contents = get(hObject,'String');
                    ind = find(ismember(contents, txt)==1);
                    set(hObject,'Value',ind);
                case 'edit'
                    set(hObject,'String',txt);
                otherwise
                    warning('unknown Style');
            end
        end
    end


end

Contact us