3131 % Modal (block other figure interaction)
3232 Modal (1 ,1 ) logical = false
3333
34- end % properties
35-
36-
37- properties (AbortSet , Dependent , Access = public )
38-
3934 % Dialog Title
40- Title
35+ Title ( 1 , 1 ) string = " "
4136
4237 end % properties
4338
4439
45- % Accessors
46- methods
47-
48- function set .Modal(obj , value )
49- obj.Modal = value ;
50- obj .updateModalImage();
51- end
52-
53- function value = get .Title(obj )
54- value = string(obj .OuterPanel .Title );
55- end
56- function set .Title(obj , value )
57- obj.OuterPanel.Title = value ;
58- end
59-
60- end % methods
61-
62-
6340 %% Dialog Button Properties
6441 % The dialog subclass can change these values
6542 properties (Dependent )
149126
150127
151128 %% Internal Properties
129+ properties (Hidden )
130+
131+ % Minimum allowable size before cropping
132+ MinimumSize (1 ,2 ) double {mustBePositive } = [30 20 ];
133+
134+ % Buffer border space required on each side when sizing in figure
135+ Buffer (1 ,1 ) double {mustBeNonnegative } = 0
136+
137+ end % properties
138+
139+
152140 properties (Transient , NonCopyable , Hidden , SetAccess = private )
153141
154142 % Outer grid to enable the panel to fill the component
187175 end % properties
188176
189177
178+ %% Constructor
179+ methods
180+
181+ function obj = BaseInternalDialog(fig , varargin )
182+
183+ arguments
184+ fig matlab.ui.Figure
185+ end
186+
187+ arguments (Repeating )
188+ varargin
189+ end
190+
191+ % Get the figure size
192+ posF = getpixelposition(fig );
193+ szFig = posF(3 : 4 );
194+
195+ % Add modal image
196+ modalImage = uiimage(fig );
197+ modalImage.ImageSource = " overlay_gray.png" ;
198+ modalImage.ScaleMethod = " stretch" ;
199+ modalImage.Visible = " off" ;
200+ modalImage.Position = [1 1 szFig ];
201+ modalImage.Tag = " ModalImage" ;
202+
203+ % Call superclass constructor
204+ obj
= [email protected] (
fig , varargin{
: });
205+
206+ % Store the modal background image
207+ obj.ModalImage = modalImage ;
208+
209+ % Update the modal image positioning
210+ obj .updateModalImage();
211+
212+ % Listen to resizing of OuterPanel
213+ % (non needed until we make the dialog resizable by user)
214+ % obj.OuterPanel.ResizeFcn = @(~,~)onOuterPanelResize(obj);
215+
216+ end % function
217+
218+ end % methods
219+
220+
190221 %% Destructor
191222 methods
192223 function delete(obj )
@@ -384,14 +415,8 @@ function assignOutput(~)
384415 function setup(obj )
385416 % Configure the dialog
386417
387- % Disable warning
388- warnState = warning(' off' ,' MATLAB:ui:components:noPositionSetWhenInLayoutContainer' );
389-
390- % Defaults
391- obj .Position(3 : 4 ) = obj .Size ;
392-
393- % Restore warning
394- warning(warnState )
418+ % Store the figure
419+ obj.Figure = ancestor(obj ,' figure' );
395420
396421 % Outer grid to enable the dialog panel to fill the component
397422 obj.OuterGrid = uigridlayout(obj ,[1 1 ]);
@@ -404,7 +429,6 @@ function setup(obj)
404429 obj.OuterPanel.FontWeight = " bold" ;
405430 % obj.OuterPanel.BorderWidth = 1;
406431 obj.OuterPanel.AutoResizeChildren = false ;
407- obj.OuterPanel.ResizeFcn = @(~,~)onOuterPanelResize(obj );
408432 obj.OuterPanel.ButtonDownFcn = @(~,evt )onTitleButtonDown(obj ,evt );
409433
410434 % Close Button
@@ -452,17 +476,9 @@ function setup(obj)
452476 obj .applyCloseButtonColor()
453477
454478 % Listen to figure size changes
455- obj.Figure = ancestor(obj ,' figure' );
456479 obj.FigureResizeListener = listener(obj .Figure ," SizeChanged" ,...
457480 @(~,evt )onFigureResized(obj ,evt ));
458481
459- % Add modal image
460- obj.ModalImage = uiimage(obj .Figure );
461- obj.ModalImage.ImageSource = " overlay_gray.png" ;
462- obj.ModalImage.ScaleMethod = " stretch" ;
463- obj.ModalImage.Visible = " off" ;
464- obj.ModalImage.Position = [1 1 1 1 ];
465-
466482 % Add lower buttons
467483 obj.DialogButtons = wt .ButtonGrid(obj .InnerGrid ," Text" ,[]," Icon" ,[]);
468484 obj.DialogButtons.Layout.Row = 2 ;
@@ -471,41 +487,34 @@ function setup(obj)
471487 obj.DialogButtons.ButtonPushedFcn = ...
472488 @(src ,evt )onDialogButtonPushed(obj ,evt );
473489
490+ % Update component lists
491+ obj.ButtonColorableComponents = [obj .DialogButtons ];
492+ obj.TitleFontStyledComponents = [obj .OuterPanel ];
493+ obj.FontStyledComponents = [obj .DialogButtons ];
494+
474495 % Ensure it fits in the figure
475496 obj .resizeToFitFigure();
476497
477- % Reposition the close button
478- obj .repositionCloseButton();
479-
480498 % Position over figure by default
481499 if isscalar(obj .Figure ) && isvalid(obj .Figure )
482500 obj .positionOver(obj .Figure )
483501 end
484502
485- % Update component lists
486- obj.ButtonColorableComponents = [obj .DialogButtons ];
487- obj.TitleFontStyledComponents = [obj .OuterPanel ];
488- obj.FontStyledComponents = [obj .DialogButtons ];
489-
490- end % function
491-
492-
493- function postSetup(obj )
494-
495- % Update modal image now
496- obj .updateModalImage();
497-
498503 end % function
499504
500505
501506 function update(obj )
502507
508+ % Update title
509+ if strlength(obj .Title )
510+ obj.OuterPanel.Title = obj .Title ;
511+ else
512+ obj.OuterPanel.Title = " " ;
513+ end
514+
503515 % Ensure it fits in the figure
504516 obj .resizeToFitFigure();
505517
506- % Reposition the close button
507- obj .repositionCloseButton();
508-
509518 end % function
510519
511520
@@ -569,42 +578,51 @@ function checkDeletionCriteria(obj)
569578 %% Private methods
570579 methods (Access = private )
571580
572- function updateModalImage (obj )
573- % Triggered when the Modal property is changed
581+ function resizeToFitFigure (obj )
582+ % Triggered on figure resize
574583
575- % Setup must be complete to run this code
576- if ~obj .SetupFinished
577- return
578- end
584+ % Update modal image
585+ obj .updateModalImage();
579586
580- % If toggled on, do the following
581- if obj .Modal
582-
583- % Bring the dialog above the modal image
584- if isMATLABReleaseOlderThan(" R2025a" )
585- isDlg = obj .Figure .Children == obj ;
586- isModalImage = obj .Figure .Children == obj .ModalImage ;
587- otherChild = obj .Figure .Children(~isDlg & ~isModalImage );
588- obj.Figure.Children = vertcat(obj , obj .ModalImage , otherChild );
589- else
590- uistack(obj ," top" ); % Works in 25a but not earlier
591- end
587+ % Get the current positioning
588+ posD = obj .Position ;
589+ szRequest = obj .Size ;
590+ posLowerLeft = posD(1 : 2 );
592591
593- % Set position to match the figure
594- posF = getpixelposition(obj .Figure );
595- szF = posF (3 : 4 );
596- obj.ModalImage.Position = [ 1 1 szF ] ;
592+ % Get figure size
593+ posFig = getpixelposition(obj .Figure );
594+ szFig = posFig (3 : 4 );
595+ maxSize = szFig - ( 2 * obj . Buffer ) ;
597596
598- end % if
597+ % Size is the smaller of requested size and figure size with
598+ % buffer space
599+ szDlg = min(szRequest , maxSize );
600+
601+ % Restrict a minimum size also
602+ szDlg = max(szDlg , obj .MinimumSize );
603+
604+ % Calculate fit within figure
605+ posUpperRight = posLowerLeft + szDlg ;
606+ if any(posUpperRight > szFig )
607+ posAdjust = szFig - posUpperRight ;
608+ posLowerLeft = posLowerLeft + posAdjust ;
609+ end
610+
611+ % Don't go below 1
612+ posLowerLeft = max(posLowerLeft , 1 );
613+
614+ % Update dialog position
615+ posNew = [posLowerLeft szDlg ];
616+ set(obj ," Position" ,posNew );
599617
600- % Toggle visibility
601- obj.ModalImage.Visible = obj . Modal ;
618+ % Reposition the close button
619+ obj .repositionCloseButton() ;
602620
603621 end % function
604622
605623
606624 function repositionCloseButton(obj )
607- % Triggered on figure resize
625+ % Called at end of resize
608626
609627 % Outer panel inner/outer position
610628 outerPos = obj .OuterPanel .OuterPosition ;
@@ -631,46 +649,21 @@ function repositionCloseButton(obj)
631649 end % function
632650
633651
634- function resizeToFitFigure(obj )
635- % Triggered on figure resize
636-
637- % Get the current positioning
638- posD = obj .Position ;
639- szRequest = obj .Size ;
640- posLowerLeft = posD(1 : 2 );
641-
642- % Get figure size
643- posF = getpixelposition(obj .Figure );
644- szF = posF(3 : 4 );
645- buffer = [20 20 ];
646- maxSize = szF - buffer ;
647-
648- % Size is the smaller of requested size and figure size with
649- % buffer space
650- szD = min(szRequest , maxSize );
652+ function updateModalImage(obj )
653+ % Update modal image size and visibility
651654
652- % Restrict a minimum size also
653- minSize = [30 20 ];
654- szD = max(szD , minSize );
655+ % Only run if ModalImage exists
656+ if isscalar(obj .ModalImage ) && isvalid(obj .ModalImage )
655657
656- % Calculate fit within figure
657- posUpperRight = posLowerLeft + szD ;
658- if any(posUpperRight > szF )
659- posAdjust = szF - posUpperRight ;
660- posLowerLeft = posLowerLeft + posAdjust ;
661- end
662-
663- % Don't go below 1
664- posLowerLeft = max(posLowerLeft , 1 );
658+ % Set modal image position to match the figure
659+ posF = getpixelposition(obj .Figure );
660+ szFig = posF(3 : 4 );
661+ obj.ModalImage.Position = [1 1 szFig ];
665662
666- % Update modal image position
667- if obj .Modal
668- set(obj .ModalImage ," Position" ,[1 1 szF ]);
669- end
663+ % Toggle visibility
664+ obj.ModalImage.Visible = obj .Modal ;
670665
671- % Update dialog position
672- posNew = [posLowerLeft szD ];
673- set(obj ," Position" ,posNew );
666+ end % if
674667
675668 end % function
676669
@@ -754,20 +747,14 @@ function onFigureResized(obj,~)
754747 % Ensure it fits in the figure
755748 obj .resizeToFitFigure();
756749
757- % Reposition the close button
758- obj .repositionCloseButton();
759-
760750 end % function
761751
762752
763- function onOuterPanelResize(obj )
753+ function onOuterPanelResize(~ )
764754 % Triggered when the dialog window is resized
765755
766756 % Ensure it fits in the figure
767- obj .resizeToFitFigure();
768-
769- % Reposition the close button
770- obj .repositionCloseButton();
757+ % obj.resizeToFitFigure();
771758
772759 end % function
773760
0 commit comments