3535 % Indicates whether to allow duplicate entries in the list
3636 AllowDuplicates (1 ,1 ) matlab.lang.OnOffSwitchState = false
3737
38+ % Indicates whether to allow sort controls
39+ Sortable (1 ,1 ) matlab.lang.OnOffSwitchState = true
40+
3841 % Inidicates what to do when add button is pressed (select from
3942 % Items or custom using ButtonPushed event or ButtonPushedFcn)
4043 AddSource (1 ,1 ) wt.enum.ListAddSource = wt.enum.ListAddSource.Items
104107
105108 function value = get .ValueIndex(obj )
106109 value = obj .ListBox .ItemsData ;
110+ value(value > obj .getMaximumValidItemsNumber ) = [];
107111 end
108112
109113 function set .ValueIndex(obj ,value )
114+ if any(value > numel(obj .Items ))
115+ error(" widgets:ListSelector:ValueIndex" ,...
116+ " 'ValueIndex' must be within the length of the 'Items' property." )
117+ end
118+ if ~isempty(obj .ItemsData ) && any(value > numel(obj .ItemsData ))
119+ error(" widgets:ListSelector:ValueIndex" ,...
120+ " 'ValueIndex' must be within the length of the 'ItemsData' property." )
121+ end
110122 obj.ListBox.Items = obj .Items(value );
111123 obj.ListBox.ItemsData = value ;
112124 end
123135
124136 function set .Value(obj ,value )
125137 if isempty(value )
126- obj.SelectedIndex = [];
138+ obj.ValueIndex = [];
127139 else
128140 if isempty(obj .ItemsData )
129141 [tf , selIdx ] = ismember(value , obj .Items );
130142 else
131143 [tf , selIdx ] = ismember(value , obj .ItemsData );
132144 end
133145 if ~all(tf )
134- warning(" widgets:ListSelector:InvalidValue" ,...
135- " Attempt to set an invalid Value to the list." )
136- selIdx(~tf ) = [];
146+ if isempty(obj .ItemsData )
147+ itemValueName = ' Items' ;
148+ else
149+ itemValueName = ' ItemsData' ;
150+ end
151+ error(" widgets:ListSelector:InvalidValue" ,...
152+ " 'Value' must be an element defined in the '%s' property." , itemValueName )
153+ end
154+ if ~isempty(obj .ItemsData ) && numel(tf ) > numel(obj .Items )
155+ error(" widgets:ListSelector:InvalidValue" ,...
156+ " 'Value' must be an element defined in the 'ItemsData' property within the length of the 'Items' property." )
137157 end
138- obj.SelectedIndex = selIdx ;
158+ obj.ValueIndex = selIdx ;
139159 end
140160 end
141161
@@ -289,7 +309,17 @@ function setup(obj)
289309 function update(obj )
290310
291311 % What is selected?
292- selIdx = obj .SelectedIndex ;
312+ selIdx = obj .ValueIndex ;
313+
314+ % Is the list sortable?
315+ if obj .Sortable
316+ obj.ListButtons.Icon = [" add_24.png" , " delete_24.png" , " up_24.png" , " down_24.png" ];
317+ obj.ListButtons.ButtonTag = [" Add" , " Remove" , " Up" , " Down" ];
318+ else
319+ selIdx = sort(selIdx );
320+ obj.ListButtons.Icon = [" add_24.png" , " delete_24.png" ];
321+ obj.ListButtons.ButtonTag = [" Add" , " Remove" ];
322+ end
293323
294324 % Update the list
295325 obj.ListBox.Items = obj .Items(selIdx );
@@ -313,7 +343,7 @@ function updateEnables(obj)
313343 if obj .Enable
314344
315345 % What is selected?
316- selIdx = obj .SelectedIndex ;
346+ selIdx = obj .ValueIndex ;
317347 numRows = numel(selIdx );
318348
319349 % Highlighted selection in list?
@@ -418,21 +448,27 @@ function promptToAddListItems(obj)
418448 " InitialValue" ,obj .ListBox .ItemsData );
419449 end
420450
451+ % Restore figure focus
452+ fig = ancestor(obj ," figure" );
453+ if isscalar(fig ) && isvalid(fig )
454+ figure(fig )
455+ end
456+
421457 if isempty(newSelIdx )
422458 % User cancelled
423459 return
424460 elseif obj .AllowDuplicates
425- newSelIdx = [obj .SelectedIndex newSelIdx ];
461+ newSelIdx = [obj .ValueIndex newSelIdx ];
426462 end
427463
428464 % Was a change made?
429- if ~isequal(obj .SelectedIndex , newSelIdx )
465+ if ~isequal(obj .ValueIndex , newSelIdx )
430466
431467 % Get the original value
432468 oldValue = obj .Value ;
433469
434470 % Make the update
435- obj.SelectedIndex = newSelIdx ;
471+ obj.ValueIndex = newSelIdx ;
436472
437473 % Trigger event
438474 evtOut = wt .eventdata .ValueChangedData(obj .Value , oldValue );
@@ -515,6 +551,19 @@ function shiftListBoxIndex(obj, shift)
515551
516552 end % function
517553
554+ function val = getMaximumValidItemsNumber(obj )
555+ % Returns maximum valid selected index.
556+ % Takes into account ItemsData and Items.
557+
558+ % Is ItemsData available?
559+ if ~isempty(obj .ItemsData )
560+ val = min(numel(obj .ItemsData ), numel(obj .Items ));
561+ else
562+ val = numel(obj .Items );
563+ end
564+
565+ end % function
566+
518567 end % methods
519568
520569end % classdef
0 commit comments