Skip to content

Commit 690a1ef

Browse files
rjackeyrjackey
authored andcommitted
#43 BaseWidget Make a better implementation of requestUpdate, SetupComplete, Dirty flag
1 parent 48e011b commit 690a1ef

File tree

1 file changed

+101
-124
lines changed

1 file changed

+101
-124
lines changed

widgets/+wt/+abstract/BaseWidget.m

Lines changed: 101 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,84 @@
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+
obj = [email protected](args{:});
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+
groups = [email protected](obj);
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

Comments
 (0)