function [varargout] = MultiSlider (varargin)
% MultiSlider Create multi slider control.
% MultiSlider, by itself, creates a new multi slider control in the
% current figure, and returns its handle.
%
% MultiSlider(H, 'Results') returns an array of floats that represent
% the ordered grip positions on the slider H.
%
% MultiSlider(H, Property, Value) sets the Property to the specified
% Value for slider H. Possible properties are:
% - XLabel: String label for x-axis
% - Position: Array(4) [xPos yPos width height] in pixels
% - Domain: Array(2) [xMin xMax]
% - NTicks: Integer, number of ticks on the x-axis
% - TicksRoundDigits: Integer, number of digits to round the ticks
% - UserFcn: String, User defined function triggered each time a grip is
% slided
%
% A multislider is an axis along which grips can be placed by clicking
% on empty axis spots. The position of each of the grips can be changed
% by drag/drop.
% When finished, the positions/values represented by the grips can be
% retrieved.
%
% April 22, 2005 MultiSlider V1.01
% Changed licence to BSD at request of Mathworks.
%
% Copyright (C) 2005 Wilko de Jong
%
try
switch nargin
case 0
% Just instantiate a new (default) multi slider
varargout{1} = initialize;
case 2
if ishandle(varargin{1}) && strcmp(varargin{2}, 'Results')
varargout{1} = GetResults(varargin{1});
end
case 3
if ishandle(varargin{1}) && ischar(varargin{2})
varargout{1} = SetProperty(varargin{1}, varargin{2}, varargin{3});
end
case 4
if ischar(varargin{1})
% This may be a callback
fhandle = str2func(varargin{1});
fhandle(varargin{2}, varargin{3}, varargin{4});
end
end
end
%--------------------------------------------------------------------------
function [ms] = initialize
% Set up the axes
ms = axes;
pa = get(ms, 'Parent');
set(ms, 'Units', 'Pixels');
set(ms, 'Box', 'off');
set(ms, 'Color', get(pa, 'Color'));
set(ms, 'XColor', [0 0 0]);
set(ms, 'YColor', get(pa, 'Color'));
set(ms, 'ZColor', get(pa, 'Color'));
set(ms, 'YTick', []);
set(ms, 'Position', [20 20 300 10]);
set(ms, 'XLim', [0 1]);
set(ms, 'ButtonDownFcn', 'MultiSlider(''MultiSliderButtonDownFcn'', gcbo, [], guidata(gcbo))');
% Create an empty collection for the grips
userdata = struct();
userdata.grips = [];
userdata.Domain = [0 1];
userdata.NTicks = 3;
userdata.Pointers.GripAddHotSpot = [8 8];
userdata.TicksRoundDigits = 2;
userdata.UserFcn = '';
userdata.Pointers.GripAdd = [ ...
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN; ...
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN; ...
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 1 1 1 1; ...
NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN 1 NaN NaN; ...
NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN 1 NaN NaN; ...
NaN NaN NaN NaN NaN NaN 1 1 1 NaN NaN NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN NaN NaN 1 1 1 NaN NaN NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN NaN 1 1 1 1 1 NaN NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN NaN 1 1 1 1 1 NaN NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN 1 1 1 1 1 1 1 NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN 1 1 1 1 1 1 1 NaN NaN NaN NaN NaN; ...
NaN NaN NaN 1 1 1 1 1 1 1 1 1 NaN NaN NaN NaN; ...
NaN NaN NaN 1 1 1 1 1 1 1 1 1 NaN NaN NaN NaN; ...
NaN NaN 1 1 1 1 1 1 1 1 1 1 1 NaN NaN NaN; ...
NaN NaN 1 1 1 1 1 1 1 1 1 1 1 NaN NaN NaN; ...
NaN 1 1 1 1 1 1 1 1 1 1 1 1 1 NaN NaN];
userdata.Pointers.GripMoveHotSpot = [8 8];
userdata.Pointers.GripMove = [ ...
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN; ...
NaN NaN NaN 1 1 NaN NaN NaN NaN NaN NaN 1 1 NaN NaN NaN; ...
NaN NaN 1 2 1 NaN NaN NaN NaN NaN NaN 1 2 1 NaN NaN; ...
NaN 1 2 2 1 1 1 1 1 1 1 1 2 2 1 NaN; ...
1 2 2 2 1 1 1 1 1 1 1 1 2 2 2 1 ; ...
NaN 1 2 2 1 1 1 1 1 1 1 1 2 2 1 NaN; ...
NaN NaN 1 2 1 NaN NaN NaN NaN NaN NaN 1 2 1 NaN NaN; ...
NaN NaN NaN 1 1 NaN NaN NaN NaN NaN NaN 1 1 NaN NaN NaN; ...
NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN; ...
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN; ...
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN];
% Control mouseover events
RefreshOriginalMouseOver();
% Store the userdata
set(ms, 'UserData', userdata);
%--------------------------------------------------------------------------
function RefreshOriginalMouseOver()
myFigure = get(gcf);
myCallback = 'MultiSlider(''FigureMouseMoveFcn'', gcbo, [], guidata(gcbo))';
if ~strcmp(myFigure.WindowButtonMotionFcn, myCallback)
userdata = get(gcf, 'UserData');
userdata.OriginalWindowButtonMotionFcn = myFigure.WindowButtonMotionFcn;
set(gcf, 'WindowButtonMotionFcn', myCallback);
set(gcf, 'UserData', userdata);
end
%--------------------------------------------------------------------------
function [hGrip] = NewGrip(hMultiSlider, xPos)
hGrip = patch;
set(hGrip, 'YData', [0;1;0]);
set(hGrip, 'FaceColor', [0 0 0]);
set(hGrip, 'ButtonDownFcn', 'MultiSlider(''GripButtonDownFcn'', gcbo, [], guidata(gcbo))');
MoveGrip(hGrip, xPos);
% Add to collection
userdata = get(hMultiSlider, 'UserData');
userdata.grips(length(userdata.grips) + 1) = hGrip;
set(hMultiSlider, 'UserData', userdata);
%--------------------------------------------------------------------------
function DeleteGrip(hMultiSlider, hGrip)
myMultiSlider = get(hMultiSlider);
userdata = myMultiSlider.UserData;
for ii = 1 : length(userdata.grips)
if userdata.grips(ii) == hGrip
userdata.grips = [userdata.grips(1:ii-1) userdata.grips(ii+1:end)];
delete(hGrip);
set(hMultiSlider, 'UserData', userdata);
return
end
end
%--------------------------------------------------------------------------
function [hMultiSlider] = SetProperty(hMultiSlider, pName, pVal)
myMultiSlider = get(hMultiSlider);
userdata = myMultiSlider.UserData;
try
switch(pName)
case 'XLabel'
set(myMultiSlider.XLabel, 'String', pVal);
case 'Position'
set(hMultiSlider, 'Position', pVal);
case 'Domain'
userdata.Domain = pVal;
case 'NTicks'
userdata.NTicks = pVal;
case 'TicksRoundDigits'
userdata.TicksRoundDigits = pVal;
case 'UserFcn'
userdata.UserFcn = pVal;
end
end
set(hMultiSlider, 'UserData', userdata);
hMultiSlider = Refresh(hMultiSlider);
%--------------------------------------------------------------------------
function [hMultiSlider] = Refresh(hMultiSlider)
myMultiSlider = get(hMultiSlider);
userdata = myMultiSlider.UserData;
myTick = [0:userdata.NTicks-1] ./ (userdata.NTicks-1);
myTickLabel = num2str([myTick .* diff(userdata.Domain) + userdata.Domain(1)]', ['%0.' num2str(userdata.TicksRoundDigits) 'f']);
set(hMultiSlider, 'XTick', myTick);
set(hMultiSlider, 'XTickLabel', myTickLabel);
%--------------------------------------------------------------------------
function [results]