Code covered by the BSD License  

Highlights from
MATLAB Support Package for Velleman K8055/VM110 Experiment Board

MATLAB Support Package for Velleman K8055/VM110 Experiment Board

by

 

MATLAB library for communicating with a Velleman K8055/VM110 USB Experiment Interface Board

gui.(Sealed) slider
% gui.slider
%    A widget that displays an adjustable slider
%
%    w = gui.slider creates a widget that displays an adjustable slider and
%    an associated numeric entry field (changes to the slider are reflected
%    in the number field and vice versa). The widget is added to the
%    current autogui  (if there is no current autogui, one is created). 
%
%    w = gui.slider(M) creates the widget with the label string M.
%
%    w = gui.slider(M,R) creates the widget with the label string M, and
%    range R. R is a a two-element vector, [minValue maxValue].
%
%    w = gui.slider(M,R,G) creates the widget with the label string M and
%    range R, and adds it to the gui container G.
%
%  Sample usage:
%     g = gui.autogui;
%    w1 = gui.slider;
%    w2 = gui.slider('Preemphasis', [0 1]);
%    w3 = gui.slider('Preemphasis', [0 1], g);
%
%    Also see: 
%    <a href="matlab:help gui.slider.Value">gui.slider.Value</a>
%    <a href="matlab:help gui.numericmenu">gui.numericmenu</a>
%    <a href="matlab:help gui.listbox">gui.listbox</a>

%   Copyright 2009 The MathWorks, Inc.

classdef (Sealed) slider < gui.labeledwidget

    properties(Dependent)
        % Value 
        %   A number indicating the current position of the slider.
        %   The permissible range of numbers is specified by the ValueRange
        %   property.
        %   Sample usage:
        %    s = gui.slider('Choose a Frequency (Hz)');
        %    s.ValueRange = [100 2000];
        %    s.Value = 500; % set the slider to the 500 Hz location
        %    s.Value % get the value
        Value
    end
    
    properties (Dependent, SetObservable)

        % ValueRange - Specifies the range of allowed slider values
        %
        %   ValueRange is a two element vector, [minValue maxValue], that
        %   indicates the values of the leftmost and rightmost slider
        %   positions. 
        %
        %   Sample usage:
        %    w = gui.slider;
        %    w.ValueRange = [50 200];
        ValueRange
        
        % Enable - Specifies whether the widget is active or not.
        %
        %   Enable is a boolean property (true/false).     
        %    true => user can modify the state of the widget 
        %           (e.g., enter text into a field, move a slider)
        %    false => the widget is "grayed out" and cannot be modified.
        %
        %   Sample usage:
        %    w = gui.slider;
        %    w.Enable = false;          
        Enable        
    end
        
    properties(Access=private)
        UiControl
        UiFlowContainer
        UiNumberEdit        
    end
    
    methods
        function obj = slider(labelStr, range, varargin)
            
           if ~exist('labelStr', 'var')
               labelStr = 'Choose a value:';
           else
               if ~ischar(labelStr)
                   throw(MException('slider:InvalidParameter', ...
                       'Label must be a character string (e.g., ''Choose value:'''));
               end
           end
           if ~exist('range', 'var')
               range = [0 1];
           else
               validateRange(range);
           end
           initialValue = mean(range);
           
            obj = obj@gui.labeledwidget(labelStr,varargin{:});            
            assert(~obj.Initialized && ~obj.Visible);
            
            % Later calls to setSizeInFlow(...) and getHeightInFlow()
            % assume UiHandle is a uiflowcontainer            
            assert(strcmp(get(obj.UiHandle,'type'), 'uiflowcontainer'));
            
            color = obj.getParentUiColor();
            obj.UiFlowContainer = gui.util.uiflowcontainer('parent', obj.UiHandle, ...
                'FlowDirection', 'lefttoright');
            
            obj.UiNumberEdit = uicontrol('Style', 'edit', ...
                'string', num2str(initialValue), ...
                'BackgroundColor', 'w', ...
                'parent', obj.UiFlowContainer, ...
                'tag', 'slider-uinumberedit', ...
                'callback', @(h,e) editCallback(obj));
                    
            obj.UiControl = uicontrol( 'Style','slider','Parent',obj.UiFlowContainer,...
                'BackgroundColor',color,...   
                'units', 'pixels', ...                
                'min', range(1), ...
                'max', range(2), ...
                'value', initialValue, ...
                'HorizontalAlignment', 'Left', ...                
                'HandleVisibility', 'off', ...
                'tag', 'slider-uicontrol', ...
                'callback', @(h,e) propagateValueChange(obj));
                                                            
            obj.Initialized = true;
            obj.Visible = true;
        end
    end
    
    % Interface to properties
    methods 
        function set.Enable(obj,makeEnable)
            if makeEnable
                set(obj.UiControl,'Enable','on');
            else
                set(obj.UiControl,'Enable','off');
            end
        end
        
        function out = get.Enable(obj)
            out = strcmp(get(obj.UiControl,'Enable'), 'on');
        end
        
        
        function set.Value(obj,val)
            ensureValidNumber(val, 'Value');
            range = obj.ValueRange;
            if val < range(1) || val > range(2)
                throw(MException('slider:InvalidValue', ...
                    'Value should be between MinValue (%g) and MaxValue (%g)', range(1), range(2)));
            end
            set(obj.UiControl,'Value',val);
            propagateValueChange(obj);
        end
        
        function out = get.Value(obj)
            out = get(obj.UiControl,'Value');
        end
        
        function set.ValueRange(obj, range)            
            validateRange(range);
            v = get(obj.UiControl, 'Value');
            if (v < range(1))
                newval = range(1);
                warning('slider:ValueReset', 'Value set to new MinValue (%g)', newval);
                propagateValueChange(obj);
            elseif (v > range(2))
                newval = range(2);
                warning('slider:ValueReset', 'Value set to new MaxValue (%g)', newval);                
            else
                newval = v;
            end
            set(obj.UiControl,'Min', range(1), 'Max', range(2), 'Value', newval);
            if v ~= newval
                propagateValueChange(obj);
            end
        end
        
        function out = get.ValueRange(obj)
            out = [get(obj.UiControl, 'Min') get(obj.UiControl, 'Max')];
        end
        
    end
    
    methods (Hidden)
        function editCallback(obj)
            newVal = str2double(get(obj.UiNumberEdit, 'string'));
            currentVal = get(obj.UiControl, 'value');
            if isnan(newVal) || ~ensureValidNumber(newVal)
                set(obj.UiNumberEdit, 'string', num2str(currentVal));
            else
                range = obj.ValueRange;
                newVal = min(max(newVal, range(1)), range(2));
                set(obj.UiControl, 'Value', newVal);
                propagateValueChange(obj);
            end
        end
 
        function propagateValueChange(obj)
            v = get(obj.UiControl, 'value');
            set(obj.UiNumberEdit, 'String', num2str(v));
            notify(obj, 'ValueChanged');
        end
        
    end    
    
    methods (Access=protected)
        
        % called upon initialization
        function initNotify(obj)
            initNotify@gui.labeledwidget(obj);

            labelSize = get(obj.UiLabel, 'Extent'); % [0 0 width height]            
            obj.Position = struct('width',  ceil(1.5*labelSize(3)), ...
                                  'height', 2*ceil(1.1*labelSize(4)) );
            
            obj.LabelLocation = 'above';
        end
        
        % override method
        function postLabelLocationChange(obj, labelLoc)                
            uiControlHeight = gui.util.uiposition.getHeightInFlow(obj.UiControl);            
            uiLabelHeight = gui.util.uiposition.getHeightInFlow(obj.UiControl);            
            switch labelLoc
                case 'none'
                    obj.setPositionHeight( uiControlHeight );
                case {'above','below'}
                    obj.setPositionHeight( uiLabelHeight + uiControlHeight );
                case {'left', 'right'}
                    obj.setPositionHeight( max(uiLabelHeight, uiControlHeight) );
            end             
        end
        
        % override method
        % pos is a vector [x y w h]
        function postPositionChange(obj, pos)
            nans = isnan(pos(3:4));
            if all(nans), return; end
            if nans(1)
                pos(3) = obj.getPositionWidth();
            end
            if nans(2)
                pos(4) = obj.getPositionHeight();
            end
            w = pos(3); h = pos(4);
            
            switch obj.LabelLocation
                case 'none'
                    labelpos = [];                    
                    ctrlpos = [round(0.70 * w)  round(0.95 * h)];
                    editpos = [round(0.30 * w)  round(0.95 * h)];
                case {'above','below'}
                    labelpos = [round(0.95 * w) round(0.45 * h)];
                    ctrlpos =  [round(0.70 * w) round(0.50 * h)];
                    editpos =  [round(0.25 * w) round(0.50 * h)];
                case {'left', 'right'}
                    labelpos = [round(0.30 * w) round(0.95 * h)];
                    ctrlpos =  [round(0.40 * w) round(0.95 * h)];
                    editpos =  [round(0.25 * w) round(0.95 * h)];
            end            
            
            gui.util.uiposition.setSizeInFlow(obj.UiControl, ctrlpos);            
            gui.util.uiposition.setSizeInFlow(obj.UiNumberEdit, editpos);            
            if ~isempty(labelpos)
                gui.util.uiposition.setSizeInFlow(obj.UiLabel, labelpos);
            end                      
        end
        
    end    

    
end


function valueOkay = ensureValidNumber(val, str)
valueOkay = isscalar(val) && isnumeric(val) && isreal(val) && ~isnan(val) && ~isinf(val);
if nargout==0 && ~valueOkay
    throwAsCaller(MException('slider:InvalidValue', '%s should be a real number', str));
end
end

function validateRange(range)
if ~(isnumeric(range) && numel(range)==2)
    throw(MException('slider:InvalidRange', ...
        ['ValueRange should be of the form [MinValue MaxValue]\n' ...
        'with MinValue < MaxValue and both being real numbers']));
end
ensureValidNumber(range(1), 'MinValue');
ensureValidNumber(range(2), 'MaxValue');
if range(1) >= range(2)
    throw(MException('slider:InvalidRange', 'MinValue should be smaller than MaxValue'));
end
end

Contact us