questdlgJWR.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. function ButtonName=questdlg(Question,Title,Btn1,Btn2,Btn3,Default)
  2. % QUESTDLG Question dialog box.
  3. % ButtonName=QUESTDLG(Question) creates a modal dialog box that
  4. % automatically wraps the cell array or string (vector or matrix)
  5. % Question to fit an appropriately sized window. The name of the
  6. % button that is pressed is returned in ButtonName. The Title of
  7. % the figure may be specified by adding a second string argument:
  8. %
  9. % ButtonName=questdlg(Question, Title)
  10. %
  11. % Question will be interpreted as a normal string.
  12. %
  13. % QUESTDLG uses UIWAIT to suspend execution until the user responds.
  14. %
  15. % The default set of buttons names for QUESTDLG are 'Yes','No' and
  16. % 'Cancel'. The default answer for the above calling syntax is 'Yes'.
  17. % This can be changed by adding a third argument which specifies the
  18. % default Button:
  19. %
  20. % ButtonName=questdlg(Question, Title, 'No')
  21. %
  22. % Up to 3 custom button names may be specified by entering
  23. % the button string name(s) as additional arguments to the function
  24. % call. If custom button names are entered, the default button
  25. % must be specified by adding an extra argument, DEFAULT, and
  26. % setting DEFAULT to the same string name as the button you want
  27. % to use as the default button:
  28. %
  29. % ButtonName=questdlg(Question, Title, Btn1, Btn2, DEFAULT);
  30. %
  31. % where DEFAULT is set to Btn1. This makes Btn1 the default answer.
  32. % If the DEFAULT string does not match any of the button string names,
  33. % a warning message is displayed.
  34. %
  35. % To use TeX interpretation for the Question string, a data
  36. % structure must be used for the last argument, i.e.
  37. %
  38. % ButtonName=questdlg(Question, Title, Btn1, Btn2, OPTIONS);
  39. %
  40. % The OPTIONS structure must include the fields Default and Interpreter.
  41. % Interpreter may be 'none' or 'tex' and Default is the default button
  42. % name to be used.
  43. %
  44. % If the dialog is closed without a valid selection, the return value
  45. % is empty.
  46. %
  47. % Example:
  48. %
  49. % ButtonName=questdlg('What is your favorite color?', ...
  50. % 'Color Question', ...
  51. % 'Red', 'Green', 'Blue', 'Green');
  52. % switch ButtonName,
  53. % case 'Red',
  54. % disp('Your favorite color is Red');
  55. % case 'Blue',
  56. % disp('Your favorite color is Blue.')
  57. % case 'Green',
  58. % disp('Your favorite color is Green.');
  59. % end % switch
  60. %
  61. % See also DIALOG, ERRORDLG, HELPDLG, INPUTDLG, LISTDLG,
  62. % MSGBOX, WARNDLG, FIGURE, TEXTWRAP, UIWAIT, UIRESUME.
  63. % Copyright 1984-2010 The MathWorks, Inc.
  64. % $Revision: 5.55.4.17 $
  65. if nargin<1
  66. error('MATLAB:questdlg:TooFewArguments', 'Too few arguments for QUESTDLG');
  67. end
  68. Interpreter='none';
  69. Question=dialogCellstrHelper(Question);
  70. % General Information
  71. Black =[0 0 0 ]/255;
  72. % LightGray =[192 192 192 ]/255;
  73. % LightGray2 =[160 160 164 ]/255;
  74. % MediumGray =[128 128 128 ]/255;
  75. % White =[255 255 255 ]/255;
  76. % Nargin Check
  77. if nargout>1
  78. error('MATLAB:questdlg:WrongNumberOutputs', 'Wrong number of output arguments for QUESTDLG');
  79. end
  80. if nargin==1,Title=' ';end
  81. if nargin<=2, Default='Yes';end
  82. if nargin==3, Default=Btn1 ;end
  83. if nargin<=3, Btn1='Yes'; Btn2='No'; Btn3='Cancel';NumButtons=3;end
  84. if nargin==4, Default=Btn2;Btn2=[];Btn3=[];NumButtons=1;end
  85. if nargin==5, Default=Btn3;Btn3=[];NumButtons=2;end
  86. if nargin==6, NumButtons=3;end
  87. if nargin>6
  88. error('MATLAB:questdlg:TooManyInputs', 'Too many input arguments');NumButtons=3; %#ok
  89. end
  90. if isstruct(Default),
  91. Interpreter=Default.Interpreter;
  92. Default=Default.Default;
  93. end
  94. % Create QuestFig
  95. FigPos=get(0,'DefaultFigurePosition');
  96. FigPos(3)=267;
  97. FigPos(4)=70;
  98. FigPos=getnicedialoglocation(FigPos, get(0,'DefaultFigureUnits'));
  99. QuestFig=dialog(...
  100. 'Visible' ,'off', ...
  101. 'Name' ,Title, ...
  102. 'Pointer' ,'arrow', ...
  103. 'Position' ,FigPos, ...
  104. 'KeyPressFcn' ,@doFigureKeyPress, ...
  105. 'IntegerHandle' ,'off', ...
  106. 'WindowStyle' ,'normal', ...
  107. 'HandleVisibility','callback', ...
  108. 'CloseRequestFcn' ,@doDelete, ...
  109. 'Tag' ,Title ...
  110. );
  111. % Set Positions
  112. DefOffset =10;
  113. IconWidth =54;
  114. IconHeight =54;
  115. IconXOffset=DefOffset;
  116. IconYOffset=FigPos(4)-DefOffset-IconHeight; %#ok
  117. IconCMap=[Black;get(QuestFig,'Color')]; %#ok
  118. DefBtnWidth =56;
  119. BtnHeight =22;
  120. BtnYOffset=DefOffset;
  121. BtnWidth=DefBtnWidth;
  122. ExtControl=uicontrol(...
  123. QuestFig , ...
  124. 'Style' ,'pushbutton', ...
  125. 'String' ,' ' ...
  126. );
  127. btnMargin=1.4;
  128. set(ExtControl,'String',Btn1);
  129. BtnExtent=get(ExtControl,'Extent');
  130. BtnWidth=max(BtnWidth,BtnExtent(3)+8);
  131. if NumButtons > 1
  132. set(ExtControl,'String',Btn2);
  133. BtnExtent=get(ExtControl,'Extent');
  134. BtnWidth=max(BtnWidth,BtnExtent(3)+8);
  135. if NumButtons > 2
  136. set(ExtControl,'String',Btn3);
  137. BtnExtent=get(ExtControl,'Extent');
  138. BtnWidth=max(BtnWidth,BtnExtent(3)*btnMargin);
  139. end
  140. end
  141. BtnHeight=max(BtnHeight,BtnExtent(4)*btnMargin);
  142. delete(ExtControl);
  143. MsgTxtXOffset=IconXOffset+IconWidth;
  144. FigPos(3)=max(FigPos(3),MsgTxtXOffset+NumButtons*(BtnWidth+2*DefOffset));
  145. set(QuestFig,'Position',FigPos);
  146. BtnXOffset=zeros(NumButtons,1);
  147. if NumButtons==1,
  148. BtnXOffset=(FigPos(3)-BtnWidth)/2;
  149. elseif NumButtons==2,
  150. BtnXOffset=[MsgTxtXOffset FigPos(3)-DefOffset-BtnWidth];
  151. elseif NumButtons==3,
  152. BtnXOffset=[MsgTxtXOffset 0 FigPos(3)-DefOffset-BtnWidth];
  153. BtnXOffset(2)=(BtnXOffset(1)+BtnXOffset(3))/2;
  154. end
  155. MsgTxtYOffset=DefOffset+BtnYOffset+BtnHeight;
  156. % Calculate current msg text width and height. If negative,
  157. % clamp it to 1 since its going to be recalculated/corrected later
  158. % based on the actual msg string
  159. MsgTxtWidth=max(1, FigPos(3)-DefOffset-MsgTxtXOffset-IconWidth);
  160. MsgTxtHeight=max(1, FigPos(4)-DefOffset-MsgTxtYOffset);
  161. MsgTxtForeClr=Black;
  162. MsgTxtBackClr=get(QuestFig,'Color');
  163. CBString='uiresume(gcbf)';
  164. DefaultValid=false;
  165. DefaultWasPressed=false;
  166. BtnHandle=cell(NumButtons, 1);
  167. DefaultButton=0;
  168. % Check to see if the Default string passed does match one of the
  169. % strings on the buttons in the dialog. If not, throw a warning.
  170. for i=1:NumButtons
  171. switch i
  172. case 1
  173. ButtonString=Btn1;
  174. ButtonTag='Btn1';
  175. if strcmp(ButtonString, Default)
  176. DefaultValid=true;
  177. DefaultButton=1;
  178. end
  179. case 2
  180. ButtonString=Btn2;
  181. ButtonTag='Btn2';
  182. if strcmp(ButtonString, Default)
  183. DefaultValid=true;
  184. DefaultButton=2;
  185. end
  186. case 3
  187. ButtonString=Btn3;
  188. ButtonTag='Btn3';
  189. if strcmp(ButtonString, Default)
  190. DefaultValid=true;
  191. DefaultButton=3;
  192. end
  193. end
  194. BtnHandle{i}=uicontrol(QuestFig, ...
  195. 'Style' ,'pushbutton', ...
  196. 'Position' ,[ BtnXOffset(1) BtnYOffset BtnWidth BtnHeight ], ...
  197. 'KeyPressFcn' ,@doControlKeyPress, ...
  198. 'Callback' ,CBString, ...
  199. 'String' ,ButtonString, ...
  200. 'HorizontalAlignment','center', ...
  201. 'Tag' ,ButtonTag...
  202. );
  203. end
  204. if ~DefaultValid
  205. warnstate=warning('backtrace','off');
  206. warning('MATLAB:QUESTDLG:stringMismatch','Default string does not match any button string name.');
  207. warning(warnstate);
  208. end
  209. MsgHandle=uicontrol(QuestFig, ...
  210. 'Style' ,'text', ...
  211. 'Position' ,[MsgTxtXOffset MsgTxtYOffset 0.95*MsgTxtWidth MsgTxtHeight ], ...
  212. 'String' ,{' '}, ...
  213. 'Tag' ,'Question', ...
  214. 'HorizontalAlignment','left', ...
  215. 'FontWeight' ,'bold', ...
  216. 'BackgroundColor' ,MsgTxtBackClr, ...
  217. 'ForegroundColor' ,MsgTxtForeClr ...
  218. );
  219. [WrapString,NewMsgTxtPos]=textwrap(MsgHandle,Question,75);
  220. % NumLines=size(WrapString,1);
  221. AxesHandle=axes('Parent',QuestFig,'Position',[0 0 1 1],'Visible','off');
  222. texthandle=text( ...
  223. 'Parent' ,AxesHandle , ...
  224. 'Units' ,'pixels' , ...
  225. 'Color' ,get(BtnHandle{1},'ForegroundColor') , ...
  226. 'HorizontalAlignment' ,'left' , ...
  227. 'FontName' ,get(BtnHandle{1},'FontName') , ...
  228. 'FontSize' ,get(BtnHandle{1},'FontSize') , ...
  229. 'VerticalAlignment' ,'bottom' , ...
  230. 'String' ,WrapString , ...
  231. 'Interpreter' ,Interpreter , ...
  232. 'Tag' ,'Question' ...
  233. );
  234. textExtent=get(texthandle, 'Extent');
  235. % (g357851)textExtent and extent from uicontrol are not the same. For window, extent from uicontrol is larger
  236. % than textExtent. But on Mac, it is reverse. Pick the max value.
  237. MsgTxtWidth=max([MsgTxtWidth NewMsgTxtPos(3)+2 textExtent(3)]);
  238. MsgTxtHeight=max([MsgTxtHeight NewMsgTxtPos(4)+2 textExtent(4)]);
  239. MsgTxtXOffset=IconXOffset+IconWidth+DefOffset;
  240. FigPos(3)=max(NumButtons*(BtnWidth+DefOffset)+DefOffset, ...
  241. MsgTxtXOffset+MsgTxtWidth+DefOffset);
  242. % Center Vertically around icon
  243. if IconHeight>MsgTxtHeight,
  244. IconYOffset=BtnYOffset+BtnHeight+DefOffset;
  245. MsgTxtYOffset=IconYOffset+(IconHeight-MsgTxtHeight)/2;
  246. FigPos(4)=IconYOffset+IconHeight+DefOffset;
  247. % Center around text
  248. else
  249. MsgTxtYOffset=BtnYOffset+BtnHeight+DefOffset;
  250. IconYOffset=MsgTxtYOffset+(MsgTxtHeight-IconHeight)/2;
  251. FigPos(4)=MsgTxtYOffset+MsgTxtHeight+DefOffset;
  252. end
  253. if NumButtons==1
  254. BtnXOffset=(FigPos(3)-BtnWidth)/2;
  255. elseif NumButtons==2
  256. BtnXOffset=[(FigPos(3)-DefOffset)/2-BtnWidth (FigPos(3)+DefOffset)/2];
  257. elseif NumButtons==3
  258. BtnXOffset(2)=(FigPos(3)-BtnWidth)/2;
  259. BtnXOffset=[BtnXOffset(2)-DefOffset-BtnWidth BtnXOffset(2) BtnXOffset(2)+BtnWidth+DefOffset];
  260. end
  261. set(QuestFig ,'Position',getnicedialoglocation(FigPos, get(QuestFig,'Units')));
  262. assert(iscell(BtnHandle));
  263. BtnPos=cellfun(@(bh)get(bh,'Position'), BtnHandle, 'UniformOutput', false);
  264. BtnPos=cat(1,BtnPos{:});
  265. BtnPos(:,1)=BtnXOffset;
  266. BtnPos=num2cell(BtnPos,2);
  267. assert(iscell(BtnPos));
  268. cellfun(@(bh,pos)set(bh, 'Position', pos), BtnHandle, BtnPos, 'UniformOutput', false);
  269. if DefaultValid
  270. setdefaultbutton(QuestFig, BtnHandle{DefaultButton});
  271. end
  272. delete(MsgHandle);
  273. set(texthandle, 'Position',[MsgTxtXOffset MsgTxtYOffset 0]);
  274. IconAxes=axes(...
  275. 'Parent' ,QuestFig , ...
  276. 'Units' ,'Pixels' , ...
  277. 'Position' ,[IconXOffset IconYOffset IconWidth IconHeight], ...
  278. 'NextPlot' ,'replace' , ...
  279. 'Tag' ,'IconAxes' ...
  280. );
  281. set(QuestFig ,'NextPlot','add');
  282. load dialogicons.mat questIconData questIconMap;
  283. IconData=questIconData;
  284. questIconMap(256,:)=get(QuestFig,'Color');
  285. IconCMap=questIconMap;
  286. Img=image('CData',IconData,'Parent',IconAxes);
  287. set(QuestFig, 'Colormap', IconCMap);
  288. set(IconAxes, ...
  289. 'Visible','off' , ...
  290. 'YDir' ,'reverse' , ...
  291. 'XLim' ,get(Img,'XData'), ...
  292. 'YLim' ,get(Img,'YData') ...
  293. );
  294. % Make sure we are on screen
  295. movegui(QuestFig)
  296. set(QuestFig ,'WindowStyle','modal','Visible','on');
  297. drawnow;
  298. if DefaultButton ~=0
  299. uicontrol(BtnHandle{DefaultButton});
  300. end
  301. if ishghandle(QuestFig)
  302. % Go into uiwait if the figure handle is still valid.
  303. % This is mostly the case during regular use.
  304. uiwait(QuestFig);
  305. end
  306. % Check handle validity again since we may be out of uiwait because the
  307. % figure was deleted.
  308. if ishghandle(QuestFig)
  309. if DefaultWasPressed
  310. ButtonName=Default;
  311. else
  312. ButtonName=get(get(QuestFig,'CurrentObject'),'String');
  313. end
  314. doDelete;
  315. else
  316. ButtonName='';
  317. end
  318. function doFigureKeyPress(obj, evd) %#ok
  319. switch(evd.Key)
  320. case {'return','space'}
  321. if DefaultValid
  322. DefaultWasPressed=true;
  323. uiresume(gcbf);
  324. end
  325. case 'escape'
  326. doDelete
  327. end
  328. end
  329. function doControlKeyPress(obj, evd) %#ok
  330. switch(evd.Key)
  331. case {'return'}
  332. if DefaultValid
  333. DefaultWasPressed=true;
  334. uiresume(gcbf);
  335. end
  336. case 'escape'
  337. doDelete
  338. end
  339. end
  340. function doDelete(varargin)
  341. delete(QuestFig);
  342. end
  343. end