www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/+mbcgui/+widget/AxisSlider.m

    classdef AxisSlider < mbcgui.widget.Component
    %mbcgui.widget.AxisSlider class
    %    mbcgui.widget.AxisSlider properties:
    %       Position - Property is of type 'rect'
    %       Visible - Property is of type 'on/off'
    %       Parent - Property is of type 'MATLAB array'
    %       Orientation - Property is of type 'string'
    %       MajorTicks - Property is of type 'MATLAB array'
    %       MinorTicks - Property is of type 'bool'
    %       TickLabels - Property is of type 'bool'
    %       AxisColor - Property is of type 'MATLAB array'
    %       MarkerColor - Property is of type 'MATLAB array'
    %       MarkerSize - Property is of type 'double'
    %       Min - Property is of type 'double'
    %       Max - Property is of type 'double'
    %       Value - Property is of type 'double'
    %       String - Property is of type 'ustring'
    %       Selected - Property is of type 'bool'
    %       DragMode - Property is of type 'on/off'
    %       DragCallback - Property is of type 'MATLAB array'
    %       DragStartCallback - Property is of type 'MATLAB array'
    %       DragStopCallback - Property is of type 'MATLAB array'
    %       ClickCallback - Property is of type 'MATLAB array'
    %
    %    mbcgui.widget.AxisSlider methods:
    %       doDrawMarker - Redraw the value marker
    %       doPosition - Redraw axisslider control
    %       doString - Set the string for the axis label
    %       doTickStatus - Set the correct look for the ticks
    %       setLimits - Set the min and max properties of the object
    
    %  Copyright 2015 The MathWorks, Inc. and Ford Global Technologies, Inc.
    
    properties (AbortSet, SetObservable)
        %ORIENTATION Property is of type 'string'
        Orientation = 'vertical';
        %MAJORTICKS Property is of type 'MATLAB array'
        MajorTicks = true;
        %MINORTICKS Property is of type 'bool'
        MinorTicks = true;
        %TICKLABELS Property is of type 'bool'
        TickLabels = true;
        %AXISCOLOR Property is of type 'MATLAB array'
        AxisColor = 'k';
        %MARKERCOLOR Property is of type 'MATLAB array'
        MarkerColor = 'b';
        %MARKERSIZE Property is of type 'double'
        MarkerSize = 5;
        %MIN Property is of type 'double'
        Min = 0;
        %MAX Property is of type 'double'
        Max = 10;
        %VALUE Property is of type 'double'
        Value=0;
        %STRING Property is of type 'ustring'
        String='';
        %SELECTED Property is of type 'bool'
        Selected=false;
        %DRAGMODE Property is of type 'on/off'
        DragMode = 'off';
        %DRAGCALLBACK Property is of type 'MATLAB array'
        DragCallback = [];
        %DRAGSTARTCALLBACK Property is of type 'MATLAB array'
        DragStartCallback = [];
        %DRAGSTOPCALLBACK Property is of type 'MATLAB array'
        DragStopCallback = [];
        %CLICKCALLBACK Property is of type 'MATLAB array'
        ClickCallback = [];
    end
    
    properties (Access=protected, AbortSet)
        %ASLIST Property is of type 'handle vector'
        ASList = [];
        %AXES Property is of type 'MATLAB array'
        Axes = [];
        %MARKER Property is of type 'MATLAB array'
        Marker = [];
    end
    
    
    methods  % constructor block
        function h = AxisSlider( varargin)
        %AXISSLIDER Constructor for axisslider object
        %  H = AXISSLIDER(prop1, val1 ,...)
        %
        % e.g.
        % h = xregGui.AxisSlider('min',0,'max',10,'Orientation','horizontal',...
        %                        'DragMode','on','MajorTicks',[1 3 5 7 9],...
        %                        'Position',[30 100 200 15],...
        %                        'String','Hello','MarkerSize',15)
        
        h@mbcgui.widget.Component(varargin{:});
        % Create HG objects
        lims = [h.Min h.Max];
        h.Axes = axes('Parent', h.Parent, ...
            'Visible',h.Visible,...
            'HitTest', 'off', ...
            'Color', 'none', ...
            'XColor', h.AxisColor, ...
            'YColor', h.AxisColor, ...
            'TickDir', 'out', ...
            'Units', 'pixels', ...
            'FontSize', 8, ...
            'XLim', lims, ...
            'YLim', lims);
        LabelSettings = {'Interpreter', 'none', 'HitTest', 'off'};
        if h.Selected
            LabelSettings = [LabelSettings, {'FontWeight', 'bold'}];
            set(h.Axes, 'LineWidth', 1.5, 'FontWeight', 'bold');
        end
        
        xlabel(h.Axes, '', LabelSettings{:});
        ylabel(h.Axes, '', LabelSettings{:});
        
        h.Marker = patch('Parent', h.Axes, ...
            'HitTest', 'off', ...
            'Clipping','off', ...
            'EdgeColor','none', ...
            'FaceColor', h.MarkerColor);
        
        h.doTickStatus;
        h.doDrawMarker;
        h.doSetDragMode;
        h.doString;
        h.ASList = [
            event.proplistener(h, h.findprop('MajorTicks'), 'PostSet', @i_setTicks); ...
            event.proplistener(h, h.findprop('MinorTicks'), 'PostSet', @i_setTicks); ...
            event.proplistener(h, h.findprop('TickLabels'), 'PostSet', @i_setTicks); ...
            event.proplistener(h, h.findprop('AxisColor'), 'PostSet', @i_setAxesColor); ...
            event.proplistener(h, h.findprop('MarkerColor'), 'PostSet', @i_setMarkerColor); ...
            event.proplistener(h, h.findprop('Orientation'), 'PostSet', @i_setOrientation); ...
            event.proplistener(h, h.findprop('Min'), 'PostSet', @i_setMinMax); ...
            event.proplistener(h, h.findprop('Max'), 'PostSet', @i_setMinMax); ...
            event.proplistener(h, h.findprop('Value'), 'PostSet', @i_setValue); ...
            event.listener(h, 'ObjectBeingDestroyed', @i_destroyObject); ...
            event.proplistener(h, h.findprop('String'), 'PostSet', @i_setstring); ...
            event.proplistener(h, h.findprop('Selected'), 'PostSet', @i_setselected); ...
            event.proplistener(h, h.findprop('DragMode'), 'PostSet', @i_setDragMode); ...
            event.proplistener(h, h.findprop('MarkerSize'), 'PostSet', @i_setValue); ...
            ];
        
        end  % axisslider
        
    end  % constructor block
    
    methods  % public methods
        %----------------------------------------
        function doDrawMarker(h)
        %DODRAWMARKER Redraw the value marker
        %  DODRAWMARKER(OBJ) redraws the value marker on the axis
        
        val = h.Value;
        if isnan(val)
            set(h.Marker, 'Visible','off');
            if strcmp(h.Orientation, 'vertical')
                xlabel(h.Axes, '');
                ylabel(h.Axes, h.String);
            else
                xlabel(h.Axes, h.String);
                ylabel(h.Axes, '');
            end
        else
            % The figure units are pixels, and the
            % size of the axes is 1 pixel in the "minor" direction.  The
            % limits of the axes are the same in both directions.
            pos = h.Position;
            lims = get(h.Axes, 'XLim'); % same as "ylim"
            
            % This is the value at which the marker is to be positioned.
            val = min(max(h.Value,lims(1)),lims(2));
            
            vert = zeros(3,3);
            hw = h.MarkerSize; % in pixels (in the "minor" direction)
            rng = lims(2)-lims(1); % slider range
            
            if strcmp(h.Orientation, 'vertical')
                axissize = max(pos(4),1); % size, in pixels of the axes in the "major" direction
                
                % In the "major" direction, the marker extends "MarkerSize" pixels
                % in either direction.  Calculate this in axis units.
                markerdelta_major = (hw/axissize)*rng;
                % Same as above, except that we know the axis size in this direction is 1 pixel
                markerdelta_minor = hw*rng;
                
                % One vertex at the current value
                vert(1, 1) = lims(2);
                vert(1, 2) = val;
                % One vertext up and to the right
                vert(2, 1) = lims(2) + markerdelta_minor;
                vert(2, 2) = val + markerdelta_major;
                % One vertext down and to the right
                vert(3, 1) = vert(2, 1);
                vert(3, 2) = val - markerdelta_major;
            else
                % See explanation above
                axissize = max(pos(3),1);
                
                markerdelta_major = (hw/axissize)*rng;
                markerdelta_minor = hw*rng;
                
                vert(1, 1) = val;
                vert(1, 2) = lims(1);
                vert(2, 1) = val + markerdelta_major;
                vert(2, 2) = lims(1)+ markerdelta_minor;
                vert(3, 1) = val - markerdelta_major;
                vert(3, 2) = vert(2, 2);
            end
            % Patch has only one face, joining the three vertices.
            set(h.Marker, 'Vertices', vert, 'Faces', [1 2 3], 'Visible', h.Visible);
        end
        
        end  % doDrawMarker
        
        %----------------------------------------
        function doPosition( h , newpos)
        %DOPOSITION Redraw axisslider control
        %
        %  H.DOPOSITION;
        %  H.DOPOSITION(NEWPOS);
        %
        
        if nargin==1
            newpos = h.Position;
        end
        newpos(3:4) = max(newpos(3:4), [1 1]);
        
        if strcmp(h.Orientation, 'vertical')
            axpos = [max(newpos(1), newpos(1)+newpos(3)-6 ) newpos(2)  1  newpos(4)];
        else
            axpos = [newpos(1)  max(newpos(2), newpos(2)+newpos(4)-6)  newpos(3) 1];
        end
        
        set(h.Axes, 'Position', axpos);
        
        
        end  % doPosition
        
        %----------------------------------------
        function doString(h)
        %DOSTRING Set the string for the axis label
        %
        %  H.DOSTRING;
        
        if strcmp(h.Orientation, 'vertical')
            xlabel(h.Axes, '');
            ylabel(h.Axes, h.String);
        else
            xlabel(h.Axes, h.String);
            ylabel(h.Axes, '');
        end
        end  % doString
        
        %----------------------------------------
        function doTickStatus( h, majorticks, minorticks, ticklabels)
        %DOTICKSTATUS Set the correct look for the ticks
        %
        %  H.DOTICKSTATUS;
        %  H.DOTICKSTATUS(MAJORTICKS, MINORTICKS, TICKLABELS);
        
        
        if nargin==1
            majorticks = h.MajorTicks;
            minorticks = h.MinorTicks;
            ticklabels = h.TickLabels;
        end
        
        
        if numel(majorticks)>1
            set(h.Axes, 'XTick', unique(majorticks), 'YTick', unique(majorticks));
        elseif majorticks
            set(h.Axes, 'XTickMode', 'auto', 'YTickMode', 'auto');
        else
            set(h.Axes, 'XTick', [], 'YTick', []);
        end
        
        if minorticks
            minorticks_state = 'on';
        else
            minorticks_state = 'off';
        end
        set(h.Axes, 'XMinorTick', minorticks_state, 'YMinorTick', minorticks_state);
        
        
        if ticklabels
            set(h.Axes, 'XTickLabelMode', 'auto', 'YTickLabelMode', 'auto');
        else
            set(h.Axes, 'XTickLabel', [], 'YTickLabel', []);
        end
        
        
        end  % doTickStatus
        
        %----------------------------------------
        function setLimits( h, mn, mx )
        %SETLIMITS Set the min and max properties of the object
        %  SETLIMITS(OBJ, MIN, MAX)
        
        % Disable property listeners during operation
        disableListeners(h)
        
        set(h, 'Min', mn, 'Max', mx);
        if h.Min>h.Max
            lims = [0 1];
        else
            lims = [h.Min h.Max];
        end
        set(h.Axes, 'XLim', lims, 'YLim', lims);
        if ~isnan(h.Value)
            h.doDrawMarker;
        end
        enableListeners(h)
        
        end  % setLimits
        
    end  % public methods
    
    
    methods (Hidden) % possibly private or hidden
        %----------------------------------------
        function doSetDragMode(obj)
        
        h = obj.Axes;
        if strcmp(obj.DragMode,'on')
            set(obj.Marker,'ButtonDownFcn',{@i_DragStart,obj,h},'HitTest','on');
            set(obj.Axes,'ButtonDownFcn',{@i_Click,obj,h},'HitTest','on');
        else
            set(obj.Marker,'ButtonDownFcn',[],'HitTest','off');
            set(obj.Axes,'ButtonDownFcn',[],'HitTest','off');
        end
        end  % doSetDragMode
        
    end  % possibly private or hidden
    
    methods(Access=protected)
        function setPosition(obj,pos)
        obj.doPosition(pos);
        obj.doDrawMarker;
        end
        
        function setVisible(obj,vis)
        set(obj.Axes, 'Visible', vis);
        if isnan(obj.Value)
            set(obj.Marker, 'Visible','off');
        else
            set(obj.Marker, 'Visible', vis);
        end
        end
        
    end
    
end  % classdef

function i_setTicks(~, evt)
h= evt.AffectedObject;
h.doTickStatus;
end  % i_setTicks


function i_setAxesColor(~, evt)
h = evt.AffectedObject;
ax = h.Axes;
set(ax, 'XColor', h.AxisColor, 'YColor', h.AxisColor);
end  % i_setAxesColor


function i_setMarkerColor(~, evt)
h = evt.AffectedObject;
set(h.Marker, 'FaceColor', h.MarkerColor);
end  % i_setMarkerColor


function i_setOrientation(src, evt)
h = evt.AffectedObject;
ax = h.Axes;
h.doPosition;
h.doDrawMarker;
s.AffectedObject = h;
s.NewValue = h.String;
i_setstring(src,s,ax);
end  % i_setOrientation


function i_setMinMax(~, evt)
h = evt.AffectedObject;
ax = h.Axes;
if h.Min>=h.Max
    lims = [0 1];
else
    lims = [h.Min h.Max];
end
set(ax, 'XLim', lims, 'YLim', lims);
h.doDrawMarker;
end  % i_setMinMax


function i_setValue(~, evt)
h = evt.AffectedObject;
h.doDrawMarker;
end  % i_setValue


function i_destroyObject(src,~)
% delete the HG objects associated with this object
if ~mbcgui.util.isBeingDestroyed(src.Parent)
    delete(src.Axes);
end
end  % i_destroyObject


function i_setstring(~, evt)
h = evt.AffectedObject;
h.doString;
end  % i_setstring


function i_setselected(~, evt)
h = evt.AffectedObject;
ax = h.Axes;
if evt.NewValue
    set([get(ax, 'YLabel'); get(ax, 'XLabel')], 'FontWeight', 'bold');
    set(ax, 'LineWidth', 1.5, 'FontWeight', 'bold');
else
    set([get(ax, 'YLabel'); get(ax, 'XLabel')], 'FontWeight', 'normal');
    set(ax, 'LineWidth', 0.5, 'FontWeight', 'normal');
end
end  % i_setselected


function i_setDragMode(~,evt)
h = evt.AffectedObject;
h.doSetDragMode;
end  % i_setDragMode

function i_DragStart(~,~,obj,h)
F = ancestor(obj.Parent, 'figure');
set(F, 'WindowButtonMotionFcn', {@i_DragMotion,obj,h}, ...
    'WindowButtonUpFcn', {@i_DragRelease,obj,h});
if ~isempty(obj.DragStartCallback)
    xregcallback(obj.DragStartCallback,obj,obj.Value);
end
end  % i_DragStart


%-------------------
function i_DragMotion(~,~,obj,h)

p = get(h,'CurrentPoint');
if strcmp(obj.Orientation, 'vertical')
    obj.Value = p(1,2);
else
    obj.Value = p(2,1);
end
if ~isempty(obj.DragCallback)
    xregcallback(obj.DragCallback,obj,obj.Value);
end
end  % i_DragMotion


%-------------------
function i_DragRelease(src,evt,obj,h)

i_DragMotion(src,evt,obj,h)
F = ancestor(obj.Parent, 'figure');
set(F, 'WindowButtonMotionFcn', '', ...
    'WindowButtonUpFcn', '');
if ~isempty(obj.DragStopCallback)
    xregcallback(obj.DragStopCallback,obj,obj.Value);
end
end  % i_DragRelease


%-------------------
function i_Click(~,~,obj,h)

p = get(h,'CurrentPoint');
if strcmp(obj.Orientation, 'vertical')
    obj.Value = p(1,2);
else
    obj.Value = p(2,1);
end
if ~isempty(obj.ClickCallback)
    xregcallback(obj.ClickCallback,obj,obj.Value);
end
end  % i_Click