No BSD License  

Highlights from
Unit Conversion

image thumbnail

Unit Conversion

by

 

25 Mar 2003 (Updated )

MATLAB function, GUI & Simulink block for Unit Conversion.

unittool(fragIn, figId, tabIn)
function [factor,offset,choice] = unittool(fragIn, figId, tabIn)
%unittool   GUI tool to show or return unit conversion coefficients.
%   unittool displays a window with a selection of unit types.
%   Factor and Offset conversion factors are displayed on the tool
%   each time the user selects unit conversion options.
%
%   unittool(InVect) displays the tool with initial setting InVect. i.e. open on  
%   the tab number InVect(3) with choice indexes InVect(1:2) selected.
%
%   unittool(...,'calc') displays the tool with a space to enter a number.  
%   When entered or OK is clicked, the number is converted from the
%   input units to the output units.
%
%   [Factor,Offset,Choice] = unittool(...) displays a dialog with the selection of unit types.
%   The calling process is stopped to await the results from the conversion when OK is clicked.
%   Factor is the conversion factor
%   Offset is an offset applicable when the unit type is temperature
%   Choice is a cell vector containing the choice index vector [in,out,type]
%             input units string, output units string, and unit type string.
%
%   Outputs are all [] if Cancel is clicked or the window deleted.
%
%   For example:
%        %Display the tool.
%        unittool('calc')
%
%        %Display the dialog, await the result
%        %Select a unit type, and input & output units. Then hit OK.
%        [Factor,Offset]=unittool
%
%   See also: unitconversion.

%   Author: Mike Thomson   7 June 2002 
%   Version2: 26 April 2003 - Mod to initialise the tab button positions
%                             Higher precision in display

%-------------------------------------------------------------------------
% Set spacing and sizing constants for the GUI layout
%-------------------------------------------------------------------------
dlgUnits  = 'points'; % units used for all objects
dlgColor   = [0.8,0.8,0.8];
tabColor  = [0.7,0.7,0.7];
bgColor  = [1,1,1];

%Window positioning
winTopGap   = 35;       % gap between top of screen and top of figure **
winSideGap  = 10;       % gap between side of screen and side of figure **

% ** figure function 'Position' parameter sets "available" area. You must 
% allow space around it for the whole window size - the OS adds
% a title bar (aprx 42 points on Mac and Windows) and a window border
% (usu 2-6 points). Otherwise user cannot move the window.
% Also you may be prevented from setting bottom below 26 points.
% 800, 600 pixels -> 600, 450 points.

%Gaps
pane1Gap=5;
pane2Gap=5;
tabGap=1;
textPad = [0,0,10,2];    % extra [0,0,Width,Height] on uicontrols to pad text
listPad = [0,0,20,10];   % extra [0,0,Width,Height] on uicontrols to pad lists
selHigh = 4;

%Extras
okWide      = 60;       % for OK & Cancel buttons
okHigh      = 15;       % for OK & Cancel buttons
scrollWide  = 12;       % 
prec        = 8;        % precision of results

%Set tab button size
tabButWide=40;
tabButHigh=15;

% Min Object sizes
objWide=30; objHigh=10; objGap=4;

%=========================================================================
% PERFORM CALLBACK ACTION
%=========================================================================
if exist('fragIn') & ischar(fragIn),
   fragName=fragIn;
else
   fragName='none';
end

switch fragName
   
case 'unitTl_Recalc'
   % Get the current settings
   hData=get(figId, 'Userdata');
   t=get( hData.TabSel, 'Userdata' );
   objValues=get(hData.Tab(t).Object,{'Value'});    % get list states on this tab
   calcVal=str2num(get(hData.Pane2(4),'String'));   % get calc input value
   
   % Calculate the units
   [fac,off] = unitconversion(t,objValues{1},objValues{2});   
   
   % Display the numbers
   set( hData.Pane2(8), 'String', num2str(fac,prec) );
   set( hData.Pane2(9), 'String', num2str(off,prec) );
   set( hData.Pane2(5), 'String', num2str(calcVal*fac+off,prec) );
   
case 'unitTl_figResize'
   % Get handle data
   hData=get(figId, 'Userdata');
   
   %get figure size
   figPos = get(figId,'Position');  % record fig - user re-size
   
   % Get panel size data
   PnS=get(hData.TabButton,{'Userdata'});
   PnS=cat(1,PnS{:});
   
   % Check min size
   minWide = 50 + max(PnS(:,3)) + pane1Gap*2;
   minWide = max(minWide,2*okWide+pane2Gap*3);
   minHigh = 50 + max(PnS(:,4)) + tabButHigh + ...
      pane1Gap*2 + okHigh*3 + pane2Gap*4 + (okHigh*2+pane2Gap*2)*hData.Calc;
   
   if figPos(3)<minWide,
      winWide = minWide;
   else
      winWide = figPos(3);
   end %if
   
   if figPos(4)<minHigh,
      winHigh = minHigh;
   else
      winHigh = figPos(4);
   end %if
   
   % Check if top is off the screen
   oldUnits = get(0,'Units');         % remember old units
   set( 0, 'Units', dlgUnits );       % convert to desired units
   screenSize = get(0,'ScreenSize');  % record screensize
   set( 0, 'Units',  oldUnits );      % convert back to old units
   
   if screenSize(4)-winTopGap < figPos(2)+winHigh,
      figPos(2)=screenSize(4)-winTopGap-winHigh;
   end
   
   set(figId, 'Position', [figPos(1), figPos(2), winWide, winHigh]);
   
   % Set Pane 2 sizes
   Pane2High=okHigh*3+pane2Gap*4 + (okHigh*2+pane2Gap*2)*hData.Calc;
   x=(winWide - 2*okWide)/3;
   p2Pos={[-10, 0, winWide+20, Pane2High];...
      [x, pane2Gap, okWide, okHigh];...
      [2*x+okWide, pane2Gap, okWide, okHigh];...
      [x, pane2Gap*2+okHigh, okWide, okHigh];...
      [2*x+okWide, pane2Gap*2+okHigh, okWide, okHigh];...
      [x, pane2Gap*3+okHigh*2, okWide, objHigh];...
      [2*x+okWide, pane2Gap*3+okHigh*2, okWide, objHigh];...
      [x, pane2Gap*2+okHigh, okWide, okHigh];...
      [2*x+okWide, pane2Gap*2+okHigh, okWide, okHigh];...
      [x, pane2Gap*3+okHigh*2, okWide, objHigh];...
      [2*x+okWide, pane2Gap*3+okHigh*2, okWide, objHigh]};
   if hData.Calc,
      p2Pos(8:11)={...
          [x, pane2Gap*4+okHigh*3, okWide, okHigh];...
          [2*x+okWide, pane2Gap*4+okHigh*3, okWide, okHigh];...
          [x, pane2Gap*5+okHigh*4, okWide, objHigh];...
          [2*x+okWide, pane2Gap*5+okHigh*4, okWide, objHigh]};
   end
   set( hData.Pane2, {'Position'}, p2Pos );
   
   % Set TabFrame sizes - NB these are also used later to position pwFrame
   tabFrameWide=winWide-2*pane1Gap;
   tabFrameHigh=winHigh-2*pane1Gap - Pane2High - tabButHigh;
   tabFrameTopbase=Pane2High+pane1Gap+tabFrameHigh;
   pc{1}=[0, Pane2High, pane1Gap, winHigh-Pane2High];
   pc{2}=[pane1Gap+tabFrameWide, Pane2High, pane1Gap, winHigh-Pane2High];
   pc{3}=[pane1Gap, Pane2High, tabFrameWide, pane1Gap];
   pc{4}=[pane1Gap, tabFrameTopbase, tabFrameWide, tabButHigh+pane1Gap];
   pc{5}=[pane1Gap-1, Pane2High+1, tabFrameWide+2, pane1Gap-2];
   pc{6}=[0.5, tabFrameTopbase+0.5, pane1Gap+0.5, tabButHigh+pane1Gap-1.5];
   pc{7}=[winWide-pane1Gap-1, tabFrameTopbase+0.5, pane1Gap, tabButHigh+pane1Gap-1.5];
   set( hData.TabFrame, {'Position'}, pc' );
   
   % Set Tab Button positions
   tab=get(hData.TabSel,'Userdata');
   %    Will the buttons fit?
   nTabs=length(hData.TabButton);
   tPos=get(hData.TabButton,{'Position'});  % fetch button sizes
   tPos=cat(1,tPos{:});
   sumButWide=sum(tPos(:,3));
   butZoneWide=winWide-2*pane1Gap;
   bSlideWide=tabButHigh+1;
   if sumButWide > butZoneWide,
      butFrac=max(1.11,nTabs - (butZoneWide-bSlideWide)*nTabs / sumButWide);
      bSliMx=-bSlideWide + butFrac*sumButWide/nTabs;
      bSlidPos=[pane1Gap, winHigh-pane1Gap-tabButHigh, bSlideWide, tabButHigh];
      bSlidIni=-bSlideWide + 1.2*butFrac*sum(tPos(1:tab,3))/nTabs;
      set(hData.TabSlide,'Position',bSlidPos, 'Visible','on', 'Value',bSlidIni);
      set(hData.TabSlide,'Min',-bSlideWide, 'Max',bSliMx, 'SliderStep',[1/butFrac,1]);
   else
      set(hData.TabSlide, 'Visible','off', 'Min',0, 'Max',1, 'Value',0);
   end
  
   % Reset the tab format
   unittool('unitTl_tabSelect',figId,tab);
   
case 'unitTl_tabSelect'
   % Get handle data
   hData=get(figId, 'Userdata');
   
   % Which tab?
   oldtab=get(hData.TabSel,'Userdata');
   if nargin>2,
      tab=tabIn;      % button number passed in as tabIn
   else
      tab=find(gcbo==hData.TabButton); % find index number of button
      if tab==oldtab,
         return;     % just return if we're already in this tab
      end %if
   end %if
   
   % Get panel size data
   PnS=get(hData.TabButton(tab),'Userdata'); % [panelWide;panelHigh;pnlRTWide;pnlCTHigh]
   tFr=get( hData.TabFrame, 'Position');
   tFr=cat(1,tFr{[2,4]});  % convert to matrix
   pwFrameLeft=tFr(2,1);
   pwFrameBott=tFr(1,2)+tFr(1,3);
   pwFrameWide=tFr(2,3);
   pwFrameHigh=tFr(2,2)-tFr(1,2)-tFr(1,3);
   ttSize=hData.TabTitSz(tab,:);

   % Set pwFrame positions
   pc{1}=[pwFrameLeft, pwFrameBott, PnS(3), pwFrameHigh];
   pc{2}=[pwFrameLeft, pwFrameBott+pwFrameHigh-PnS(4)-ttSize(2), pwFrameWide, PnS(4)];
   set( hData.PwFrame, {'Position'}, pc' );

   % Set Scroll positions - use h to indicate slider present
   viewPos=[pwFrameLeft+PnS(3), pwFrameBott, pwFrameWide-PnS(3), pwFrameHigh-PnS(4)-ttSize(2)];
   h=0;
   if PnS(1)>viewPos(3),
      set( hData.Scroll(1), 'Visible','on' );
      h=scrollWide;
   else
      set( hData.Scroll(1), 'Visible','off' );
   end
   titOff=viewPos(2)+viewPos(4);
   objOff=max( viewPos(2)+h,  titOff-PnS(2) );
   objResize=max(min(0,viewPos(4)-h-PnS(2)),objHigh-PnS(2));
   set( hData.Scroll(1), 'Position', [viewPos(1:2), viewPos(3), scrollWide] ,...
                         'Userdata', [objOff,titOff,objResize] );

   % Set Scroll parameter values 
   hStp=1;
   hSliMx=PnS(1)-viewPos(3);    % slider value at rhs
   if hSliMx<=0, hSliMx=1; end;
   if (PnS(1)-viewPos(3))>0,
      hStp=(viewPos(3))/(PnS(1)-viewPos(3)); % sets slider knob size
   end
   if hStp<=0, hStp=1; end;
   set( hData.Scroll(1), 'Max',hSliMx, 'SliderStep',[min(0.1*hStp,1) hStp], 'Value',0);
   
   % Set TabSel Userdata
   set( hData.TabSel, 'Userdata', tab );
   
   % Set TabTitle pars
   pos=[pwFrameLeft,pwFrameBott+pwFrameHigh-ttSize(2),pwFrameWide,ttSize(2)];
   set( hData.TabTitle, 'Position',pos,...
      'String',hData.TabTitTx{tab});
   
   % Set TitFrame positions
   clear pc; % reset size
   pc{1}=[pwFrameLeft, pwFrameBott, PnS(3), tabGap+h];
   pc{2}=[pwFrameLeft, viewPos(2)+viewPos(4), PnS(3), PnS(4)];
   pc{3}=[viewPos(1)+viewPos(3), viewPos(2)+viewPos(4), tabGap, PnS(4)];
   set( hData.TitFrame, {'Position'}, pc' );
   
   % Make previous Tab's objects invisible if it's not this one (resizing)
   if oldtab~=tab,
      set(hData.Tab(oldtab).Object,{'Visible'},{'off'});
      set(hData.Tab(oldtab).CTitle,{'Visible'},{'off'});
      set(hData.TabButton(oldtab), 'Background',dlgColor);
   end %if
   
   % Make this Tab's objects visible
   set(hData.Tab(tab).Object,{'Visible'},{'on'});
   set(hData.Tab(tab).CTitle,{'Visible'},{'on'});
   set(hData.TabButton(tab), 'Background',tabColor);
   
   % Nudge the tab buttons
	slProp=get(hData.TabSlide, {'Value';'Min';'Max'});
	tPos=get(hData.TabButton(tab),'Position');  % fetch this button pos
	butnShift=slProp{1}+max(tPos(1)+tPos(3)-(pwFrameLeft+pwFrameWide-2*pane1Gap),0);
	butnShift=butnShift+min(tPos(1)-pwFrameLeft-tabButHigh-2*pane1Gap,0);
	butnShift=max(min(butnShift,slProp{3}),slProp{2});
	set(hData.TabSlide, 'Value',butnShift);
   
   % Position the tab buttons
	unittool('unitTl_scrollTabs',figId);
   
   % Reset the objects positions
   unittool('unitTl_scroll',figId);
   
   % Get the current settings & display the numbers
   unittool('unitTl_Recalc',figId);

case 'unitTl_scrollTabs'
   % Get handle data
   hData=get(figId, 'Userdata');
   
   % Move Tab buttons' positions
   nTabs=length(hData.TabButton);      
   tab=get( hData.TabSel, 'Userdata' ); % Which Tab are we in?
   butnShift=get(hData.TabSlide, {'Value','Userdata'});  % fetch slider shift & button widths
   tButWide=butnShift{2};
   tCumWide=[0;cumsum(tButWide)];       % pos offsets - 0 for 1st
   winPos=get(figId, 'Position');
   tabFrameTopbase=winPos(4)-pane1Gap-tabButHigh;
   for k=1:nTabs,
      pc{k}=[pane1Gap+tCumWide(k)-butnShift{1}, tabFrameTopbase, tButWide(k), tabButHigh];
   end
   pc{tab}=pc{tab}+[0,0,0,2];           % enlarge the current tab button
   set( hData.TabButton, {'Position'}, pc' );
   
   % Move TabSel position
   oldtab=get(hData.TabSel,'Userdata');
   set( hData.TabSel, 'Position', [pane1Gap+tCumWide(oldtab)-butnShift{1}, tabFrameTopbase-selHigh/2, tButWide(oldtab)-1, selHigh] );
   
case 'unitTl_scroll'
   % Get handle data
   hData=get(figId, 'Userdata');
   
   % Which Tab are we in? (in fact it might be better to store these in hData)
   tab=get( hData.TabSel, 'Userdata' );
   PnS=get(hData.TabButton(tab),'Userdata'); % [panelWide;panelHigh;pnlRTWide;pnlCTHigh]
   htOff=get(hData.Scroll(1),'Userdata'); % for panel height positioning
   
   % Get object positions wrt fig & wrt panel
   ObjPos=hData.Tab(tab).oPos;
   
   % Get horiz scroll value
   sclH=get(hData.Scroll(1), 'Value');
   
   % Set panel offsets
   pnlOff=[PnS(3)+pane1Gap-sclH htOff(1) 0 htOff(3)];
   
   % Set Object positions
   pos=num2cell( [ObjPos + ones(size(ObjPos,1),1)*pnlOff ] ,2);
   set( hData.Tab(tab).Object, {'Position'}, pos );
   
   % Get title positions wrt fig &  wrt panel & set Title positions
   if ~isempty(hData.Tab(tab).CTitle),
      CTPos=hData.Tab(tab).ctPos;
      pos=num2cell( [CTPos + ones(size(CTPos,1),1)*[pnlOff(1),htOff(2),0,0] ] ,2);
      set( hData.Tab(tab).CTitle, {'Position'}, pos );
   end

case 'unitTl_OkClick'
   % If output required, just trigger completion
   % ElseIf no output required & no 'calc', just kill
   % Else just evaluate
   
   % Get handle data
   hData=get(figId, 'Userdata');

   % Get OK button Userdata - delete?
   del=get(hData.Pane2(2),'Userdata');
   if strcmp(del,'delete'),
      if ~hData.Calc,
         delete(figId);
         return;
      end
   else
      % Only trigger exit if no 'calc' option
      tab=get( hData.TabSel, 'Userdata' );
      set(gcbo,'Userdata',tab);  % Set OK button Userdata to trigger dialog completion
   end
   
   unittool('unitTl_Recalc',figId);
   
case 'unitTl_CnlClick'
   % Get OK button from handle data
   hData=get(figId, 'Userdata');
   
   % Get OK Userdata
   del=get(hData.Pane2(2),'Userdata');
   if strcmp(del,'delete'),
      delete(figId);
      return;
   end
   
   % Set OK button Userdata & release dialog
   set(hData.Pane2(2),'Userdata',0);
   
otherwise
   
%=========================================================================
% INPUT PARAMETER CHECKS
%=========================================================================
% Check parameter list
%-------------------------------------------------------------------------
error(nargchk(0,2,nargin));

%------------------------------------------------------------------------
% Set arrays to match unitconversion function
%-------------------------------------------------------------------------
unitTag  = {'Angle';'Area';'Density';'Energy';'Flow';'FlowNum';'Force'...
      ;'Freq';'FuelCons';'Inertia';'Length';'Vel';'Mass';'Power';'Press'...
      ;'SpecHeat';'Temp';'KinVis';'Volume'};
unitTit = {'Angle';'Area';'Density';'Energy & Torque';'Flow (Vol or Mass) Assumes sg=1'...
      ;'Flow Number';'Force';'Frequency';'Fuel Consumption';'Inertia'...
      ;'Length';'Linear Velocity';'Mass';'Power';'Pressure & Stress';'Specific Heat'...
      ;'Temperature';'Kinematic Viscosity';'Volume'};
angUnit = {'cycle';'rad';'deg';'min';'sec'};
areaUnit = {'km2';'hectare';'m2';'cm2';'mm2';'mile2';'acre';'ft2';'in2'};
densUnit = {'tonne/m3';'kg/m3';'sg';'lb/in3';'lb/ft3';'lb/i-gal';'lb/us-gal';'slug/ft3'};
energyUnit = {'MJ';'J (Nm)';'kW.hr';'cal';'Chu';'therm';'Btu';'ft.lbf';'hp.s'};
flowUnit = {'m3/s';'litre/s';'cc/s';'in3/s';'gal/hr';'kg/s';'lb/s';'lb/hr'};
flwNmUnit = {'cc/s / sq(kPa)';'cc/s / sq(bar)';'gph / sq(psi)';'in3/s / sq(psi)'};
forceUnit = {'bar.m2';'kN';'N';'kPa.mm2';'dyne';'kgf';'tonf';'lbf';'poundal'};
freqUnit = {'1/ms';'Hz';'rad/s';'deg/s';'rpm';'1/hour';'1/day'};
fuCnsUnit = {'100km/l';'km/l';'m/l';'mi/i-gal';'mi/us-gal'};
inertUnit = {'kg.m2';'lb.ft2';'lb.in2'};
lenUnit = {'km';'m';'cm';'mm';'n-mile';'mile';'yard';'ft';'in'};
velUnit = {'km/s';'km/hr';'m/s';'m/min';'m/hr';'knot';'mph';'ft/s';'ft/hr'};
massUnit = {'tonne';'kg';'g';'ton';'slug';'stone';'lb';'oz';'dr'};
pwrUnit = {'kW';'W';'Chu/s';'Btu/s';'Btu/hr';'ft.lbf/s';'PS';'hp'};
pressUnit = {'MPa';'bar';'kPa';'Pa';'atm';'ton/in2';'psi';'mm(Hg)'};
specHtUnit = {'kJ / kg.K';'J / kg.K';'Chu / lb.K';'Btu / lb.R';'hp.s / lb.K';'ft.lbf / lb.R'};
tempUnit = {'K';'C';'R';'F'};
knVsUnit = {'m2/s';'cm2/s';'cStoke';'ft2/s';'in2/s'};
volUnit = {'m3';'litre';'cm3';'mm3';'ft3';'in3';'i-gal';'pint';'us-gal'};

%------------------------------------------------------------------------
% Convert the arrays & data for input into dialog
%-------------------------------------------------------------------------
[strItems(1:19).tag]=deal(unitTag{:});
[strItems(1:19).title]=deal(unitTit{:});
[strItems(1:19).name]=deal({'Input Unit','Output Unit'});
celList={angUnit,areaUnit,densUnit,energyUnit,flowUnit,flwNmUnit,...
   forceUnit,freqUnit,fuCnsUnit,inertUnit,lenUnit,velUnit,massUnit,...
   pwrUnit,pressUnit,specHtUnit,tempUnit,knVsUnit,volUnit};
for t=1:19,
   [strItems(t).list(1:2)]=deal(celList(t));  %choice items
end
[strItems(1:19).mode]=deal([1,1]);            %mode all single
for t=1:19,
   selDeft(t).index={1,1};                    %empty default - set later
end
if nargout<1,
   figNam = 'Unit Conversion Tool';
else
   figNam = 'Unit Conversion Dialog';
end
selMode = 1;

%-------------------------------------------------------------------------
% Set ItemStruct sizes
%-------------------------------------------------------------------------
nTabs=length(strItems);

% Always 2 choice items
for t=1:nTabs,
   nCols(t)=2;
end

% Initial settings
if nargin>0 & isnumeric(fragIn) & length(fragIn)>2,
	iniTab=min(fragIn(3),19);
	iniIn=min(fragIn(1),length(strItems(iniTab).list{1}));
	iniOut=min(fragIn(2),length(strItems(iniTab).list{2}));
	[selDeft(iniTab).index]=deal({iniIn,iniOut});
	iniSel=iniTab;
	calc=0; 
elseif nargin==1 & strcmp(lower(fragIn),'calc'), 
   iniSel=1;
   calc=1; 
else
   iniSel=1;
   calc=0;
end

if nargin>1 & strcmp(lower(figId),'calc'),
   calc=1; 
end;

%=========================================================================
% BUILD THE GUI
%=========================================================================
% Create a generically-sized invisible figure window
%-------------------------------------------------------------------------
% Note that this needs to be invisible at first & will be moved & shown later on.
inoutFig = figure('Units'      ,dlgUnits, ...
                  'NumberTitle'  ,'off', ...
                  'IntegerHandle','off', ...
                  'MenuBar'      ,'none',...
                  'Name'         ,figNam, ...
                  'Visible'      ,'off', ...
                  'Color'        ,tabColor,...
                  'Colormap'     ,[]);

%-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
% Add contents of the scrolled panels 
%-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
% Make the nCols choice lists per tab
%------------------------------------------------------------------------
for t=1:nTabs,
	%listText=strItems{t+1};
   hChoice=[];
	for c=1:nCols(t),
		hChoice(c) = uicontrol( ...
                    'Style'     ,'listbox',...
                    'Units'     ,dlgUnits, ...
                    'Min'       ,0, ...
                    'Max'       ,2, ...
                    'Callback'  ,'unittool(''unitTl_Recalc'',gcbf);', ...
                    'Value'     ,selDeft(t).index{c}, ...
                    'String'    ,strItems(t).list{c} );
	end %For
   
	% Store the contents object handles in a structure
	hTab(t).Object=hChoice;

	% Get Extent for later - Min effects the mode which affects Extent
	oExtTexts{t} = get( hChoice, {'Extent'} );   % get extent 
   % Set the Mode with Min
   set( hChoice, {'Min'}, num2cell(strItems(t).mode') );

end %For

%------------------------------------------------------------------------
% Add the scroll sliders
%------------------------------------------------------------------------
% Note that these will be sized & positioned later on.

hScrollH = uicontrol(...
         'Style','slider',...
         'Units',dlgUnits, ...
         'Min',0,'Max',1 ,...
         'Value',0 , ...
         'Callback','unittool(''unitTl_scroll'',gcbf);',...
         'SliderStep',[0.1 1]);

%------------------------------------------------------------------------
% Add the panelWindow surround frames
%------------------------------------------------------------------------
hPwFrame(1) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',tabColor, 'Foreground',tabColor);  % To frame left text
hPwFrame(2) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',tabColor, 'Foreground',tabColor);  % To frame top text

%------------------------------------------------------------------------
% Add the panel title objects
%------------------------------------------------------------------------
% NB these need to be invisible at first & will be positioned & shown later.

for t=1:nTabs,
   
% Make the Col titles - even if empty
hTitleCol=[]; % re-initialise for this tab
for c = 1 : nCols(t),
   hTitleCol(c) = uicontrol( ...
     'Style'       ,'text', ...
     'String'      ,strItems(t).name(c), ...
     'Units'       ,dlgUnits, ...
     'Horizontal'  ,'center',...
     'Visible'     ,'off',...
     'Background'  ,tabColor );
end % for
hTab(t).CTitle=hTitleCol; % Store panel title handles in structure

%------------------------------------------------------------------------
% Do full size check for objects & titles
%------------------------------------------------------------------------
%  & set panel titles' & objects' Userdata here
% Object extent sizes
oTexts = oExtTexts{t}; 
oTexts = cat( 1, oTexts{:} );
oWides = oTexts(:,3)';
oHighs = oTexts(:,4);
oMaxWide = max([ones(1,nCols(t))*objWide;oWides])'+ listPad(3);  % calculate the largest width & height
oMaxHigh = max([objHigh;oHighs])+ listPad(4);     % add some blank space around text

% Col Title sizes 
ctTexts = get( hTitleCol, {'Extent'} ); % get ext, convert to nx4 matrix
ctTexts = cat( 1, ctTexts{:} );
ctHigh = max(ctTexts(:,4))+ textPad(4); % one height for all
ctWides = ctTexts(:,3) + textPad(3);    % vector of widths for all
oMaxWide = max(ctWides,oMaxWide);       % stretch prompts if titles large
ctWides = oMaxWide;                     % fit titles if prompts large

% Object Positions
xPos=cumsum( ones(nCols(t),1)*objGap + [0;oMaxWide(1:nCols(t)-1)] );
yPos=objGap;
hTab(t).oPos=[xPos,ones(nCols(t),1)*yPos,oMaxWide,ones(nCols(t),1)*oMaxHigh];

% Col Title positions
ctPos=[xPos,zeros(nCols(t),1),ctWides,ones(nCols(t),1)*ctHigh];
hTab(t).ctPos=ctPos;     % Store panel title size & pos in structure

% Set panel size for objects & Titles
panelWide(t)=xPos(nCols(t))-xPos(1)+oMaxWide(nCols(t))+2*objGap;
panelHigh(t)=oMaxHigh+2*objGap;
pnlRTWide(t)=1; %delete this?
pnlCTHigh(t)=ctHigh;

end %for

%------------------------------------------------------------------------
% Add the panel title end frames
%------------------------------------------------------------------------
hTitFrame(1) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',tabColor, 'Foreground',tabColor);  % To cover bottom left
hTitFrame(2) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',tabColor, 'Foreground',tabColor);  % To frame top left
hTitFrame(3) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',tabColor, 'Foreground',tabColor);  % To frame top right

%-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
% Add rest of the window 
%-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
% Define a box for the tab frame
%------------------------------------------------------------------------
hTabFrame(3) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',dlgColor);  % To frame bottom tab
hTabFrame(4) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',dlgColor);  % To frame top tab

%------------------------------------------------------------------------
% Create tab buttons & selector patch
%------------------------------------------------------------------------
for t=1:nTabs,
   hTabButton(t)=uicontrol('Units',dlgUnits,...
      'Background',dlgColor,...   
      'Callback'  ,'unittool(''unitTl_tabSelect'',gcbf);', ...
      'Userdata'  ,[panelWide(t),panelHigh(t),pnlRTWide(t),pnlCTHigh(t)],...
      'String'    ,strItems(t).tag );
end %for
tTexts=get(hTabButton,{'Extent'});
tTexts = cat( 1, tTexts{:} );        % convert to an n x 4 matrix
tWides = tTexts(:,3) + textPad(3);   % vector of widths for all
tPos=num2cell([ones(nTabs,2),tWides,ones(nTabs,1)],2); %pos & height done later
set(hTabButton,{'Position'},tPos);   % set widths to initialise the tab slider

hTabSel=uicontrol('Style','frame','Units',dlgUnits,...
   'Background',tabColor,'Foreground',tabColor,...   
   'Userdata'  ,iniSel );

hTabSlide=uicontrol('Style','Slider', 'Units',dlgUnits,...
         'Min',0,'Max',nTabs ,...
         'Value',0 , ...
         'Visible','off',...
         'Callback','unittool(''unitTl_scrollTabs'',gcbf);',...
         'Userdata',tWides,...
         'SliderStep',[0.1 1]);
      
hTabFrame(1) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',dlgColor);                         % To frame left tab
hTabFrame(2) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',dlgColor);                         % To frame right tab
hTabFrame(5) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',dlgColor, 'Foreground',dlgColor);  % To cover bottom frame ends
hTabFrame(6) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',dlgColor, 'Foreground',dlgColor);  % To cover scrolled buttons
hTabFrame(7) = uicontrol('Style','frame','Units',dlgUnits, ...
   'Background',dlgColor, 'Foreground',dlgColor);  % To cover scrolled buttons

hTabTitle = uicontrol('Style','text', 'Units',dlgUnits,...
   'Background',tabColor, 'Horizontal','center');  % For title in panel
ttSize = [];

% Set the size of the Tab Title
for t=1:nTabs,
   set(hTabTitle,'String',strItems(t).title); 
   ttSize(t,:)=get(hTabTitle,'Extent') + textPad;
end

%------------------------------------------------------------------------
% Store all handles in a structure for retrieval
%------------------------------------------------------------------------
hData.Tab=hTab;
hData.TabButton=hTabButton;
hData.TabSel=hTabSel;
hData.TabSlide=hTabSlide;
hData.TabTitle=hTabTitle;
hData.TabTitSz=ttSize(:,[3:4]);
[hData.TabTitTx{1:nTabs}]=deal(strItems.title);
hData.PwFrame=hPwFrame;
hData.TitFrame=hTitFrame;
hData.TabFrame=hTabFrame;
hData.Scroll=hScrollH;
hData.Calc=calc;

%------------------------------------------------------------------------
% Create pane 2
%------------------------------------------------------------------------
% Frame & buttons
hOkFrame=uicontrol('Style','frame','Units',dlgUnits,...
   'Background',dlgColor ,'Foreground',dlgColor );

hOkBut=uicontrol('Units',dlgUnits,...
   'Background',dlgColor,...   
   'Callback'  ,'unittool(''unitTl_OkClick'',gcbf);', ...
   'Userdata'  ,-1,...
   'String'    ,'OK' );

hCnlBut=uicontrol('Units',dlgUnits,...
   'Background',dlgColor,...   
   'Callback'  ,'unittool(''unitTl_CnlClick'',gcbf);', ...
   'String'    ,'Cancel' );

% Factor & Offset text boxes
hFacTxt=uicontrol('Units',dlgUnits,...
   'Style','Text',...   
   'Background',bgColor,...   
   'String'    ,'1' );

hOffTxt=uicontrol('Units',dlgUnits,...
   'Style','Text',...   
   'Background',bgColor,...   
   'String'    ,'0' );

hFacTit=uicontrol('Units',dlgUnits,...
   'Style','Text',...   
   'Background',dlgColor,...   
   'String'    ,'Factor' );

hOffTit=uicontrol('Units',dlgUnits,...
   'Style','Text',...   
   'Background',dlgColor,...   
   'String'    ,'Offset' );

% Conversion Calc Controls
hInCalcTxt=uicontrol('Units',dlgUnits,...
   'Style','Edit',...   
   'Background',bgColor,...  
   'Callback'  ,'unittool(''unitTl_Recalc'',gcbf);',...
   'String'    ,'0' );

hOutCalcTxt=uicontrol('Units',dlgUnits,...
   'Style','Text',...   
   'Background',bgColor,...   
   'String'    ,'0' );

hInCalcTit=uicontrol('Units',dlgUnits,...
   'Style','Text',...   
   'Background',dlgColor,...   
   'String'    ,'Input Value' );

hOutCalcTit=uicontrol('Units',dlgUnits,...
   'Style','Text',...   
   'Background',dlgColor,...   
   'String'    ,'Output Value' );

% Set callbacks for figure close & resize
set(inoutFig, 'CloseRequestFcn' ,['unittool(''unitTl_CnlClick'', gcbf);'],...
              'ResizeFcn'       ,['unittool(''unitTl_figResize'',gcbf);']);

%------------------------------------------------------------------------
% Store the handle structure in the figure Userdata
%------------------------------------------------------------------------
hData.Pane2=[hOkFrame, hOkBut, hCnlBut, ...
   hInCalcTxt, hOutCalcTxt, hInCalcTit, hOutCalcTit, ...
   hFacTxt, hOffTxt, hFacTit, hOffTit];

set(inoutFig, 'Userdata', hData);

%------------------------------------------------------------------------
% Calculate sizes & set positions
%------------------------------------------------------------------------
% Retrieve screen dimensions (in correct units)
oldUnits = get(0,'Units');         % remember old units
set( 0, 'Units', dlgUnits );       % convert to desired units
screenSize = get(0,'ScreenSize');  % record screensize
set( 0, 'Units',  oldUnits );      % convert back to old units

% Calc max size required - h & v indicate if srolls are required
reqWide = max(max((panelWide+pnlRTWide),ttSize(:,3)')) + pane1Gap*2;
reqHigh = max(panelHigh+pnlCTHigh) + tabButHigh + max(ttSize(:,4)) +...
   pane1Gap*2 + okHigh*3 + pane2Gap*4 + (okHigh*2+pane2Gap*2)*calc;

h=0;v=0;
if reqHigh>screenSize(4)-winTopGap-winSideGap,
   v=scrollWide;
end
if reqWide+v>screenSize(3)-2*winSideGap,
   winWide=screenSize(3)-2*winSideGap;
   h=scrollWide;
else
   winWide=reqWide+v;
end

if reqHigh+h>screenSize(4)-winTopGap-winSideGap,
   winHigh=screenSize(4)-winTopGap-winSideGap;
else
   winHigh=reqHigh+h;
end

% Perform the window resize - triggers callback
winWide=winWide+0.5; % an annoying bug may lose 0.5 on width
winHigh=winHigh+0.5; % an annoying bug may lose 0.5 on height
set(inoutFig, 'Position', [winSideGap, screenSize(4)-winTopGap-winHigh, winWide, winHigh]);

%=========================================================================
% ACTIVATE
%=========================================================================
% Make figure visible
%------------------------------------------------------------------------
if ~calc, set(hData.Pane2(4:7),{'Visible'},{'off'}); end; % hide calc controls
set( inoutFig, 'Visible','on', 'HandleVisibility','callback' );

%------------------------------------------------------------------------
% Wait for choice to be made (i.e OK button UserData must be assigned)...
%------------------------------------------------------------------------
if nargout>0,
   waitfor(hOkBut,'Userdata');

%------------------------------------------------------------------------
% ...selection has been made. Assign o/p and delete the Selection figure
%------------------------------------------------------------------------
   t = get(hOkBut,'Userdata'); % this is the final tab when ok clicked
	
   if t<=0,
      factor=[];
      offset=[];
      choice=[];
   else
      objValues=get(hData.Tab(t).Object,{'Value'}); % get all list states on this tab
      [factor,offset] = unitconversion(t,objValues{1},objValues{2}); % Calculate units
      choice=[{[objValues{1},objValues{2},t]};celList{t}(objValues{1});celList{t}(objValues{2});unitTag(t)];
   end %if
	
   delete(inoutFig);

else

   set(hOkBut,'Userdata','delete');
   
end %if

end %switch

Contact us