1- classdef (Abstract ) BaseWidget < matlab .ui .componentcontainer .ComponentContainer & ...
1+ classdef (Abstract ) BaseWidget < ...
2+ matlab .ui .componentcontainer .ComponentContainer & ...
3+ wt .mixin .BackgroundColorable & ...
4+ wt .mixin .PropertyViewable & ...
25 wt .mixin .ErrorHandling
36 % Base class for a graphical widget
47
5- % Copyright 2020-2021 The MathWorks Inc.
6-
8+ % Copyright 2020-2023 The MathWorks Inc.
79
10+
811 %% Internal properties
9- properties (AbortSet , Transient , NonCopyable , ...
10- Access = {? wt .abstract .BaseWidget , ? matlab .uitest .TestCase } )
12+ properties (AbortSet , Transient , NonCopyable , Hidden , SetAccess = protected )
1113
12- % List of graphics controls that BackgroundColor should apply to
13- BackgroundColorableComponents ( : , 1 ) matlab.graphics.Graphics
14+ % The internal grid to manage contents
15+ Grid matlab.ui.container.GridLayout
1416
1517 end % properties
16-
17-
18- properties (Transient , NonCopyable , Access = {? matlab .uitest .TestCase })
18+
19+
20+ properties (Transient , NonCopyable , Hidden , SetAccess = private )
21+
22+ % Internal flag to confirm setup has finished
23+ SetupFinished (1 ,1 ) logical = false
1924
20- % Used internally to indicate when setup has finished
21- SetupFinished_I (1 ,1 ) logical = false
25+ end % properties
26+
27+
28+ properties (Transient , NonCopyable , UsedInUpdate = true , ...
29+ GetAccess = private, SetAccess = protected)
30+
31+ % Internal flag to trigger an update call
32+ Dirty (1 ,1 ) logical = false
2233
2334 end % properties
2435
25-
26- properties (Transient , NonCopyable , UsedInUpdate , Access = {? matlab .uitest .TestCase })
36+
37+ %% Special support for pre-R2021a releases (g2282435)
38+ properties (Transient , Access = private )
2739
28- % Used internally to request update call
29- RequestUpdate_I (1 ,1 ) logical = false
40+ % Flag to indicate earlier release ( to be updated during setup)
41+ IsPre21a (1 ,1 ) logical = verLessThan( ' matlab ' , ' 9.10 ' )
3042
3143 end % properties
32-
44+
3345
3446 %% Debugging Methods
3547 methods
3648
3749 function forceUpdate(obj )
38- % Forces update to run (For debugging only!)
39-
50+ % Forces update to run (For debugging only!)
51+
52+ disp(" DEBUG: Forcing update for " + class(obj ));
4053 obj .update();
41-
54+
4255 end % function
4356
4457 end % methods
4558
59+
60+ %% Constructor
61+ methods
62+
63+ function obj = BaseWidget(varargin )
64+
65+ % Attach internal postSetup callback
66+ args = horzcat(varargin(: ), {" CreateFcn" , @(src ,evt )postSetup_I(src )});
67+
68+ % Call superclass constructor
69+ 70+
71+ end % function
72+
73+ end % methods
4674
47-
48- %% Setup
49- properties ( Transient , NonCopyable , ...
50- Access = {? wt .abstract .BaseWidget , ? matlab .uitest .TestCase } )
51-
52- % The internal grid to manage contents
53- Grid matlab.ui.container.GridLayout
54-
55- end % properties
56-
57-
75+
76+ %% Protected Methods
5877 methods (Access = protected )
5978
6079 function setup(obj )
6180 % Configure the widget
62-
63- % Use CreateFcn to tell when setup finishes
64- obj.CreateFcn = @(src ,evt )obj .toggleSetupFinished_I();
65-
81+
6682 % Grid Layout to manage building blocks
6783 obj.Grid = uigridlayout(obj );
6884 obj.Grid.ColumnWidth = {' 1x' };
@@ -71,117 +87,78 @@ function setup(obj)
7187 obj.Grid.ColumnSpacing = 2 ;
7288 obj.Grid.Padding = [0 0 0 0 ];
7389
74- % Listen to BackgroundColor changes
75- addlistener(obj ,' BackgroundColor' ,' PostSet' ,...
76- @(h ,e )obj .updateBackgroundColorableComponents());
90+ end % function
91+
92+
93+ function postSetup(~)
94+ % Optional post-setup method
95+ % (after setup and input arguments set, before update)
7796
7897 end % function
7998
80- end % methods
81-
82-
83-
84- %% Protected Methods
85- methods (Access = protected )
8699
100+ function requestUpdate(obj )
101+ % Request update method to run
102+ % (This is for backward compatibility.
103+ % Alternatively just set "obj.Dirty = true")
104+
105+ % Support for initial release before R2021a
106+ if obj .IsPre21a && obj .SetupFinished
107+
108+ % g2282435 Force a call to update
109+ obj .update();
110+
111+ else
112+
113+ % Trigger property to request update during next drawnow
114+ % (for optimal efficiency)
115+ obj.Dirty = true ;
116+
117+ end % if
118+
119+ end % function
120+
121+
87122 function updateBackgroundColorableComponents(obj )
88123 % Update components that are affected by BackgroundColor
124+ % (overrides the superclass method)
89125
126+ % Update grid color
90127 obj.Grid.BackgroundColor = obj .BackgroundColor ;
91- hasProp = isprop( obj . BackgroundColorableComponents , ' BackgroundColor ' );
92- set( obj .BackgroundColorableComponents( hasProp ),...
93- " BackgroundColor " , obj .BackgroundColor );
128+
129+ % Call superclass method
130+ obj .updateBackgroundColorableComponents @ wt . mixin .BackgroundColorable( );
94131
95132 end % function
96-
97-
98- function requestUpdate(obj )
99- % Request update method to run
100-
101- if ~obj .SetupFinished_I
102- % Do nothing
103- elseif verLessThan(' matlab' ,' 9.10' )
104- % g228243 Force a call to update
105- obj .update();
106- else
107- % Trigger set of a UsedInUpdate property to request update
108- % during next drawnow. (for optimal efficiency)
109- obj.RequestUpdate_I = true ;
110- end
133+
134+
135+ function groups = getPropertyGroups(obj )
136+ % Customize the property display
137+ % (override to use the mixin implementation, since multiple
138+ % superclasses have competing implementations)
139+
140+ 111141
112142 end % function
113143
114144 end % methods
115-
116-
117-
145+
146+
118147 %% Private Methods
119148 methods (Access = private )
120149
121- function toggleSetupFinished_I (obj )
150+ function postSetup_I (obj )
122151 % Indicate setup is complete
123152
124- obj.SetupFinished_I = true ;
153+ obj.SetupFinished = true ;
125154 obj.CreateFcn = ' ' ;
155+
156+ % Call any custom postSetup method
157+ obj .postSetup();
126158
127159 end % function
128160
129161 end % methods
130-
131-
132-
133- %% Display customization
134- methods (Hidden , Access = protected )
135-
136- function groups = getPropertyGroups(obj )
137- % Customize how the properties are displayed
138-
139- % Ignore most superclass properties for default display
140- persistent superProps
141- if isempty(superProps )
142- superProps = properties(' matlab.ui.componentcontainer.ComponentContainer' );
143- end
144-
145- % Get the relevant properties
146- allProps = properties(obj );
147- propNames = setdiff(allProps , superProps , ' stable' );
148-
149- % Remove props we don't need to see
150- propNames( startsWith(propNames , " Font" ) ) = [];
151- propNames( matches(propNames , " Enable" ) ) = [];
152-
153- % Split out the callbacks, fonts
154- isCallback = endsWith(propNames , " Fcn" );
155- isColor = endsWith(propNames , " Color" );
156- normalProps = propNames(~isCallback & ~isColor );
157- callbackProps = propNames(isCallback & ~isColor );
158-
159- % Define the groups
160- groups = [
161- matlab .mixin .util .PropertyGroup(callbackProps )
162- matlab .mixin .util .PropertyGroup(normalProps )
163- matlab .mixin .util .PropertyGroup([" Position" , " Units" ])
164- ];
165-
166- % Ignore empty groups
167- groups(~[groups .NumProperties ]) = [];
168-
169- end % function
170-
171- end % methods
172-
173-
174-
175- %% Accessors
176- methods
177-
178- function set .BackgroundColorableComponents(obj ,value )
179- obj.BackgroundColorableComponents = value ;
180- obj .updateBackgroundColorableComponents()
181- end
182-
183- end % methods
184-
185-
186- end % classdef
187162
163+
164+ end % classdef
0 commit comments