function status=bussel(action,argument1,argument2)
%BUSSEL GUI Interface for selecting data off a bus line.
%
%Example:
% bussel('Init')
%
%Brings up the gui. Enter the string:
%
% eval('bussel(''Init'')')
%
%in the dialog strings of the text based Selector block to use the gui.
%Be sure to name the selector block "Bus" before grouping and masking it.
%
%This also works with the Insert block and will likely work with any
%block that has the same underlying structure.
%William York, 11/95.
%Copyright (c) 1995 by The MathWorks, Inc.
%$Revision: 1.2 $ $Date: 1997/03/11 19:55:51 $
BusName=[];
FigureTag=[];
Action=[];
Version = version;
v5 = strcmp(Version(1),'5'); % succesful status is 1 (true)
if (nargout > 0)
status = 1;
end
if (nargin > 3)
error('Too many input arguments to bussel.')
end
if (nargin > 2)
BusName=deblank(argument2);
% remove leading blanks from BusName too
if (~isempty(BusName) & BusName(1) == ' ')
loc = min(find(BusName ~= ' '));
BusName = BusName(loc:length(BusName));
end
end
if (nargin > 1)
FigureTag=argument1;
end
if (nargin > 0)
Action=action;
end
if (nargin == 0)
error('Not enough input arguements to bussel.')
end
if (strcmp(Action,'Init') | ...
strcmp(Action,'Revert') | ...
strcmp(Action,'Update'))
if (strcmp(Action,'Init') | strcmp(Action,'Revert'))
EnableRevert=0;
EnableApply=0;
else
EnableRevert=1;
EnableApply=1;
end
if (strcmp(Action,'Init'))
% Get current system and block name
blockname=gcb;
h_cb=get_param(blockname,'Handle');
% Check if figure already exists
h_fig=findobj('Tag',blockname);
if (~isempty(h_fig))
figure(h_fig)
return
end
end
if (strcmp(Action,'Update'))
% Check if bus file is valid
[Strings,Sizes,str]=busread(BusName);
if (isempty(Strings))
errstr=['Error - ' str];
errordlg(errstr,[gcb ' Error']);
if (nargout > 0)
status = 0;
end
return
end
end
if (strcmp(Action,'Revert')| strcmp(Action,'Update'))
% Bus file is valid, clear the figure window
h_fig=findobj('Tag',FigureTag);
delete(get(h_fig,'Children'))
% Get the handle to the current block
h_cb=get(h_fig,'UserData');
% Check if the block diagram exists
TestString='sys=get_param(h_cb,''Parent'');';
ErrorString='sys=[];';
eval(TestString,ErrorString);
if (isempty(sys))
errordlg('Block no longer exists - closing selector.');
delete(flipud(findobj('Tag',FigureTag)))
return
end
% Diagram exists
cb=get_param(h_cb,'Name');
blockname = [sys '/' cb];
end
% Get the parameters from the underlying Bus system
h_bus=get_param([blockname '/Bus'],'Handle');
BlockType=get_param(h_bus,'Mask Type');
entries=mask2str(h_bus);
if (isempty(entries) | size(entries,1) ~= 4)
error('Can''t read mask entries from bus block - the mask info is corrupt.')
end
% The mask should always contain at least these 4 entries, In this order
if (strcmp(Action,'Init') | strcmp(Action,'Revert'))
BusName=deblank(strrep(entries(1,:),'''',''));
StoredBusName = BusName;
else
StoredBusName=deblank(strrep(entries(1,:),'''',''));
end
DataNames=deblank(strrep(entries(2,:),'''',''));
% This may contain two numbers
TmpMatrix = str2num(entries(3,:));
if (isempty(TmpMatrix))
% str2num failed, try to recover
TmpMatrix = str2num([ '[' entries(3,:) ']' ]);
if (isempty(TmpMatrix) | size(TmpMatrix,2) ~= 2)
errordlg('Can''t read mask entries from bus block - the mask info is corrupt.');
end
% the new value should be OK - force the apply button to activate
EnableApply=1;
end
SizesFlag = TmpMatrix(1);
if (size(TmpMatrix,2) > 1)
CreateBusFlag = TmpMatrix(2);
else
CreateBusFlag = 1;
end
NamesFlag=str2num(deblank(strrep(entries(4,:),'''','')));
[Strings,Sizes,str]=busread(BusName);
if (isempty(Strings))
errstr=['Warning - ' str];
warndlg(errstr,[gcb ' Warning']);
end
NumStrings=size(Strings,1);
ButtonWidth = 70;
ButtonHeight = 25;
FrameSpace = 15;
ScreenS=get(0,'ScreenSize');
VerticalSpace=5;
% Number of rows
NumPush=1; % number of rows of pushbuttons (apply, close, etc)
if (findstr('Insert Signal',BlockType))
NumToggle=3; % number of rows of toggle buttons (show *)
else
NumToggle=2; % number of rows of toggle buttons (show *)
end
NumBlank=1; % number of blank rows between strings and the toggles
NumButtons=NumStrings; % number of strings in bus
NumText=1; % number of editable text blocks (bus name)
NumControls=(NumPush + NumToggle + NumBlank + NumText);
% Figure positioning
NumColumns=1;
ButtonsPerColumn=ceil(NumButtons/NumColumns);
ButtonAreaHeight = ...
ButtonsPerColumn*ButtonHeight + ...
ButtonsPerColumn*VerticalSpace;
ControlHeight = ...
NumControls*ButtonHeight + ...
(NumControls-1)*VerticalSpace;
FigH = ...
VerticalSpace + ...
ButtonAreaHeight + ...
ControlHeight + ...
VerticalSpace;
% Check if the figure height is > the screen size
% setup screen size scale - if figure is > Scale% of screen, add another
% column
Scale = .90;
if (FigH > Scale * ScreenS(4))
% Reset figure height - this needs some work but it gets the job
% done
NumColumns = ceil(ButtonAreaHeight / ...
(Scale * (ScreenS(4) - 5 * (ButtonHeight + VerticalSpace))));
% height of control buttons
ButtonsPerColumn= NumButtons / NumColumns;
ButtonAreaHeight = ...
ButtonsPerColumn*ButtonHeight + ...
ButtonsPerColumn*VerticalSpace;
FigH = ...
VerticalSpace + ...
ButtonAreaHeight + ...
ControlHeight + ...
VerticalSpace;
end
NumObjects = ButtonsPerColumn + NumControls;
CenterSpace = ...
ButtonWidth*.9 + FrameSpace + ...
ButtonWidth*.9 + FrameSpace + ...
ButtonWidth*.9;
if (NumColumns > 1)
CenterSpace = ...
CenterSpace + ButtonWidth*0.1 + ButtonWidth;
end
if (NumColumns > 2)
CenterSpace = ...
CenterSpace + (FrameSpace + 2*ButtonWidth) * (NumColumns - 2);
end
FigW = FrameSpace + CenterSpace + FrameSpace;
FigurePos=[(ScreenS(3)-FigW)/2 (ScreenS(4)-FigH)/2 FigW FigH];
DefUIBgC = get(0,'DefaultUIControlBackgroundColor');
% Place figures and UiControls
% Check if h_fig references a valid figure
if (~isempty(h_fig) & ishandle(h_fig))
set(h_fig,'Pos',FigurePos)
else
if v5
% Figure handle does not exist, create a new one
h_fig=figure('Visible','off','Units','pixels', ...
'Pos',FigurePos,'Color',DefUIBgC, ...
'NumberTitle','off','Name',[blockname ], ...
'HandleVisibility','callback', ...
'Resize','off', ...
'Tag',[blockname ],'MenuBar','none','UserData',h_cb);
else
% Figure handle does not exist, create a new one
h_fig=figure('Visible','off','Units','pixels', ...
'Pos',FigurePos,'Color',DefUIBgC, ...
'NumberTitle','off','Name',[blockname ], ...
'NextPlot','new', ...
'Resize','off', ...
'Tag',[blockname ],'MenuBar','none','UserData',h_cb);
end
end
% Place push buttons
Ind=1;
Mul=NumObjects - NumToggle - NumBlank - ButtonsPerColumn - NumText - Ind;
ApplyCallback='bussel(''Apply'',get(gcf,''Tag''));';
ApplyPos=[
FrameSpace
VerticalSpace + Mul*VerticalSpace + Mul*ButtonHeight
ButtonWidth*.9
ButtonHeight
];
ApplyPos=ApplyPos';
if (EnableApply)
EnableString = 'on';
else
EnableString = 'off';
end
h_apply=uicontrol('Visible','off','Parent',h_fig, ...
'Units','pixels','Enable',EnableString,'String','Apply', ...
'pos',ApplyPos,'Style','push','Tag','ApplyButton', ...
'CallBack',ApplyCallback);
if (EnableRevert)
EnableString = 'on';
else
EnableString = 'off';
end
RevertCallback='bussel(''Revert'',get(gcf,''Tag''));';
RevertPos=ApplyPos+[
ApplyPos(3)+ FrameSpace,
0,
0,
0,
]';
h_revert=uicontrol('Visible','off','Parent',h_fig,'Units','pixels', ...
'Enable',EnableString,'String','Revert','pos',RevertPos, ...
'Style','push','Tag','RevertButton','CallBack',RevertCallback);
CloseCallback='bussel(''Close'',get(gcf,''Tag''));';
ClosePos=RevertPos+[
RevertPos(3)+ FrameSpace,
0,
0,
0,
]';
h_close=uicontrol('Visible','off','Parent',h_fig,'Units','pixels', ...
'Enable','on','String','Close','pos',ClosePos, ...
'Style','push','Tag','CloseButton','CallBack',CloseCallback);
% Place check boxes for toggling of signal show / sizes
if (findstr('Insert Signal',BlockType))
Ind=1; % Num buttons down from bottom of blank below radio buttons
Mul=NumObjects - NumBlank - ButtonsPerColumn - NumText - Ind;
CreateBusCallback='bussel(''EnableApply'',get(gcf,''Tag''));';
CreateBusString='Create new bus?';
h_toggle=uicontrol('Visible','off','Parent',h_fig,'Units','pixels', ...
'Enable','on','String',CreateBusString,'pos',[
FrameSpace
VerticalSpace + Mul*VerticalSpace + Mul*ButtonHeight
2*ButtonWidth
ButtonHeight
], 'Style','checkbox','Value',CreateBusFlag,'Tag','CreateBusButton','CallBack',CreateBusCallback);
else
Ind=0;
end
Ind=Ind+1; % Num buttons down from bottom of blank below radio buttons
Mul=NumObjects - NumBlank - ButtonsPerColumn - NumText - Ind;
NamesCallback=['h_fig=gcf;' ...
'h_names=findobj(''Parent'',h_fig,''Tag'',''NamesButton'');' ...
'h_sizes=findobj(''Parent'',h_fig,''Tag'',''SizesButton'');' ...
'if (get(h_names,''Value'')),' ...
' set(h_sizes,''Enable'',''on'');' ...
'else,' ...
' set(h_sizes,''Enable'',''off'');' ...
'end;' ...
'bussel(''EnableApply'',get(gcf,''Tag''));'];
% NamesString='Show signal names?';
NamesString='Labels on mask?';
h_toggle=uicontrol('Visible','off','Parent',h_fig,'Units','pixels', ...
'Enable','on','String',NamesString,'pos',[
FrameSpace
VerticalSpace + Mul*VerticalSpace + Mul*ButtonHeight
2*ButtonWidth
ButtonHeight
], 'Style','checkbox','Value',NamesFlag,'Tag','NamesButton','CallBack',NamesCallback);
Ind=Ind+1; % Num buttons down from bottom of blank below radio buttons
Mul=NumObjects - NumBlank - ButtonsPerColumn - NumText - Ind;
SizesCallback='bussel(''EnableApply'',get(gcf,''Tag''));';
% SizesString='Show signal sizes?';
SizesString='Sizes with labels?';
if (NamesFlag)
SizesEnable='on';
else
SizesEnable='off';
end
h_toggle=uicontrol('Visible','off','Parent',h_fig,'Units','pixels', ...
'Enable',SizesEnable,'String',SizesString,'pos',[
FrameSpace
VerticalSpace + Mul*VerticalSpace + Mul*ButtonHeight
2*ButtonWidth
ButtonHeight
], 'Style','checkbox','Value',SizesFlag,'Tag','SizesButton','CallBack',SizesCallback);
% Blank space goes here
% Place radio buttons for selecting signals
RadioCallback='bussel(''EnableApply'',get(gcf,''Tag''));';
ColumnNumber=1;
ColumnOffset=0;
Ind2=1;
if (NumButtons == 0)
Mul=NumObjects - NumText - Ind2;
uicontrol('Style','text','Parent', h_fig, 'pos',[ ...
FrameSpace + ColumnOffset ...
VerticalSpace + Mul*VerticalSpace + Mul*ButtonHeight ...
2*ButtonWidth ...
ButtonHeight ...
],'String','Enter busfile name');
set(h_apply,'Enable','off');
end
for Ind1=1:NumButtons
if (Ind1 > ColumnNumber * ButtonsPerColumn)
ColumnOffset=ColumnNumber*(FrameSpace+2*ButtonWidth);
ColumnNumber=ColumnNumber+1;
Ind2=1;
end
Mul=NumObjects - NumText - Ind2;
h_btn(Ind1)=uicontrol('Visible','off','Parent',h_fig,'Units','pixels', ...
'Enable','on','HorizontalAlignment','left','pos',[ ...
FrameSpace + ColumnOffset ...
VerticalSpace + Mul*VerticalSpace + Mul*ButtonHeight ...
2*ButtonWidth ...
ButtonHeight ...
], 'Style','radiobutton','Tag',['RadioButton_' num2str(Ind1)], ...
'Callback',RadioCallback, ...
'String',[deblank(Strings(Ind1,:)) '[' num2str(Sizes(Ind1)) ']' ]);
Ind2 = Ind2+1;
end
Ind=1;
Mul=NumObjects - Ind;
TextPos = [
FrameSpace
VerticalSpace + Mul*VerticalSpace + Mul*ButtonHeight
32
20
];
h_text=uicontrol('Visible','off','Parent',h_fig,'Units','pixels', ...
'BackgroundColor',DefUIBgC, 'pos',TextPos, ...
'Style','text','String','Bus:', ...
'HorizontalAlignment','left');
% Edit callback syntax: "bussel('Init',FigureHandle,BusName);"
EditCallback=[ 'bussel(''Update'',get(gcf,''Tag''),' ...
'get(findobj(''Parent'',findobj(''Tag'',get(gcf,''Tag'')),', ...
'''Tag'',''BusName''),''String''));'];
EditPos = TextPos + [
TextPos(3),
0,
75,
0,
];
h_edit=uicontrol('Visible','off','Parent',h_fig,'Units','pixels', ...
'Callback',EditCallback,'BackgroundColor','white', ...
'pos',EditPos,'Style','edit','HorizontalAlignment','left', ...
'Tag','BusName','String',BusName);
UpdatePos = [
EditPos(1) + EditPos(3) + FrameSpace,
EditPos(2),
ButtonWidth*.9,
ButtonHeight,
];
% This uses the same callback as the edit object
h_update=uicontrol('Visible','off','Parent',h_fig,'Units','pixels', ...
'Enable','on','String','Update','pos',UpdatePos, ...
'Style','push','Tag','UpdateButton','CallBack',EditCallback);
% Check if any strings are set
if (~isempty(DataNames))
% Find out which strings are currently set
% DataNames contains the clean names as stored in the Bus mask
% Strings contains the space padded names as stored in the bus definition file
% Loop through all the DataNames - this is a | delimited string
PipeLocations=find(DataNames=='|');
if (isempty(PipeLocations))
WordDelimiters=[0 length(DataNames)+1];
else
WordDelimiters=[0 PipeLocations length(DataNames)+1];
end
FailureString='';
for (Ind1=1:length(WordDelimiters)-1)
Start=WordDelimiters(Ind1)+1;
End=WordDelimiters(Ind1+1)-1;
CurrentDataName=DataNames(Start:End);
% make sure the underlying system matches the bus definition file
ValidDefinitionFile=0;
% Loop through all the Strings - this is a space padded string matrix
for (Ind2=1:size(Strings,1))
CurrentString=deblank(Strings(Ind2,:));
if (strcmp(CurrentDataName,CurrentString))
% The data name appears in the Bus mask - this line is active.
% Toggle the radio button to reflect that the line is active.
set(h_btn(Ind2),'Value',1)
ValidDefinitionFile=1;
end
end
if (~ValidDefinitionFile)
if (~isempty(FailureString))
FailureString = [FailureString ', ' CurrentDataName];
else
FailureString = CurrentDataName;
end
end
end
if (~isempty(FailureString) & ...
strcmp(BusName,StoredBusName) & ...
NumButtons > 0)
errordlg(str2mat(['WARNING - Bus definition file not in sync with ' ...
'the block diagram.'],['The following strings are undefined: ' ...
FailureString]));
set(h_apply,'Enable','on');
end
end % if(~isempty(DataNames))
% Make units normalized - keep figure position non-normalized
FigPosition = get(h_fig,'position');
FigUnits = get(h_fig,'units');
set(findobj(h_fig),'units','normalized')
set(h_fig,'units',FigUnits);
set(h_fig,'position',FigPosition);
% Make figure visible
set(findobj(h_fig),'visible','on')
% end Action == Init
elseif (strcmp(Action,'Close'))
if (isempty(FigureTag))
error(['Action ' Action ' requires a second argument - the Figure tag'])
end
% Get handle to figure given tag
h_fig=findobj('Tag',FigureTag);
% Apply any pending changes if necessary
if(strcmp(lower(get(findobj('Parent',h_fig,'Tag','ApplyButton'),'Enable')),'on'))
applyStatus = bussel('Apply',FigureTag);
% Check if the apply failed
if (~applyStatus)
% the apply failed, don't close the figure
return
end
% Check if the figure got closed
if (~ishandle(findobj('Tag',FigureTag)))
% figure was likely closed, nothing to do
return
end
end
% Delete the figure and its children
delete(flipud(findobj('Tag',FigureTag)))
% end Action == Close
elseif (strcmp(Action,'Apply'))
if (isempty(FigureTag))
error(['Action ' Action ' requires a second argument - the Figure tag'])
end
% Get handle to figure given tag
h_fig=findobj('Tag',FigureTag);
% Get the name of the bus file from the dialog
h_edit=findobj('Parent',h_fig,'Tag','BusName');
BusName=deblank(get(h_edit,'String'));
% remove leading blanks from BusName too
if (BusName(1) == ' ')
loc = min(find(BusName ~= ' '));
BusName = BusName(loc:length(BusName));
end
% Get the handle to the current block
h_cb=get(h_fig,'UserData');
TestString='sys=get_param(h_cb,''Parent'');';
ErrorString='sys=[];';
eval(TestString,ErrorString);
if (isempty(sys))
errordlg('Block no longer exists - closing selector.');
delete(flipud(findobj('Tag',FigureTag)))
return
end
cb=get_param(h_cb,'Name');
% Get the handle to the underlying Bus block
h_bus=get_param([sys '/' cb '/Bus'],'Handle');
BlockType=get_param(h_bus,'Mask Type');
% Get the list of selected names - in order
NumButtons=length(findobj('Parent',h_fig,'Style','radiobutton'));
h_btn_all=0;
for (Ind=1:NumButtons)
h_btn_all(Ind)=findobj('Parent',h_fig,'Tag',['RadioButton_' num2str(Ind)]);
end
h_btn_sel=findobj('Parent',h_fig,'Style','radiobutton','Value',1);
NumSelected=length(h_btn_sel);
if (NumSelected==0)
errordlg('No signals selected.');
if (nargout > 0)
status = 0;
end
return
else
Strings=[];
for (Ind=1:length(h_btn_all))
if (get(h_btn_all(Ind),'Value')==1)
RealString=get(h_btn_all(Ind),'String');
[TempString,TempSize]=strtok(RealString,'[');
if (isempty(Strings))
Strings=deblank(TempString);
Sizes=str2num(strrep(strrep(TempSize,'[',''),']',''));
else
Strings=[
Strings '|' deblank(TempString)
];
Sizes=[
Sizes
str2num(strrep(strrep(TempSize,'[',''),']',''))
];
end
end
end
end
if (isempty(Strings) | isempty(Sizes))
error('Can''t understand strings list from selector window');
end
% Set the data name parameters in the underlying Bus system
if (findstr('Insert Signal',BlockType))
h_busname=findobj('Parent',h_fig,'Tag','CreateBusButton');
CreateBusFlag=get(h_busname,'Value');
else
CreateBusFlag=1;
end
h_names=findobj('Parent',h_fig,'Tag','NamesButton');
DrawFlag=get(h_names,'Value') ;
h_sizes=findobj('Parent',h_fig,'Tag','SizesButton');
SizesFlag=get(h_sizes,'Value');
NumNames=size(find(Strings=='|'),2) + 1;
dbimdraw(h_cb,DrawFlag,BusName,Strings,Sizes*SizesFlag,~CreateBusFlag);
% Update the Mask
if (findstr('Insert Signal',BlockType))
% Using Insert block
NewMaskEntry=str2mat( ...
['''' BusName ''''], ...
['''' Strings ''''], ...
[ '[ ' num2str(SizesFlag) ', ' num2str(CreateBusFlag) ' ]' ], ...
num2str(DrawFlag));
else
NewMaskEntry=str2mat( ...
['''' BusName ''''], ...
['''' Strings ''''], ...
num2str(SizesFlag), ...
num2str(DrawFlag));
end
str2mask(h_bus,NewMaskEntry);
% Build the string to create the D matrix
if (findstr('Insert Signal',BlockType))
% Using Insert block
[Indices,VecSize] = addtobus(BusName,Strings);
else
[Indices,VecSize] = parsebus(BusName,Strings);
end
if strcmp(get_param(h_bus,'blocktype'),'SubSystem')
% When we use the selector in a subsystem
h_bus_sel = find_system(h_bus,...
'LookUnderMasks','on','blocktype','Selector');
CURRENT_W = eval(get_param(h_bus_sel, 'InputPortWidth'));
if (VecSize > CURRENT_W)
set_param(h_bus_sel,'InputPortWidth',mat2str(VecSize))
set_param(h_bus_sel,'Elements', mat2str(Indices))
else
set_param(h_bus_sel,'Elements', mat2str(Indices))
set_param(h_bus_sel,'InputPortWidth',mat2str(VecSize))
end
else
% If we are using the State-Space block
DmatrixString = ['busdmat(' mat2str(Indices) ',' mat2str(VecSize) ')'];
set_param(h_bus,'D',DmatrixString);
end
% Disable Apply button
set(findobj('Parent',h_fig,'Tag','ApplyButton'),'Enable','off')
% end Action == Apply
elseif (strcmp(Action,'EnableApply'))
if (isempty(FigureTag))
error(['Action ' Action ' requires a second argument - the Figure tag'])
end
% Get handle to figure given tag
h_fig=findobj('Tag',FigureTag);
% Enable the Apply button
set(findobj('Parent',h_fig,'Tag','ApplyButton'),'Enable','on')
if ~v5
set(findobj('Parent',h_fig,'Tag','ApplyButton'),'Selected','on')
end
% Also enable the Revert button
set(findobj('Parent',h_fig,'Tag','RevertButton'),'Enable','on')
% end Action == EnableApply
else
error(['Invalid action for bussel. Action was "' Action '"'])
end
% EOF bussel.m