Skip to content

Commit e2fe051

Browse files
committed
Resolve Issue #63 (empty figure)
* Add class validators on `nigeLab.nigelObj` properties: `.GUI`, `.GUIContainer`, `.SortGUI` + Because nigeLab.libs.DashBoard (and nigeLab.Sort) couldn't be constructed without input arguments, their constructors have been changed. + This is safe because they are only constructed via methods of nigeLab.nigelObj at this point. + Now `nigeLab.Sort` and `nigeLab.libs.DashBoard` can be constructed with no inputs (as empty handles).
2 parents 1a630cd + 855c0ad commit e2fe051

4 files changed

Lines changed: 177 additions & 76 deletions

File tree

+nigeLab/+libs/@DashBoard/DashBoard.m

Lines changed: 85 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,19 @@
104104

105105
% Check input
106106
if nargin < 1
107-
% Allow selection of TANK if not assigned directly
108-
tankObj = nigeLab.Tank();
107+
obj = nigeLab.libs.DashBoard([0,0]); % Empty DashBoard
108+
close(gcf); % If a figure is opened
109+
return; % Should always be called from tankObj anyways
110+
elseif isnumeric(tankObj)
111+
dims = tankObj;
112+
obj = repmat(obj,dims);
113+
return;
109114
end
110115

111116
% Add current path and initialize properties
112117
addpath(pwd); % (In case path is changed while GUI is open)
113118
obj.Tank = tankObj;
114-
obj.initRefProps();
119+
obj.Color = nigeLab.libs.DashBoard.initColors();
115120

116121
% Build figure and all container panels
117122
obj.nigelGUI = obj.buildGUI();
@@ -221,41 +226,103 @@ function delete(obj)
221226
% % % GET.PROPERTY METHODS % % % % % % % % % % % %
222227
% [DEPENDENT] Return .Fields property
223228
function value = get.Fields(obj)
229+
if isempty(obj.Tank)
230+
value = {};
231+
return;
232+
end
224233
value = obj.Tank.Fields;
225234
end
226235

227236
% [DEPENDENT] Return .FieldType property
228237
function value = get.FieldType(obj)
238+
if isempty(obj.Tank)
239+
value = {};
240+
return;
241+
end
229242
value = obj.Tank.FieldType;
230243
end
231244

232245
% [DEPENDENT] Return .ParametersPanel property
233246
function value = get.ParametersPanel(obj)
247+
value = [];
248+
if isempty(obj.Children)
249+
return;
250+
elseif numel(obj.Children) < 4
251+
return;
252+
elseif ~iscell(obj.Children)
253+
return;
254+
elseif ~isvalid(obj.Children{4})
255+
return;
256+
end
234257
value = obj.Children{4};
235258
end
236259

237260
% [DEPENDENT] Return .QueuePanel property
238261
function value = get.QueuePanel(obj)
262+
value = [];
263+
if isempty(obj.Children)
264+
return;
265+
elseif numel(obj.Children) < 3
266+
return;
267+
elseif ~iscell(obj.Children)
268+
return;
269+
elseif ~isvalid(obj.Children{3})
270+
return;
271+
end
239272
value = obj.Children{3};
240273
end
241274

242275
% [DEPENDENT] Return .StatsPanel property
243276
function value = get.StatsPanel(obj)
277+
value = [];
278+
if isempty(obj.Children)
279+
return;
280+
elseif numel(obj.Children) < 2
281+
return;
282+
elseif ~iscell(obj.Children)
283+
return;
284+
elseif ~isvalid(obj.Children{2})
285+
return;
286+
end
244287
value = obj.Children{2};
245288
end
246289

247290
% [DEPENDENT] Return .TreePanel property
248291
function value = get.TreePanel(obj)
292+
value = [];
293+
if isempty(obj.Children)
294+
return;
295+
elseif numel(obj.Children) < 1
296+
return;
297+
elseif ~iscell(obj.Children)
298+
return;
299+
elseif ~isvalid(obj.Children{1})
300+
return;
301+
end
249302
value = obj.Children{1};
250303
end
251304

252305
% [DEPENDENT] Return .QueuePanel property
253306
function value = get.TitleBar(obj)
307+
value = [];
308+
if isempty(obj.Children)
309+
return;
310+
elseif numel(obj.Children) < 5
311+
return;
312+
elseif ~iscell(obj.Children)
313+
return;
314+
elseif ~isvalid(obj.Children{5})
315+
return;
316+
end
254317
value = obj.Children{5};
255318
end
256319

257320
% [DEPENDENT] Return .Visible property
258321
function value = get.Visible(obj)
322+
if isempty(obj.nigelGUI)
323+
value = 'invalid';
324+
return;
325+
end
259326
if isvalid(obj.nigelGUI)
260327
value = obj.nigelGUI.Visible;
261328
else
@@ -329,8 +396,10 @@ function Show(obj)
329396

330397
% [DEPENDENT] Set .Visible property
331398
function set.Visible(obj,value)
332-
if isvalid(obj.nigelGUI)
333-
obj.nigelGUI.Visible = value;
399+
if ~isempty(obj.nigelGUI)
400+
if isvalid(obj.nigelGUI)
401+
obj.nigelGUI.Visible = value;
402+
end
334403
end
335404
end
336405
% % % % % % % % % % END SET.PROPERTY METHODS % % %
@@ -655,7 +724,7 @@ function buildButtons(obj,nigelPanelObj)
655724
end
656725

657726
% Returns figure handle, with layout mediated by core nigelPanels
658-
function fig = buildGUI(obj,fig)
727+
function fig = buildGUI(obj)
659728
% LOADPANELS Method to create all custom uipanels (nigelPanels)
660729
% that populate most of the GUI interface.
661730
%
@@ -669,17 +738,16 @@ function buildButtons(obj,nigelPanelObj)
669738
% obj.Children{3} <--> 'QueuePanel'
670739
% obj.Children{4} <--> 'ParametersPanel'
671740

672-
% Check input
673-
if nargin < 2
674-
fig = figure('Name','nigelDash Interface',...
675-
'Units','Normalized',...
676-
'Position',[0.1 0.1 0.8 0.8],...
677-
'Color',obj.Color.fig,...
678-
'ToolBar','none',...
679-
'MenuBar','none',...
680-
'NumberTitle','off',...
681-
'DeleteFcn',@(~,~)obj.delete);
682-
end
741+
742+
fig = figure('Name','nigelDash Interface',...
743+
'Units','Normalized',...
744+
'Position',[0.1 0.1 0.8 0.8],...
745+
'Color',obj.Color.fig,...
746+
'ToolBar','none',...
747+
'MenuBar','none',...
748+
'NumberTitle','off',...
749+
'DeleteFcn',@(~,~)obj.delete);
750+
683751

684752
% Create "Tree" panel (nodes are: Tank > Animal > Block)
685753
str = {'TreePanel'};
@@ -920,21 +988,6 @@ function deleteListeners(obj)
920988
obj.Listener(:) = [];
921989
end
922990

923-
% Initialize reference property values
924-
function initRefProps(obj)
925-
% INITREFPROPS Initialize property values for referencing later
926-
%
927-
% obj.initRefProps(tankObj); Takes references from parameters of
928-
% tankObj, which should be
929-
% identical for all Blocks and
930-
% Animals that are under
931-
% consideration by DashBoard.
932-
933-
obj.Color = nigeLab.libs.DashBoard.initColors();
934-
obj.Fields = obj.Tank.Pars.Block.Fields;
935-
obj.FieldType = obj.Tank.Pars.Block.FieldType;
936-
end
937-
938991
% Initialize UI context menu for tree click interactions
939992
function treeContextMenu = initUICMenu(obj)
940993
% INITUICMENU Initialize UI Context menu. Adds all 'do' methods

+nigeLab/@Sort/Sort.m

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,43 @@
6868
% sortObj = nigeLab.Sort;
6969
% sortObj = nigeLab.Sort(nigelObj);
7070

71-
% Initialize parameters
72-
if ~initParams(sortObj)
73-
error(['nigeLab:' mfilename ':BadInit'],...
74-
'Could not set parameters for sortObj.');
75-
end
76-
7771
% Initialize input data
7872
if nargin > 0
79-
if ~initData(sortObj,nigelObj)
73+
if isnumeric(nigelObj) % Initialize
74+
dims = nigelObj;
75+
sortObj = repmat(sortObj,dims);
76+
return;
77+
end
78+
79+
% Initialize parameters
80+
if ~initParams(sortObj,nigelObj)
8081
error(['nigeLab:' mfilename ':BadInit'],...
81-
'sortObj array not created successfully.');
82+
'Could not set parameters for sortObj.');
8283
end
83-
else
84-
if ~initData(sortObj)
84+
85+
if ~initData(sortObj,nigelObj)
8586
error(['nigeLab:' mfilename ':BadInit'],...
8687
'sortObj array not created successfully.');
8788
end
89+
% else % Note: it is no longer possible to call `Sort`
90+
% % constructor from Command Window directly; has
91+
% % to be called via a `nigelObj` method
92+
% % 2020-01-20 -MM
93+
%
94+
% % Initialize parameters
95+
% if ~initParams(sortObj)
96+
% error(['nigeLab:' mfilename ':BadInit'],...
97+
% 'Could not set parameters for sortObj.');
98+
% end
99+
% % And then initialize data
100+
% if ~initData(sortObj)
101+
% error(['nigeLab:' mfilename ':BadInit'],...
102+
% 'sortObj array not created successfully.');
103+
% end
104+
else % Therefore, if it is given without inputs, it is for init
105+
sortObj = nigeLab.Sort([0,0]); % Empty
106+
close(gcf);
107+
return;
88108
end
89109

90110
% Initialize graphical interface
@@ -98,7 +118,7 @@
98118
end
99119
end
100120

101-
% NO ATTRIBUTES (contructor & overloaded methods)
121+
% NO ATTRIBUTES (overloaded methods)
102122
methods
103123
% Overloaded `delete` method
104124
function delete(sortObj)
@@ -188,7 +208,7 @@ function delete(sortObj)
188208

189209
% PROTECTED
190210
methods (Access=protected)
191-
flag = initParams(sortObj); % Initialize general parameters
211+
flag = initParams(sortObj,nigelObj); % Initialize general parameters
192212
flag = initData(sortObj,nigelObj); % Initialize data structures
193213
flag = initUI(sortObj); % Initializes spike scoring UI parameters
194214

+nigeLab/@Sort/initParams.m

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,39 @@
1-
function flag = initParams(sortObj)
2-
%% INITPARAMS Initialize parameters structure for Spike Sorting UI.
1+
function flag = initParams(sortObj,nigelObj)
2+
%INITPARAMS Initialize parameters structure for Spike Sorting UI.
33
%
44
% flag = INITPARAMS(sortObj);
5-
%
6-
% By: Max Murphy v3.0 01/07/2019 Port to object-oriented architecture.
7-
% v2.0 10/03/2017 Added ability to handle multiple input
8-
% probes with redundant channel labels.
9-
% v1.0 08/18/2017 Original version (R2017a)
5+
% --> Load `Sort` defaults from nigeLab.defaults.Sort();
6+
%
7+
% flag = INITPARAMS(sortObj,nigelObj);
8+
% --> Load `Sort` parameters from nigelObj directly
109

11-
%% MODIFY SORT CLASS OBJECT PROPERTIES HERE
10+
% MODIFY SORT CLASS OBJECT PROPERTIES HERE
1211
flag = false;
1312

14-
pars = nigeLab.defaults.Sort();
15-
16-
%% COULD ADD PARSING FOR PROPERTY VALIDITY HERE?
17-
% To look into for future...
18-
%
19-
% e.g. Check that "SDMAX" is numeric, and greater than "SDMIN" etc...
13+
if nargin < 2
14+
pars = nigeLab.defaults.Sort();
15+
flag = true;
16+
else
17+
pars = cell(size(nigelObj)); % In case it is array
18+
[pars{:}] = getParams(nigelObj,'Sort');
19+
pars(cellfun(@isempty,pars)) = [];
20+
if isempty(pars)
21+
warning(['[INITPARAMS]: Array of %g %g objects does not ' ...
22+
'have `Sort` parameters initialized yet.\n'],...
23+
numel(nigelObj),class(nigelObj));
24+
return;
25+
elseif isequal(pars{:})
26+
flag = true;
27+
else
28+
warning(['[INITPARAMS]: Array of %g %g objects does not ' ...
29+
'contain identical `Sort` parameters for each object.\n'],...
30+
numel(nigelObj),class(nigelObj));
31+
return;
32+
end
33+
end
2034

21-
%% UPDATE PARS PROPERTY
35+
% UPDATE PARS PROPERTY
2236
sortObj.pars = pars;
23-
flag = true;
37+
2438

2539
end

0 commit comments

Comments
 (0)