Skip to content

Commit 65357f9

Browse files
committed
interim work on BaseInternalDialog.m, looking at ParentComponent, lifecycle listeners, deletion, etc.
1 parent 0035955 commit 65357f9

File tree

1 file changed

+129
-10
lines changed

1 file changed

+129
-10
lines changed

widgets/+wt/+abstract/BaseInternalDialog.m

Lines changed: 129 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@
66

77
% Copyright 2022-2025 The MathWorks Inc.
88

9-
% To do:
10-
% - finish importing old BaseDialog
11-
% - make examples
12-
% - handle theme changes
13-
149

1510
%% Events
1611
events (HasCallbackProperty)
@@ -158,7 +153,7 @@
158153
properties (AbortSet, Access = public)
159154

160155
% Dialog button action names that trigger deletion (button tags/names)
161-
DeleteActions (1,:) string = ["close","ok","cancel","exit"]
156+
DeleteActions (1,:) string = ["delete","close","ok","cancel","exit"]
162157

163158
end %properties
164159

@@ -215,6 +210,95 @@
215210
end %properties
216211

217212

213+
properties (Transient, Hidden)
214+
215+
% Optional parent component creating the dialog. The component must
216+
% be provided to constructor, and the dialog will be centered on
217+
% the component where possible. The lifecycle will be tied so that
218+
% the dialog will be deleted if the component is deleted.
219+
ParentComponent matlab.graphics.Graphics
220+
221+
end %properties
222+
223+
224+
%% Constructor / Destructor
225+
methods
226+
function obj = BaseInternalDialog(parentComponent)
227+
% Construct a dialog
228+
229+
arguments
230+
parentComponent matlab.graphics.Graphics ...
231+
{mustBeScalarOrEmpty} = gobjects(0)
232+
end
233+
234+
% Get ancestor figure, if possible
235+
% If no figure available, place dialog in a new figure
236+
id = "wt:abstract:BaseInternalDialog:InvalidParent";
237+
msg = "Input to BaseInternalDialog must be a uifigure or a component within a uifigure.";
238+
if isempty(parentComponent)
239+
% No component or figure, make a new figure
240+
241+
parent = uifigure;
242+
hasComponent = false;
243+
244+
elseif isa(parentComponent,"matlab.ui.Figure")
245+
% Given a figure for the parent
246+
247+
parent = parentComponent;
248+
hasComponent = false;
249+
250+
elseif isa(parentComponent, "matlab.graphics.Graphics")
251+
% Given a component (it must be in a figure)
252+
253+
parent = ancestor(parentComponent,'figure');
254+
if isempty(parent)
255+
% Component not in a figure
256+
error(id,parent)
257+
else
258+
hasComponent = true;
259+
end
260+
261+
else
262+
263+
error(id,msg)
264+
265+
end
266+
267+
% Call superclass
268+
if hasComponent
269+
addedArgs = {"ParentComponent", parentComponent};
270+
else
271+
addedArgs = {};
272+
end
273+
[email protected](parent, addedArgs{:});
274+
% [email protected](parent);
275+
276+
% Did it have a component argument?
277+
if hasComponent
278+
279+
% Store the parent component
280+
%obj.ParentComponent = parentComponent;
281+
282+
% Position over the component
283+
%obj.positionOver(parentComponent)
284+
285+
% Set dialog lifecycle to that of the parent component
286+
% The dialog will be deleted if the parent component is deleted
287+
obj.attachLifecycleListeners(parentComponent);
288+
289+
else
290+
291+
% Set dialog lifecycle to that of the parent
292+
% The dialog will be deleted if the parent component is deleted
293+
obj.attachLifecycleListeners(parent);
294+
295+
end
296+
297+
end %function
298+
299+
end %methods
300+
301+
218302
%% Public methods
219303
methods (Sealed, Access = public)
220304

@@ -267,9 +351,15 @@ function positionOver(obj, refComp)
267351

268352
end %if
269353

354+
% Disable warning
355+
warnState = warning('off','MATLAB:ui:components:noPositionSetWhenInLayoutContainer');
356+
270357
% Set final position
271358
obj.Position = [dlgPos dlgSize];
272359

360+
% Restore warning
361+
warning(warnState)
362+
273363
end %function
274364

275365

@@ -365,19 +455,25 @@ function assignOutput(~)
365455
function setup(obj)
366456
% Configure the dialog
367457

458+
% Disable warning
459+
warnState = warning('off','MATLAB:ui:components:noPositionSetWhenInLayoutContainer');
460+
368461
% Defaults
369462
obj.Position(3:4) = [350,200];
370463

464+
% Restore warning
465+
warning(warnState)
466+
371467
% Outer grid to enable the dialog panel to fill the component
372468
obj.OuterGrid = uigridlayout(obj,[1 1]);
373469
obj.OuterGrid.Padding = [0 0 0 0];
374470

375471
% Outer dialog panel
376472
obj.OuterPanel = uipanel(obj.OuterGrid);
377473
obj.OuterPanel.Title = "Dialog Title";
378-
obj.OuterPanel.FontSize = 14;
474+
obj.OuterPanel.FontSize = 16;
379475
obj.OuterPanel.FontWeight = "bold";
380-
obj.OuterPanel.BorderWidth = 1;
476+
%obj.OuterPanel.BorderWidth = 1;
381477
obj.OuterPanel.AutoResizeChildren = false;
382478
obj.OuterPanel.ResizeFcn = @(~,~)onOuterPanelResize(obj);
383479
obj.OuterPanel.ButtonDownFcn = @(~,evt)onTitleButtonDown(obj,evt);
@@ -414,6 +510,9 @@ function setup(obj)
414510
obj.getThemeColor("--mw-borderColor-secondary");
415511
obj.OuterPanel.BackgroundColor = ...
416512
obj.getThemeColor("--mw-backgroundColor-secondary");
513+
elseif isMATLABReleaseOlderThan("R2023a")
514+
obj.OuterPanel.ForegroundColor = [0.38 0.38 0.38];
515+
obj.OuterPanel.BackgroundColor = [.9 .9 .9];
417516
else
418517
obj.OuterPanel.ForegroundColor = [0.38 0.38 0.38];
419518
obj.OuterPanel.BorderColor = [.5 .5 .5];
@@ -490,21 +589,41 @@ function attachLifecycleListeners(obj, owners)
490589
% Delete the dialog automatically upon destruction of the specified "owner" graphics objects
491590

492591
arguments
493-
obj (1,1) wt.abstract.BaseDialog
592+
obj (1,1) wt.abstract.BaseInternalDialog
494593
owners handle
495594
end
496595

497596
% Create listeners
498597
% The dialog will be deleted if the listenObj is deleted
499598
newListeners = listener(owners, "ObjectBeingDestroyed",...
500-
@(src,evt)delete(obj));
599+
@(src,evt)forceCloseDialog(obj));
501600

502601
% Add to any existing listeners
503602
obj.LifecycleListeners = horzcat(obj.LifecycleListeners, newListeners);
504603

505604
end %function
506605

507606

607+
function forceCloseDialog(obj)
608+
% Should the dialog be deleted?
609+
610+
obj.Output = [];
611+
obj.LastAction = 'delete';
612+
613+
if ~obj.IsWaitingForOutput
614+
615+
% Delete the dialog
616+
delete(obj)
617+
618+
else
619+
620+
obj.IsWaitingForOutput = false;
621+
622+
end
623+
624+
end %function
625+
626+
508627
function checkDeletionCriteria(obj)
509628
% Should the dialog be deleted?
510629

0 commit comments

Comments
 (0)