0001
0002 function hh = uitabpanel(varargin)
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 tag = '';
0060 units = 'normalized';
0061 position = [0,0,1,1];
0062 fontweight = 'normal';
0063 [style,type] = deal('lefttop',2);
0064 visible = 'on';
0065
0066 foregroundcolor = [1,1,1];
0067 backgroundcolor = [0.7725,0.8431,0.9608];
0068 panelbackgroundcolor = [0.4314,0.5882,0.8431];
0069 titlehighlightcolor = [1,0.8,0];
0070
0071 horizontalalignment = 'center';
0072 [createfcn,deletefcn,resizefcn] = deal({},{},{});
0073
0074 active = 0;
0075 styles = {'popup','lefttop','righttop','leftbottom','rightbottom', ...
0076 'centertop','centerbottom'};
0077
0078 for k=1:2:nargin
0079 property = lower(varargin{k});
0080 value = varargin{k+1};
0081 switch property
0082 case {'style','tabposition','titleposition'}
0083 style = value;
0084 type = strmatch(lower(style),styles);
0085 if isempty(type)
0086 error(['Bad value for Style/TitlePosition property: ' style '.']);
0087 end
0088 case 'fontsize'
0089 fontsize = value;
0090 case {'title','string'}
0091 string = value;
0092 ntab = length(string);
0093 case {'frameposition','position'}
0094 position = value;
0095 case {'framebackgroundcolor','backgroundcolor'}
0096 backgroundcolor = value;
0097 case {'framebordertype','bordertype'}
0098 bordertype = value;
0099 case {'panelheights','heights'}
0100 panelheight = value;
0101 case {'titleforegroundcolor','foregroundcolor'}
0102 foregroundcolor = value;
0103 case {'selecteditem','active'}
0104 active = value;
0105 otherwise
0106 eval([property '= value;']);
0107 end
0108 end
0109
0110 if ~exist('parent','var')
0111 parent = gcf;
0112 end
0113 if ~exist('margins','var')
0114 if type==1
0115 margins = {[1.5,0.75,1.5,1],'characters'};
0116 else
0117 margins = {1,'pixels'};
0118 end
0119 end
0120 if ~iscell(margins)
0121 margins = {margins,units};
0122 end
0123
0124 if ~exist('bordertype','var')
0125 if type==1
0126 bordertype = 'etchedin';
0127 else
0128 bordertype = 'none';
0129 end
0130 end
0131
0132 if ~exist('titlebackgroundcolor','var')
0133 titlebackgroundcolor = 0.95*panelbackgroundcolor;
0134 end
0135
0136 cmenu = uicontextmenu;
0137 uimenu(cmenu,'Label','Goto Tab');
0138 uimenu(cmenu,'Separator','on');
0139
0140 htab = uipanel( ...
0141 'Parent',parent, ...
0142 'Units',units, ...
0143 'Position',position, ...
0144 'DeleteFcn',deletefcn, ...
0145 'ResizeFcn',resizefcn, ...
0146 'BackgroundColor',backgroundcolor, ...
0147 'BorderType',bordertype, ...
0148 'UIContextMenu',cmenu, ...
0149 'Visible',visible, ...
0150 'FontSize', fontsize,...
0151 'Tag',tag);
0152 set(htab,'Units','pixels');
0153 tabpos = get(htab,'Position');
0154
0155 status = uicontainer( ...
0156 'Parent',htab, ...
0157 'BackgroundColor',backgroundcolor, ...
0158 'Units',margins{2}, ...
0159 'Position',[1,1,1,1], ...
0160 'UIContextMenu',cmenu, ...
0161 'Visible','off');
0162 set(status,'Units','pixels');
0163 charsz = get(status,'Position');
0164 margins = [charsz(1:2),charsz(1:2)].*margins{1};
0165 set(status,'Units','characters');
0166 set(status,'Position',[1,1,1,1]);
0167 set(status,'Units','pixels');
0168 charsz = get(status,'Position');
0169 titleheight = 2*charsz(4);
0170
0171 if type==1
0172
0173
0174
0175 panelpos = tabpos;
0176 titlepos = [margins(1),tabpos(2)+tabpos(4)-titleheight-margins(2), ...
0177 tabpos(3)-sum(margins([1,3])),titleheight];
0178 ttextpos = [0.05,0.1,0.9,0.76];
0179
0180 if ~exist('panelheight','var')
0181 panelheight = ones(1,ntab);
0182 end
0183 if ~exist('panelbordertype','var')
0184 panelbordertype = 'line';
0185 end
0186
0187 for k=1:ntab
0188 title(k) = uicontrol( ...
0189 'Parent',htab, ...
0190 'Units','pixels', ...
0191 'Position',titlepos, ...
0192 'ForegroundColor',foregroundcolor, ...
0193 'BackgroundColor',titlebackgroundcolor, ...
0194 'FontWeight',fontweight, ...
0195 'FontSize', fontsize,...
0196 'HorizontalAlignment',horizontalalignment, ...
0197 'Callback',{@PopupTabCbk,k}, ...
0198 'Style','toggle', ...
0199 'String',string{k}, ...
0200 'Value',0, ...
0201 'Visible','on');
0202
0203 panel(k) = uipanel( ...
0204 'Parent',htab, ...
0205 'Units','pixels', ...
0206 'Position',titlepos+[0,0,0,panelheight(k)*charsz(4)], ...
0207 'BackgroundColor',panelbackgroundcolor, ...
0208 'BorderType',panelbordertype, ...
0209 'Visible','off');
0210
0211 uimenu(cmenu, ...
0212 'Label',string{k}, ...
0213 'Callback',{@PopupTabCbk,k});
0214 end
0215
0216 uimenu(cmenu,'Separator','on');
0217 uimenu(cmenu, ...
0218 'Label','Expand All', ...
0219 'Callback',{@PopupTabEnableAllCbk,'on'});
0220 uimenu(cmenu, ...
0221 'Label','Collapse All', ...
0222 'Callback',{@PopupTabEnableAllCbk,'off'});
0223
0224 sliderpos = [tabpos(3)-14,2,15,tabpos(4)-3];
0225 slider = uicontrol( ...
0226 'Parent',htab, ...
0227 'Units','pixels', ...
0228 'Position',sliderpos, ...
0229 'BackgroundColor',panelbackgroundcolor, ...
0230 'Style','slider', ...
0231 'Callback',@PopupTabSliderCbk, ...
0232 'Value',0, ...
0233 'Min',-1, ...
0234 'Max',0, ...
0235 'Visible','off');
0236
0237 statuspos = titlepos;
0238 statuspos([2,4]) = [margins(4),panelpos(4)-(ntab+1)*(margins(4)+titlepos(4))];
0239 set(status,'Position',statuspos);
0240 PopupTabCbk(title(1),[],active);
0241 set(status,'ResizeFcn',@PopupTabResizeCbk);
0242
0243 else
0244
0245
0246
0247 margins(3:4) = -(margins(1:2)+margins(3:4));
0248 switch type
0249 case 2
0250 [loop,sign] = deal(1:ntab,[1,0,1,0]);
0251 case 3
0252 [loop,sign] = deal(ntab:-1:1,[ntab,0,0,0]);
0253 case 4
0254 [loop,sign] = deal(1:ntab,[1,0,1,1]);
0255 case 5
0256 [loop,sign] = deal(ntab:-1:1,[ntab,0,0,1]);
0257 case 6
0258 [loop,sign] = deal(1:ntab,[1,ntab,1,0]);
0259 case 7
0260 [loop,sign] = deal(1:ntab,[1,ntab,1,1]);
0261 end
0262 addtitle = 2*[sign(3:4),-1,-1];
0263 if sign(3)
0264 ttextpos = [0.05,0.08,0.9,0.76];
0265 else
0266 ttextpos = [0.05,0.05,0.9,0.76];
0267 end
0268
0269 if ~exist('panelbordertype','var')
0270 panelbordertype = 'beveledout';
0271 end
0272
0273 for k=1:ntab
0274 title(k) = uipanel( ...
0275 'Parent',htab, ...
0276 'Units','pixels', ...
0277 'BackgroundColor',titlebackgroundcolor, ...
0278 'BorderType',panelbordertype, ...
0279 'ButtonDownFcn',{@TopBottomTabCbk,k}, ...
0280 'Visible','on');
0281
0282
0283 ttext(k) = uicontrol( ...
0284 'Parent',title(k), ...
0285 'Units','normalized', ...
0286 'Position',ttextpos, ...
0287 'ForegroundColor',foregroundcolor, ...
0288 'BackgroundColor',titlebackgroundcolor, ...
0289 'HorizontalAlignment',horizontalalignment, ...
0290 'Style','text', ...
0291 'String',string{k}, ...
0292 'Enable','inactive', ...
0293 'FontSize', fontsize,...
0294 'HitTest','off',...
0295 'Visible','on');
0296
0297 panel(k) = uipanel( ...
0298 'Parent',htab, ...
0299 'Units','pixels', ...
0300 'BackgroundColor',panelbackgroundcolor, ...
0301 'BorderType',panelbordertype, ...
0302 'Visible','off');
0303
0304 uimenu(cmenu, ...
0305 'Label',string{k}, ...
0306 'Callback',{@TopBottomTabCbk,k});
0307 end
0308
0309 if ~active, active = 1; end
0310 set(panel(active),'Visible','on');
0311
0312 inset(1) = uicontrol( ...
0313 'Parent',htab, ...
0314 'Units','pixels', ...
0315 'BackgroundColor',panelbackgroundcolor, ...
0316 'Style','text', ...
0317 'Visible','on');
0318 if ~isnan(titlehighlightcolor)
0319 inset(2) = uicontrol( ...
0320 'Parent',htab, ...
0321 'Units','pixels', ...
0322 'BackgroundColor',titlehighlightcolor, ...
0323 'Style','text', ...
0324 'Visible','on');
0325 inset(3) = uicontrol( ...
0326 'Parent',htab, ...
0327 'Units','pixels', ...
0328 'BackgroundColor',0.85*titlehighlightcolor, ...
0329 'Style','text', ...
0330 'Visible','on');
0331 end
0332
0333 TopBottomTabResizeCbk(status,[]);
0334 set(status,'ResizeFcn',@TopBottomTabResizeCbk);
0335 end
0336
0337 setappdata(htab,'panels',panel);
0338 setappdata(htab,'status',status);
0339 if ~isempty(createfcn)
0340 createfcn(htab,[],panel,status);
0341 end
0342
0343 if nargout, hh = htab; end
0344
0345
0346
0347
0348
0349 function PopupTabCbk(hobj,evdt,indx)
0350
0351 set(title,'Value',0);
0352 if indx>0
0353 indxvis = strcmp(get(panel(indx),'Visible'),'off');
0354 if indxvis
0355 set(panel(indx),'Visible','on');
0356 else
0357 set(panel(indx),'Visible','off');
0358 end
0359 end
0360 if isempty(strmatch('on',get(panel,'Visible')))
0361 set(status,'Visible','on');
0362 else
0363 set(status,'Visible','off');
0364 end
0365
0366 currval = get(slider,'Value');
0367 if currval<0
0368 set(slider,'Value',0);
0369 PopupTabSliderCbk(slider,evdt);
0370 end
0371 titlepos = get(title(1),'Position');
0372 addtolen = titlepos(2)+titlepos(4)+margins(4);
0373
0374 for k=1:ntab
0375 titlepos = get(title(k),'Position');
0376 titlepos(2) = addtolen-titlepos(4)-margins(4);
0377 set(title(k),'Position',titlepos);
0378 addtolen = titlepos(2);
0379 visible = strcmp(get(panel(k),'Visible'),'on');
0380 if visible
0381 panelpos = get(panel(k),'Position');
0382 addtolen = addtolen-panelpos(4);
0383 panelpos(2) = addtolen;
0384 set(panel(k),'Position',panelpos);
0385 end
0386 end
0387
0388 if visible
0389 botpos = get(panel(ntab),'Position');
0390 else
0391 botpos = get(title(ntab),'Position');
0392 end
0393
0394 visible = strcmp(get(slider,'Visible'),'on');
0395 addwidth = (-1)^(~visible);
0396 if botpos(2)*addwidth>0
0397 if visible
0398 set(slider,'Visible','off');
0399 else
0400 set(slider,'Visible','on');
0401 end
0402 else
0403 if visible
0404 addwidth = 0;
0405 else
0406 return;
0407 end
0408 end
0409
0410 addwidth = addwidth*sliderpos(3);
0411 for k=1:ntab
0412 titlepos = get(title(k),'Position');
0413 titlepos(3) = titlepos(3)+addwidth;
0414 set(title(k),'Position',titlepos);
0415 set(title(k),'UserData',titlepos(2));
0416
0417 panelpos = get(panel(k),'Position');
0418 panelpos(3) = panelpos(3)+addwidth;
0419 set(panel(k),'Position',panelpos);
0420 set(panel(k),'UserData',panelpos(2));
0421 end
0422
0423 toplen = botpos(2)-margins(2);
0424 if toplen>0
0425 set(slider,'Value',0);
0426 return;
0427 end
0428
0429 try
0430 if indxvis
0431 viewpos = get(panel(indx),'Position');
0432 if viewpos(2)-viewpos(4)<0
0433 if viewpos(4)+margins(4)<=tabpos(4);
0434 currval = min(0,viewpos(2)-margins(4)/2);
0435 else
0436 viewpos = get(title(indx),'Position');
0437 currval = viewpos(2)+viewpos(4)+margins(4)/2-tabpos(4);
0438 end
0439 end
0440 end
0441 catch
0442 end
0443
0444 set(slider,'Min',toplen);
0445 set(slider,'Value',max(currval,toplen));
0446 set(slider,'SliderStep',[0.3,1]/max(1,-toplen/100));
0447 PopupTabSliderCbk(slider,evdt);
0448
0449 end
0450
0451
0452
0453 function PopupTabSliderCbk(hobj,evdt)
0454
0455 currval = get(hobj,'Value');
0456 for k=1:ntab
0457 titlepos = get(title(k),'Position');
0458 titlepos(2) = get(title(k),'UserData')-currval;
0459 set(title(k),'Position',titlepos);
0460 panelpos = get(panel(k),'Position');
0461 panelpos(2) = get(panel(k),'UserData')-currval;
0462 set(panel(k),'Position',panelpos);
0463 end
0464
0465 end
0466
0467
0468
0469 function PopupTabEnableAllCbk(hobj,evdt,cstr)
0470
0471 set(panel,'Visible',cstr);
0472 PopupTabCbk(hobj,evdt,0);
0473
0474 end
0475
0476
0477
0478 function PopupTabResizeCbk(hobj,evdt)
0479
0480 oldpos = tabpos;
0481 units = get(htab,'Units');
0482 set(htab,'Units','pixels');
0483 tabpos = get(htab,'Position');
0484 set(htab,'Units',units);
0485
0486 addtopos = tabpos-oldpos;
0487 sliderpos([1,2,4]) = sliderpos([1,2,4])+addtopos([1,2,4]);
0488 set(slider,'Position',sliderpos);
0489
0490 addtopos = [tabpos(3:4)-oldpos(3:4),0,0];
0491 currval = get(slider,'Value');
0492 if currval<0
0493 set(slider,'Value',0);
0494 PopupTabSliderCbk(slider,evdt);
0495 end
0496
0497 for k=1:ntab
0498 titlepos = get(title(k),'Position');
0499 set(title(k),'Position',titlepos+addtopos);
0500 end
0501 PopupTabCbk(title(1),evdt,0);
0502
0503 visible = strcmp(get(slider,'Visible'),'on');
0504 if visible & currval<0
0505 set(slider,'Value',max(currval,get(slider,'Min')));
0506 PopupTabSliderCbk(slider,evdt);
0507 end
0508
0509 end
0510
0511
0512
0513
0514
0515 function TopBottomTabCbk(hobj,evdt,indx)
0516
0517 if active==indx, return; end
0518
0519
0520 n = active;
0521 titlepos = get(title(n),'Position');
0522 titlepos = titlepos+addtitle.*[n==sign(1),1,n==sign(1),1];
0523 titlepos(3) = titlepos(3)+addtitle(3)*(n==sign(2));
0524 set(title(n),'Position',titlepos,'BackgroundColor',titlebackgroundcolor);
0525 set(ttext(n),'FontWeight','normal','BackgroundColor',titlebackgroundcolor);
0526 set(panel(n),'Visible','off');
0527
0528
0529 active = indx;
0530 titlepos = get(title(indx),'Position');
0531 titlepos = titlepos-addtitle.*[indx==sign(1),1,indx==sign(1),1];
0532 titlepos(3) = titlepos(3)-addtitle(3)*(indx==sign(2));
0533
0534 set(title(indx),'Position',titlepos,'BackgroundColor',panelbackgroundcolor);
0535 set(ttext(indx),'FontWeight','bold','BackgroundColor',panelbackgroundcolor);
0536 insetpos = [titlepos(1)+1,titlepos(2)+sign(4)*titlepos(4)-2,titlepos(3)-1,3];
0537 set(inset(1),'Position',insetpos);
0538 try
0539 insetpos = insetpos+[0,(1-2*sign(4))*titleheight+2*sign(4),0,-2];
0540 set(inset(2),'Position',insetpos);
0541 set(inset(3),'Position',insetpos+[2,1-2*sign(4),-4,0]);
0542 catch
0543 end
0544 set(panel(indx),'Visible','on');
0545
0546 if isappdata(htab,'SelectionChangeFcn')
0547 SelectionChangeFcn = getappdata(htab,'SelectionChangeFcn');
0548 eventdata = struct('EventName','SelectionChanged', ...
0549 'OldValue',n,'NewValue',indx,'Panels',panel,'Status',status);
0550 if iscell(SelectionChangeFcn)
0551 SelectionChangeFcn{1}(hobj,eventdata,SelectionChangeFcn{2:end});
0552 else
0553 SelectionChangeFcn(hobj,eventdata);
0554 end
0555 end
0556
0557 end
0558
0559
0560
0561 function TopBottomTabResizeCbk(hobj,evdt)
0562
0563 units = get(htab,'Units');
0564 set(htab,'Units','pixels');
0565 tabpos = get(htab,'Position');
0566 set(htab,'Units',units);
0567
0568 titlepos = [0,0,0,titleheight];
0569 if sign(4)
0570 panelpos = [0,titleheight+1,tabpos(3),tabpos(4)-titleheight]+margins;
0571 titlepos(2) = panelpos(2)-titlepos(4);
0572 else
0573 panelpos = [0,0,tabpos(3),tabpos(4)-titleheight]+margins;
0574 titlepos(2) = panelpos(2)+panelpos(4);
0575 end
0576 set(panel,'Position',panelpos);
0577
0578 n = sum(cellfun('length',string))+2*ntab;
0579 if type<6
0580 if (n+2*ntab)*1.2*charsz(3)+2>panelpos(3)
0581 [loop,sign(1:3)] = deal(1:ntab,[1,ntab,1]);
0582 else
0583 if type==2 | type==4
0584 [loop,sign(1:3)] = deal(1:ntab,[1,0,1]);
0585 else
0586 [loop,sign(1:3)] = deal(ntab:-1:1,[ntab,0,0]);
0587 end
0588 end
0589 addtitle = 2*[sign(3:4),-1,-1];
0590 end
0591 titlepos(1) = panelpos(1)+(1-sign(3))*panelpos(3);
0592 for k=loop
0593 if sign(2)
0594 titlepos(3) = panelpos(3)*(length(string{k})+2)/n;
0595 addtopos = addtitle.*[k==1,1,k==1|k==ntab,1];
0596 else
0597 titlepos(3) = (length(string{k})+4)*1.2*charsz(3);
0598 addtopos = addtitle.*[k==sign(1),1,k==sign(1),1];
0599 end
0600 titlepos(1) = titlepos(1)-(1-sign(3))*titlepos(3);
0601 set(title(k),'Position',titlepos+addtopos);
0602 titlepos(1) = titlepos(1)+sign(3)*titlepos(3);
0603 end
0604
0605 statuspos = titlepos;
0606 statuspos(1) = sign(3)*titlepos(1)+2;
0607 statuspos(3) = titlepos(1)+sign(3)*(tabpos(3)-2*titlepos(1))-4;
0608
0609 titlepos = get(title(active),'Position');
0610 titlepos = titlepos-addtitle.*[active==sign(1),1,active==sign(1),1];
0611 titlepos(3) = titlepos(3)-addtitle(3)*(active==sign(2));
0612 set(title(active),'Position',titlepos,'BackgroundColor',panelbackgroundcolor);
0613 set(ttext(active),'FontWeight','bold','BackgroundColor',panelbackgroundcolor);
0614
0615 insetpos = [titlepos(1)+1,titlepos(2)+sign(4)*titlepos(4)-2,titlepos(3)-1,3];
0616 set(inset(1),'Position',insetpos);
0617 try
0618 insetpos = insetpos+[0,(1-2*sign(4))*titleheight+2*sign(4),0,-2];
0619 set(inset(2),'Position',insetpos);
0620 set(inset(3),'Position',insetpos+[2,1-2*sign(4),-4,0]);
0621 catch
0622 end
0623 try
0624
0625 set(status,'Position',statuspos,'Visible','on');
0626 catch
0627 set(status,'Visible','off');
0628 end
0629
0630 end
0631
0632 end