diff --git a/Required packages/Cursorbar/+graphics/+internal/CursorbarContainer.m b/Required packages/Cursorbar/+graphics/+internal/CursorbarContainer.m new file mode 100644 index 0000000..5aa1483 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/+internal/CursorbarContainer.m @@ -0,0 +1,261 @@ +classdef (ConstructOnLoad=true) CursorbarContainer < handle + % CursorbarContainer Container class for a graphics.Cursorbar objects. + % + % Container class for graphics.Cursorbar objects, where de-serialization + % restores the links. + % + % MCOS graphics cannot rely on custom machinery in load to restore + % Cursorbar listeners. Instead, create a CursorbarContainer to wrap the + % Cursorbar, which will restore the listeners when it is de-serialized. + % + % CursorbarContainer requires the new MATLAB graphics system that was + % introduced in R2014b + % + % Usage: + % CursorbarContainer() - Creates a CursorbarContainer + % without linked Cursorbar handle. + % CursorbarContainer(hCursorbar) - Creates a CursorbarContainer for + % the specified Cursorbar handle. + % + % CursorbarContainer Constructor: + % CursorbarContainer - CursorbarContainer constructor. + % + % CursorbarContainer Properties: + % Key - The key to the stored application data + % Target - Targets of the Cursorbar + % PropertyValues - Property-value pairs of the Cursorbar + % CursorbarHandle - The Cursorbar handle + % + % CursorbarContainer Methods: + % saveobj - Serialize the Target and PropertyValues. + % hasCursorbar - Checks if the CursorbarContainer contains + % the current cursorbar. + % + % CursorbarContainer Static Methods: + % loadobj - Restore the Cursorbar listeners on + % de-serialization. + % getCursorbars - Get all the cursorbars from the current + % figure. + % getContainers - Get all the containers from the current + % figure. + % + % Inherited handle Methods: + % addlistener - Add listener for event. + % delete - Delete a handle object. + % eq - Test handle equality. + % findobj - Find objects with specified property + % values. + % findprop - Find property of MATLAB handle object. + % ge - Greater than or equal relation. + % gt - Greater than relation. + % isvalid - Test handle validity. + % le - Less than or equal relation for handles. + % lt - Less than relation for handles. + % ne - Not equal relation for handles. + % notify - Notify listeners of event. + % + % Inherited handle Events: + % ObjectBeingDestroyed - Notifies listeners that a particular + % object has been destroyed. + % Web: + % Undocumented Matlab: Undocumented cursorbar object. + % + % See also: Cursorbar. + % + % Thanks to Yaroslav Don for his assistance in updating cursorbar for + % MATLAB Graphics and for his contribution of new functionality. + + % This class is based on linkaxes and matlab.graphics.internal.LinkAxes. + + % Copyright 2016 The MathWorks, Inc. + + + %% Properties + properties (Constant) + Key = 'GraphicsCursorbarContainer' % The key to the stored application data + end + + % -------------------------------------- + + properties (SetAccess = 'protected') + Target@handle % Targets of the Cursorbar + PropertyValues % Property-value pairs of the Cursorbar + end + + % -------------------------------------- + + properties (Transient) + CursorbarHandle@graphics.Cursorbar scalar % The Cursorbar handle + end + + properties (SetAccess = 'protected', Hidden) + PeerContainer@graphics.internal.CursorbarContainer % A handle to a container's Peer, if Cursorbar also has one + end + + %% Main Methods + + methods + + function hThis = CursorbarContainer(hCursorbar) + % CURSORBARCONTAINER A CursorbarContainer constructor. + % + % See also: CursorbarContainer. + + % Check MATLAB Graphics system version + if verLessThan('matlab','8.4.0') + error('graphics:internal:CursorbarContainer:CursorbarContainer:oldVersion', ... + 'CursorbarContainer requires the new MATLAB graphics system that was introduced in R2014b.'); + end + + % call handle constructor + hThis = hThis@handle; + + % set up the Cursorbar handles + % each container can hold only a single Cursorbar + if nargin==1 + validateattributes(hCursorbar,{'graphics.Cursorbar'},{'nonempty'}); + % + for i=numel(hCursorbar):-1:1 + hThis(i).CursorbarHandle = hCursorbar(i); + end + reshape(hThis,size(hCursorbar)); + end + end + + % -------------------------------------- + + function hThis = saveobj(hThis) + % SAVEOBJ Serialize the Target and PropertyValues. + + % set the target and the property values right before serialization; + if ~isempty(hThis.CursorbarHandle) + hThis.Target = hThis.CursorbarHandle.Target; + hThis.PropertyValues = { ... + 'BottomMarker', hThis.CursorbarHandle.BottomMarker, ... + 'CreateFcn', hThis.CursorbarHandle.CreateFcn, ... + 'CursorLineColor', hThis.CursorbarHandle.CursorLineColor, ... + 'CursorLineStyle', hThis.CursorbarHandle.CursorLineStyle, ... + 'CursorLineWidth', hThis.CursorbarHandle.CursorLineWidth, ... + 'DeleteFcn', hThis.CursorbarHandle.DeleteFcn, ... + 'DisplayName', hThis.CursorbarHandle.DisplayName, ... + 'FigureCallbacks', hThis.CursorbarHandle.FigureCallbacks, ... + 'HitTest', hThis.CursorbarHandle.HitTest, ... + 'Interruptible', hThis.CursorbarHandle.Interruptible, ... + 'Location', hThis.CursorbarHandle.Location, ... + 'Orientation', hThis.CursorbarHandle.Orientation, ... + 'Parent', hThis.CursorbarHandle.Parent, ... + 'Position', hThis.CursorbarHandle.Position, ... + 'SelectionHighlight', hThis.CursorbarHandle.SelectionHighlight, ... + 'ShowText', hThis.CursorbarHandle.ShowText, ... + 'Tag', hThis.CursorbarHandle.Tag, ... + 'TargetIntersections', hThis.CursorbarHandle.TargetIntersections, ... + 'TargetMarkerEdgeColor', hThis.CursorbarHandle.TargetMarkerEdgeColor, ... + 'TargetMarkerFaceColor', hThis.CursorbarHandle.TargetMarkerFaceColor, ... + 'TargetMarkerSize', hThis.CursorbarHandle.TargetMarkerSize, ... + 'TargetMarkerStyle', hThis.CursorbarHandle.TargetMarkerStyle, ... + 'TextDescription', hThis.CursorbarHandle.TextDescription, ... + 'TopMarker', hThis.CursorbarHandle.TopMarker, ... + 'UserData', hThis.CursorbarHandle.UserData, ... + 'Visible', hThis.CursorbarHandle.Visible ... + }; + end + end + + end + + % -------------------------------------- + + methods (Static = true) + function hThis = loadobj(hThis) + % LOADOBJ Restore the Cursorbar listeners on de-serialization. + + % create a new cursorbar if the target is valid + if ~isempty(hThis.Target) && all(isgraphics(hThis.Target)) && ~isempty(hThis.PropertyValues) + + % construct a new Cursorbar + hThat = hThis.PeerContainer; + if ~isempty(hThat) && ~isempty(hThat.CursorbarHandle) + % there is a valid Peer: create a Crossbar and set its values + hThis.CursorbarHandle = drawCrossbar(hThat.CursorbarHandle, hThis.PropertyValues{:}); + else + % create a new Cursorbar and set its values + hThis.CursorbarHandle = graphics.Cursorbar(hThis.Target, hThis.PropertyValues{:}); + end + end + + end + end + + %% Auxiliary Methods + + methods + + function tf = hasCursorbar(hThis,hCursorbar) + % HASCURSORBAR Checks if the CursorbarContainer contains the current cursorbar. + validateattributes(hCursorbar,{'graphics.Cursorbar'},{'scalar'}); + + % compare + tf = [hThis.CursorbarHandle]==hCursorbar; + tf = reshape(tf,size(hThis)); + end + + end + % -------------------------------------- + + methods (Static) + function hCursorbars = getCursorbars(hFig) + % GETCURSORBARS Get all the cursorbars from the current figure. + assert(ishghandle(hFig) && strcmp(hFig.Type,'figure'), ... + 'graphics:internal:CursorbarContainer:getCursorbars:notAFigure', ... + 'Input must be a valid figure handle.'); + % + hContainers = CursorbarContainer.getContainers(hFig); + if ~isempty(hContainers) + hCursorbars = [hContainers.CursorbarHandle]; + else + hCursorbars = graphics.GraphicsPlaceholder.empty; + end + end + + % -------------------------------------- + + function hContainers = getContainers(hFig) + % GETCONTAINERS Get all the containers from the current figure. + assert(ishghandle(hFig) && strcmp(hFig.Type,'figure'), ... + 'graphics:internal:CursorbarContainer:getContainers:notAFigure', ... + 'Input must be a valid figure handle.'); + % + hContainers = getappdata(hFig, graphics.internal.CursorbarContainer.Key); + end + end + + %% Protected Methods + + methods (Access = {?graphics.Cursorbar, ?graphics.internal.CursorbarContainer}) + + function setPeer(hThis,hThat) + % SETPEER Sets peer container handle. + + % set only the handle links + % Cursorbar is responsible for all the listener mechanisms + validateattributes(hThis,{'graphics.internal.CursorbarContainer'},{'scalar'}); + validateattributes(hThat,{'graphics.internal.CursorbarContainer'},{'scalar'}); + hThis.PeerContainer = hThat; + hThat.PeerContainer = hThis; + end + + % -------------------------------------- + + function removePeer(hThis) + % REMOVEPEER Removes peer container handle. + + % remove only the handle links + % Cursorbar is responsible for all the listener mechanisms + hThis.PeerContainer.PeerContainer = graphics.internal.CursorbarContainer.empty; + hThis.PeerContainer = graphics.internal.CursorbarContainer.empty; + end + + end + + +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/Cursorbar.m b/Required packages/Cursorbar/+graphics/@Cursorbar/Cursorbar.m new file mode 100644 index 0000000..6707ac4 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/Cursorbar.m @@ -0,0 +1,1677 @@ +classdef Cursorbar < graphics.Graphics & matlab.mixin.SetGet + % CURSORBAR Creates a cursor line attached to an axes or lines. + % + % The Cursorbar can be dragged interactively across the axes. If + % attached to a plot, the cursor points are updated as well. The + % Cursorbar can be either horizontal or vertical. + % + % Cursorbar requires the new MATLAB graphics system that was + % introduced in R2014b + % + % Usage: + % graphics.Cursorbar(hTarget) - Creates a Cursorbar on a target + % Axes or Chart. + % graphics.Cursorbar(hTarget, ...) - Creates a Cursorbar on a target + % Axes or Chart with additional + % property-value pairs. + % Example: + % x = linspace(0,20,101); + % y = sin(x); + % % + % h = plot(x,y); + % graphics.Cursorbar(h); + % + % Cursorbar Constructor: + % Cursorbar - Cursorbar constructor + % + % Cursorbar Properties: + % Annotation - Legend icon display style + % BeingDeleted - Deletion status of group + % BottomHandle - Handle to the bottom (left) edge marker + % BottomMarker - Top (right) edge marker shape + % BusyAction - Callback queuing + % ButtonDownFcn - Mouse-click callback + % Children - Children of Cursorbar + % CreateFcn - Creation callback + % CursorLineColor - Cursor line's color + % CursorLineStyle - Cursor line's style + % CursorLineWidth - Cursor line's width + % CursorbarOrientation - Permitted Cursorbar Orientation options + % CursorbarShowText - Permitted Cursorbar ShowText options + % DataCursorHandle - Handle to the Data Cursor + % DeleteFcn - Deletion callback + % DisplayHandle - Display text handle + % DisplayName - Text used by the legend + % FigureCallbacks - Additional Figure callbacks + % HandleVisibility - Visibility of object handle {'on','off'} + % HitTest - Response to mouse clicks captured by + % children + % Interruptible - Callback interruption + % Location - Location is a single value which is used + % to set the Position, based on the + % Orientation + % Orientation - Orientation of Cursorbar + % {'vertical','horizontal'} + % Parent - Parent of Cursorbar + % PermittedChartTargets - Classes of permitted targets + % PickableParts - Children that can capture mouse clicks + % Position - Position is used to set the location of + % main marker for the intersection + % Selected - Selection state + % SelectionHighlight - Display of selection handles when + % selected + % ShowText - Showing the Cursorbar Text {'on','off'} + % Tag - Tag to associate with the Cursorbar + % Target - Handle to the Target + % TargetIntersections - How many intersections are plotted + % {'multiple','single'} + % TargetMarkerEdgeColor - Target's marker outline color + % TargetMarkerFaceColor - Target's marker fill color + % TargetMarkerSize - Target's marker size + % TargetMarkerStyle - Target's marker style + % TextDescription - Type of text description + % {'short','long'} + % TopHandle - Handle to the top (right) edge marker + % TopMarker - Top (right) edge marker shape + % Type - Type of graphics object + % UIContextMenu - Context menu + % UpdateFcn - Update callback + % UserData - Data to associate with the Cursorbar + % object + % Visible - Visibility of Cursorbar {'on','off'} + % + % Cursorbar Methods: + % drawCrossbar - Draws a linked perpendicular bar + % duplicate - Duplicate the cursorbar to an identical + % one + % getCursorInfo - Get DataCursor info from Cursorbar + % getMarkerLocations - Return x,y position of the Cursorbar's + % intersection markers + % ishandle - Checks on self if valid handle + % isTargetAxes - Is the Target an axes + % isTargetChart - Is the Target a permitted chart object + % + % Inherited matlab.mixin.SetGet Methods: + % set - Set MATLAB object property values. + % get - Get MATLAB object properties. + % setdisp - Specialized MATLAB object property + % display. + % getdisp - Specialized MATLAB object property + % display. + % + % Inherited handle Methods: + % addlistener - Add listener for event. + % delete - Delete a handle object. + % eq - Test handle equality. + % findobj - Find objects with specified property + % values. + % findprop - Find property of MATLAB handle object. + % ge - Greater than or equal relation. + % gt - Greater than relation. + % isvalid - Test handle validity. + % le - Less than or equal relation for handles. + % lt - Less than relation for handles. + % ne - Not equal relation for handles. + % notify - Notify listeners of event. + % + % Inherited matlab.mixin.CustomDisplay Methods: + % details - Fully detailed formal object display. + % disp - Simple informal object display. + % display - Print variable name and display object. + % + % Inherited matlab.mixin.Heterogeneous Methods: + % cat - Concatenation for heterogeneous arrays. + % horzcat - Horizontal concatenation for + % heterogeneous arrays. + % vertcat - Vertical concatenation for + % heterogeneous arrays. + % + % Cursorbar Events: + % BeginDrag - Notifies listeners that the dragging of + % the Cursorbar has begun. + % EndDrag - Notifies listeners that the dragging of + % the Cursorbar has ended. + % UpdateCursorBar - Notifies listeners that the Cursorbar + % has been updated. + % + % Inherited handle Events: + % ObjectBeingDestroyed - Notifies listeners that a particular + % object has been destroyed. + % Web: + % Undocumented Matlab: Undocumented cursorbar object. + % + % See also: graphics.Cursorbar.Cursorbar, + % graphics.Cursorbar.getCursorInfo, + % graphics.Cursorbar.getMarkerLocations, + % graphics.Cursorbar.isTargetAxes, + % graphics.Cursorbar.isTargetChart, + % . + % cursorbar, crossbar, + % graphics.Cursorbar.duplicate, + % graphics.Cursorbar.drawCrossbar, + % . + % hobjects, + % graphics.Graphics, + % graphics.GraphicsPlaceholder, + % graphics.internal.CursorbarContainer. + % + % Thanks to Yaroslav Don for his assistance in updating cursorbar for + % MATLAB Graphics and for his contribution of new functionality. + + % Copyright 2003-2016 The MathWorks, Inc. + + % Change Log: + % 13 Feb 2015: First version posted on the MathWorks file exchange: + % Cursorbar - File Exchange - MATLAB Central. + % 14 May 2015: Added a custom display; added logarithmic scale support; minor bug fixes. + % XX Jan 2016: Added saving and loading functionality; added empty allocation; + % improved construction time; improved stability; minor bug fixes. + + %% Public Properties + + properties + Parent@handle % Parent of Cursorbar + + % Line objects used to create larger drag surfaces for cursor line + + DisplayHandle@handle % Display text handle + TopHandle@handle % Handle to the top (right) edge marker + BottomHandle@handle % Handle to the bottom (left) edge marker + + % Callbacks + + CreateFcn = '' % Creation callback + DeleteFcn = '' % Deletion callback + UpdateFcn = '' % Update callback + FigureCallbacks % Additional Figure callbacks + + % Identifiers + + Tag@char = '' % Tag to associate with the Cursorbar + UserData % Data to associate with the Cursorbar object + end + % -------------------------------------- + properties (Dependent) + + % Identifiers + + Annotation % Legend icon display style + DisplayName % Text used by the legend + + % Parent/Child + + Children % Children of Cursorbar + HandleVisibility % Visibility of object handle + + % Interactive Control + + Selected % Selection state + SelectionHighlight % Display of selection handles when selected + + % Callback Execution Control + + PickableParts % Children that can capture mouse clicks + HitTest % Response to mouse clicks captured by children + Interruptible % Callback interruption + BusyAction % Callback queuing + + % Creation and Deletion Control + + BeingDeleted % Deletion status of group + end + % -------------------------------------- + properties (SetObservable) + Location@double = 0 % Location is a single value which is used to set the Position, based on the Orientation + Position@double % Position is used to set the location of main marker for the intersection + + % Handles + + Target@handle % Handle to the Target + DataCursorHandle@handle % Handle to the Data Cursor + UIContextMenu@handle % Context menu + + % Cursor styles + + CursorLineColor@double = [0 0 0] % Cursor line's color + CursorLineStyle@char = '-' % Cursor line's style + CursorLineWidth@double = 2 % Cursor line's width + + % Marker styles + + TopMarker@char = 'v' % Top (right) edge marker shape + BottomMarker@char = '^' % Top (right) edge marker shape + TargetMarkerStyle@char = 'square' % Target's marker style + TargetMarkerSize@double= 8 % Target's marker size + TargetMarkerEdgeColor = [0 0 0] % Target's marker outline color + TargetMarkerFaceColor = 'none' % Target's marker fill color + end + % -------------------------------------- + properties (SetAccess=protected, SetObservable) + ButtonDownFcn % Mouse-click callback + end + % -------------------------------------- + properties (SetAccess=immutable) + Type = 'Cursorbar' % Type of graphics object + end + + % ============================================================= % + + %% Enumeration Properties + + properties (Constant) + CursorbarShowText = {'on','off'} % Permitted Cursorbar ShowText options + CursorbarOrientation = {'vertical','horizontal'} % Permitted Cursorbar Orientation options + CursorbarTargetIntersections = {'multiple','single'} % Permitted Cursorbar TargetIntersections options + CursorbarTextDescription = {'short','long'} % Permitted Cursorbar TextDescription options + + % Classes of permitted targets + PermittedChartTargets = { + 'matlab.graphics.chart.primitive.Line' + 'matlab.graphics.chart.primitive.Surface' + 'matlab.graphics.chart.primitive.Area' + 'matlab.graphics.chart.primitive.Bar' + 'matlab.graphics.chart.primitive.Contour' + 'matlab.graphics.chart.primitive.Histogram' + 'matlab.graphics.chart.primitive.Scatter' + 'matlab.graphics.chart.primitive.Stair' + 'matlab.graphics.chart.primitive.Stem' + 'matlab.graphics.primitive.Image' + 'matlab.graphics.primitive.Line' + 'matlab.graphics.primitive.Patch' + 'matlab.graphics.primitive.Surface' + } + end + % -------------------------------------- + properties (SetObservable) + ShowText@char = 'on' % Showing the Cursorbar Text {'on','off'} + Orientation@char = 'vertical' % Orientation of Cursorbar {'vertical','horizontal'} + Visible@char = 'on' % Visibility of Cursorbar {'on','off'} + TargetIntersections@char = 'multiple' % How many intersections are plotted {'multiple','single'} + TextDescription@char = 'short' % Type of text description {'short','long'} + end + + % ============================================================= % + + %% Hidden Properties + + properties (Hidden) + TargetXData@double % XData of Target + TargetYData@double % YData of Target + TargetZData@double % ZData of Target + TargetNData@double % NData of Target (which Target number out of several) + + CursorLineHandle@handle % Line object used to represent the cursor bar + TargetMarkerHandle@handle % Line objects used to represent the intersection points with the Target + end + % -------------------------------------- + properties (Hidden, SetAccess=protected) + DataCursorDummyTargetHandle@handle % Line object placeholder for the DataCursor + + SelfListenerHandles@handle % Self listeners + TargetListenerHandles@handle % Store listeners for Target + ExternalListenerHandles@handle % Store other external listeners + + PeerHandle@graphics.Cursorbar % Handle to another Cursorbar object + Container@graphics.internal.CursorbarContainer % Handle to the Cursorbar's container + end + % -------------------------------------- + properties (Hidden, GetAccess=public, SetAccess=immutable) + GroupHandle % The group containing all the objects + end + properties (GetAccess=protected, SetAccess=immutable) + ObjectBeingCreated = true % is the object being created + end + % -------------------------------------- + properties (Hidden, Constant) + % Classes of permitted 2D targets + Permitted2DTargets = { + 'matlab.graphics.chart.primitive.Surface' + 'matlab.graphics.chart.primitive.Area' + 'matlab.graphics.chart.primitive.Contour' + 'matlab.graphics.primitive.Image' + 'matlab.graphics.primitive.Patch' + 'matlab.graphics.primitive.Surface' + } + end + + % ============================================================= % + + %% Events + + events + BeginDrag % Notifies listeners that the dragging of the Cursorbar has begun. + EndDrag % Notifies listeners that the dragging of the Cursorbar has ended. + UpdateCursorBar % Notifies listeners that the Cursorbar has been updated. + end + + % ============================================================= % + + %% Public methods + + % constructor + methods + function hThis = Cursorbar(hTarget,varargin) + % CURSORBAR A Cursorbar constructor + % + % See also: Cursorbar. + + % Check MATLAB Graphics system version + if verLessThan('matlab','8.4.0') + error('graphics:Cursorbar:Cursorbar:oldVersion', ... + 'Cursorbar requires the new MATLAB graphics system that was introduced in R2014b.'); + end + + % input error check + narginchk(1,Inf); + + % validate correct property-value pair arguments + assert( mod(length(varargin),2)==0 && iscellstr(varargin(1:2:end)), ... + 'graphics:Cursorbar:BadParamValuePairs', ... + 'Invalid parameter/value pair arguments.') + + % Initialize Cursorbar + + % force hTarget to column vector of handles + hTarget = handle(hTarget(:)); + + % get Cursorbar Parent and Target + % don't set yet: this is to prevent creation of an empty + % figure when its HandleVisibility is off. + if numel(hTarget) == 1 + if all(hThis.isTargetChart(hTarget)) + hParent = handle(ancestor(hTarget,'axes')); + elseif isa(hTarget,'matlab.graphics.axis.Axes') + hParent = handle(hTarget); + else + % delete Cursorbar and error if Target isn't a line or axes + delete(hThis); + error(message('MATLAB:cursorbar:InvalidTarget')); + end + else + if all(hThis.isTargetChart(hTarget)) + hParent = handle(ancestor(hTarget(1),'axes')); + else + % delete Cursorbar if Target isn't a line or axes + delete(hThis); + error(message('MATLAB:cursorbar:InvalidTarget')); + end + end + + % set the parent & target property + set(hThis,'Parent',hParent,'Target',hTarget); + + % set GroupHandle + hThis.GroupHandle = hggroup('Parent',hParent); + hThis.GroupHandle.Visible = 'on'; + hThis.GroupHandle.PickableParts = 'visible'; + hThis.GroupHandle.HandleVisibility = 'off'; + hThis.GroupHandle.Tag = 'CursorbarGroup'; + hThis.GroupHandle.DisplayName = 'Cursorbar'; + hThis.GroupHandle.DeleteFcn = @(~,~)delete(hThis); + hThis.GroupHandle.Serializable = 'off'; % assert that none of the child handles is saved + + % add self property listeners + localAddSelfListeners(hThis); + + % add listeners for the target and its ancestors + localAddTargetListeners(hThis); + + % create Cursorbar and marker line + hLines = localCreateNewCursorBarLines(hThis); + set(hLines,'Parent',hThis.GroupHandle) + + % create context menu + hCtxtMenu = localCreateUIContextMenu(hThis); + set(hThis, 'UIContextMenu',hCtxtMenu) + set(hLines,'UIContextMenu',hCtxtMenu) + + % set up the cursorbar containers for saving and loading + localAddContainer(hThis,hParent); + + % set Position and Visible later, if they are specified as inputs + visiblepropval = ''; + positionpropval = []; + locationpropval = []; + orientationpropval = ''; + + % Loop through and set specified properties + if nargin>1 + for n = 1:2:length(varargin) + propname = varargin{n}; + propval = varargin{n+1}; + % + switch lower(propname) + case 'visible' + % Set the visible property at the end of this constructor + % since the visible listener requires the DataTip to + % be fully initialized. + visiblepropval = validatestring(propval,{'on','off'}); + case 'position' + % set the Position property just before setting Visible property + % force to a row vector + if numel(propval) > 3 || numel(propval) < 2 || ~isnumeric(propval) || ~all(isfinite(propval)) + error(message('MATLAB:graphics:cursorbar:invalidPosition')) + end + positionpropval = propval(:).'; + case 'location' + locationpropval = propval; + case 'orientation' + orientationpropval = validatestring(propval,hThis.CursorbarOrientation); + otherwise + set(hThis,propname,propval); + end + end + end + + % store vectors of Targets' XData and YData, sorted by Orientation + [x,y,z,n] = getTargetXYData(hThis,orientationpropval); + hThis.TargetXData = x; + hThis.TargetYData = y; + hThis.TargetZData = z; + hThis.TargetNData = n; + + % create new DataCursor + createNewDataCursor(hThis); + + % set Position + if ~isempty(positionpropval) + pos = positionpropval; + pos(3) = 0; % ensure 1-by-3 vector + % check Location + if ~isempty(locationpropval) + switch lower(orientationpropval) + case 'vertical', pos(1) = locationpropval; + case 'horizontal', pos(2) = locationpropval; + otherwise, pos(1) = locationpropval; % default vertical + end + end + % set Position for DataCursor from input + if isTargetAxes(hThis) + % if the Target is an axes, use the Position directly + set(hThis.DataCursorHandle.DataSource,'XData',pos(1),'YData',pos(2)); + else + % not an axes + [x,y] = closestvertex(hThis,pos,orientationpropval); + pos = [x y 0]; + hThis.DataCursorHandle.Position = pos; + end + else % Position not set + % set default Position + hAxes = get(hThis,'Parent'); + xLim = get(hAxes,'XLim'); + yLim = get(hAxes,'YLim'); + pos = [mean(xLim) mean(yLim) 0]; + % check Location + if ~isempty(locationpropval) + switch lower(orientationpropval) + case 'vertical', pos(1) = locationpropval; + case 'horizontal', pos(2) = locationpropval; + otherwise, pos(1) = locationpropval; % default vertical + end + end + % set Position for DataCursor + if isTargetAxes(hThis) + % set the DataCursor's Position to the middle of the axes + % use the 'pos' we already have + set(hThis.DataCursorHandle.DataSource,'XData',pos(1),'YData',pos(2)); + else + % choose the closest vertex to 'pos' + [x,y] = closestvertex(hThis,pos,orientationpropval); + pos = [x y 0]; + hThis.DataCursorHandle.Position = pos; + end + end + + % set Orientation + if ~isempty(orientationpropval) + set(hThis,'Orientation',orientationpropval); + end + + % set Position and Location + % set.Position silently sets Location + hThis.Position = pos; + + % Set the visible property if it was passed into the constructor + if ~isempty(visiblepropval) + set(hThis,'Visible',visiblepropval) + end + + % update + % release ObjectBeingCreated constraint + hThis.ObjectBeingCreated = false; + % update Cursorbar + update(hThis,[],[],'-nomove'); + + % apply user's CreateFcn + hThis.localApplyCreateFcn(hThis,[]); + end + end + + % ---------------------------------------- + + %% Set Methods + + methods + function s = setdisp(hThis) + % SETDISP Customize set method display. + s = set(hThis); + + % update + s.ShowText = graphics.Cursorbar.CursorbarShowText; + s.Orientation = graphics.Cursorbar.CursorbarOrientation; + s.TargetIntersections = graphics.Cursorbar.CursorbarTargetIntersections; + s.TextDescription = graphics.Cursorbar.CursorbarTextDescription; + % + s.CursorLineStyle = {'-','--',':','-.','none'}; + s.TopMarker = {'+','o','*','.','x','square','diamond','v','^','>','<','pentagram','hexagram','none'}; + s.BottomMarker = {'+','o','*','.','x','square','diamond','v','^','>','<','pentagram','hexagram','none'}; + s.TargetMarkerStyle = {'+','o','*','.','x','square','diamond','v','^','>','<','pentagram','hexagram','none'}; + s.TargetMarkerEdgeColor = {'none','flat','auto'}; + s.TargetMarkerFaceColor = {'none','flat','auto'}; + % + s.BusyAction = {'queue','cancel'}; + s.HandleVisibility = {'on','callback','off'}; + s.Interruptible = {'on','off'}; + s.HitTest = {'on','off'}; + s.Visible = {'on','off'}; + s.Selected = {'on','off'}; + s.SelectionHighlight = {'on','off'}; + s.PickableParts = {'visible','none','all'}; + + % show + if nargout==0 + disp(s); + end + end + % ---------------------------------------- + function set.ShowText(hThis,show) + try + show = validatestring(show,hThis.CursorbarShowText); + catch ME, + throwAsCaller(setmessage(ME,'ShowText')); + end + hThis.ShowText = show; + end + % ---------------------------------------- + function set.Orientation(hThis,orient) + try + orient = validatestring(orient,hThis.CursorbarOrientation); + catch ME, + throwAsCaller(setmessage(ME,'Orientation')); + end + hThis.Orientation = orient; + end + % ---------------------------------------- + function set.Visible(hThis,vis) + try + vis = validatestring(vis,{'on','off'}); + catch ME, + throwAsCaller(setmessage(ME,'Visible')); + end + hThis.Visible = vis; + end + % ---------------------------------------- + function set.TargetIntersections(hThis,tin) + try + tin = validatestring(tin,hThis.CursorbarTargetIntersections); + catch ME, + throwAsCaller(setmessage(ME,'TargetIntersections')); + end + hThis.TargetIntersections = tin; + end + % ---------------------------------------- + function set.TextDescription(hThis,des) + try + des = validatestring(des,hThis.CursorbarTextDescription); + catch ME, + throwAsCaller(setmessage(ME,'TextDescription')); + end + hThis.TextDescription = des; + end + % ---------------------------------------- + function set.Location(hThis,loc) + try + validateattributes(loc,{'double'},{'scalar','real','finite'}); + catch ME, + throwAsCaller(setmessage(ME,'Location')); + end + hThis.Location = loc; + end + % ---------------------------------------- + function set.Position(hThis,pos) + try + if numel(pos)==2, pos(3)=0; end % ensure a 3 element vector + validateattributes(pos,{'double'},{'row','numel',3,'real','finite'}); + catch ME, + throwAsCaller(setmessage(ME,'Position')); + end + hThis.Position = pos; + end + % ---------------------------------------- + function set.CreateFcn(hThis,fcn) + if ischar(fcn) || isa(fcn,'function_handle') ... + || ( iscell(fcn) && (ischar(fcn{1}) || isa(fcn{1},'function_handle')) ) + hThis.CreateFcn = fcn; + else + ME = MException('MATLAB:datatypes:callback:CreateCallback', ... + 'Callback value must be a string, a function handle, or a cell array containing string or function handle'); + throwAsCaller(setmessage(ME,'CreateFcn')); + end + end + % ---------------------------------------- + function set.DeleteFcn(hThis,fcn) + if ischar(fcn) || isa(fcn,'function_handle') ... + || ( iscell(fcn) && (ischar(fcn{1}) || isa(fcn{1},'function_handle')) ) + hThis.DeleteFcn = fcn; + else + ME = MException('MATLAB:datatypes:callback:DeleteCallback', ... + 'Callback value must be a string, a function handle, or a cell array containing string or function handle'); + throwAsCaller(setmessage(ME,'DeleteFcn')); + end + end + % ---------------------------------------- + function set.UpdateFcn(hThis,fcn) + if ischar(fcn) || isa(fcn,'function_handle') ... + || ( iscell(fcn) && (ischar(fcn{1}) || isa(fcn{1},'function_handle')) ) + hThis.UpdateFcn = fcn; + else + ME = MException('MATLAB:datatypes:callback:UpdateCallback', ... + 'Callback value must be a string, a function handle, or a cell array containing string or function handle'); + throwAsCaller(setmessage(ME,'UpdateFcn')); + end + end + end + + % ============================================================= % + + %% Dependent Methods + + methods + function set.Annotation(hThis,val) + try + hThis.GroupHandle.Annotation = val; + catch ME, + throwAsCaller(setmessage(ME,'Annotation')); + end + end + function val = get.Annotation(hThis) + val = hThis.GroupHandle.Annotation; + end + % ---------------------------------------- + function set.DisplayName(hThis,val) + try + hThis.GroupHandle.DisplayName = val; + catch ME, + throwAsCaller(setmessage(ME,'DisplayName')); + end + end + function val = get.DisplayName(hThis) + val = hThis.GroupHandle.DisplayName; + end + % ---------------------------------------- + function set.Children(~,~) + ME = MException('MATLAB:class:SetProhibited','You cannot set the read-only property ''Children'' of Class.'); + throwAsCaller(setmessage(ME,'Children')); + end + function val = get.Children(hThis) + val = hThis.GroupHandle.Children; + end + % ---------------------------------------- + function set.HandleVisibility(hThis,val) + try + hThis.GroupHandle.HandleVisibility = val; + catch ME, + throwAsCaller(setmessage(ME,'HandleVisibility')); + end + end + function val = get.HandleVisibility(hThis) + val = hThis.GroupHandle.HandleVisibility; + end + % ---------------------------------------- + function set.Selected(hThis,val) + try + hThis.GroupHandle.Selected = val; + catch ME, + throwAsCaller(setmessage(ME,'Selected')); + end + end + function val = get.Selected(hThis) + val = hThis.GroupHandle.Selected; + end + % ---------------------------------------- + function set.SelectionHighlight(hThis,val) + try + hThis.GroupHandle.SelectionHighlight = val; + catch ME, + throwAsCaller(setmessage(ME,'SelectionHighlight')); + end + end + function val = get.SelectionHighlight(hThis) + val = hThis.GroupHandle.SelectionHighlight; + end + % ---------------------------------------- + function set.PickableParts(~,~) + ME = MException('MATLAB:class:SetProhibited','You cannot set the read-only property ''PickableParts'' of Class.'); + throwAsCaller(setmessage(ME,'PickableParts')); + end + function val = get.PickableParts(hThis) + val = hThis.GroupHandle.PickableParts; + end + % ---------------------------------------- + function set.HitTest(hThis,val) + try + hThis.GroupHandle.HitTest = val; + catch ME, + throwAsCaller(setmessage(ME,'HitTest')); + end + end + function val = get.HitTest(hThis) + val = hThis.GroupHandle.HitTest; + end + % ---------------------------------------- + function set.Interruptible(hThis,val) + try + hThis.GroupHandle.Interruptible = val; + catch ME, + throwAsCaller(setmessage(ME,'Interruptible')); + end + end + function val = get.Interruptible(hThis) + val = hThis.GroupHandle.Interruptible; + end + % ---------------------------------------- + function set.BusyAction(hThis,val) + try + hThis.GroupHandle.BusyAction = val; + catch ME, + throwAsCaller(setmessage(ME,'BusyAction')); + end + end + function val = get.BusyAction(hThis) + val = hThis.GroupHandle.BusyAction; + end + % ---------------------------------------- + function set.BeingDeleted(hThis,val) + try + hThis.GroupHandle.BeingDeleted = val; + catch ME, + throwAsCaller(setmessage(ME,'BeingDeleted')); + end + end + function val = get.BeingDeleted(hThis) + val = hThis.GroupHandle.BeingDeleted; + end + end + + % ============================================================= % + + %% Sealed Methods + + methods (Sealed) + function tf = ishandle(hThis) + % ISHANDLE Checks on self if valid handle + % + % See also ishandle, graphics.Cursorbar. + tf = isvalid(hThis); + end + end + + % ============================================================= % + + %% Local (Protected Hidden) Methods + + methods (Access=protected, Hidden) + + function localApplyCreateFcn(hThis,obj,evd) + % LOCALAPPLYCREATEFCN Apply the create function. + localApplyCallbackFcn(hThis,obj,evd,'CreateFcn'); + end + + % -------------------------------------- + function localApplyDeleteFcn(hThis,obj,evd) + % LOCALAPPLYDELETEFCN Apply the delete function. + localApplyCallbackFcn(hThis,obj,evd,'DeleteFcn'); + end + + % -------------------------------------- + function localApplyUpdateFcn(hThis,obj,evd) + % LOCALAPPLYDELETEFCN Apply the delete function. + localApplyCallbackFcn(hThis,obj,evd,'UpdateFcn'); + end + + % -------------------------------------- + function localApplyCallbackFcn(hThis,obj,evd,callbackname) + % LOCALAPPLYCALLBACKFCN Apply some callback function. + func = hThis.(callbackname); + try % to apply delete function + switch class(func) + case 'char', eval(func); + case 'function_handle', feval(func,obj,evd); + case 'cell', feval(hThis.func{1},obj,evd,hThis.func{2:end}); + end + catch ME, % warn quietly + wME = setmessage(ME,callbackname); + warning(wME.identifier, wME.message); + end + end + + % -------------------------------------- + function hLines = localCreateNewCursorBarLines(hThis,~,~) + % LOCALCREATENEWCURSORBARLINES create lines for Cursorbar, and line for markers + + % Get axes and figure + hAxes = get(hThis,'Parent'); + hGroup = hThis.GroupHandle; + + % white line on dark axes, black line on light axes + AXCOLOR = get(hAxes,'Color'); + + % --------- cursor line --------- + lineprops = struct; + lineprops.Tag = 'DataCursorLine'; + lineprops.Parent = hGroup; + lineprops.XData = [NaN NaN]; + lineprops.YData = [NaN NaN]; + lineprops.Color = hThis.CursorLineColor; + % + % light colored axes + if sum(AXCOLOR) < 1.5 + lineprops.Color = [1 1 1]; + end + % + lineprops.Marker = 'none'; + lineprops.LineStyle = '-'; + lineprops.LineWidth = 2; + % + lineprops.Clipping = 'on'; + lineprops.XLimInclude = 'off'; % don't interfere with axes zooming + lineprops.YLimInclude = 'off'; % don't interfere with axes zooming + % + lineprops.HandleVisibility = 'off'; + lineprops.Visible = hThis.Visible; + lineprops.ButtonDownFcn = @hThis.localCursorButtonDownFcn; + lineprops.Serializable = 'off'; % don't save to file + + cursorline = line(lineprops); + hThis.CursorLineHandle = handle(cursorline); + hThis.ButtonDownFcn = lineprops.ButtonDownFcn; + + % --------- top,bottom affordances --------- + lineprops.XData = NaN; + lineprops.YData = NaN; + lineprops.MarkerFaceColor = hThis.CursorLineColor; + lineprops.LineStyle = 'none'; + % + % top + lineprops.Tag = 'DataCursorLineTop'; + lineprops.Marker = hThis.TopMarker; + % + topdragline = line(lineprops); + hThis.TopHandle = handle(topdragline); + % + % bottom + lineprops.Tag = 'DataCursorLineBottom'; + lineprops.Marker = hThis.BottomMarker; + % + bottomdragline = line(lineprops); + hThis.BottomHandle = handle(bottomdragline); + + % --------- marker line --------- + lineprops.Tag = 'DataCursorTargetMarker'; + lineprops.Marker = hThis.TargetMarkerStyle; + lineprops.MarkerSize = hThis.TargetMarkerSize; + lineprops.MarkerEdgeColor = hThis.TargetMarkerEdgeColor; + lineprops.MarkerFaceColor = hThis.TargetMarkerFaceColor; + lineprops.LineStyle = 'none'; + % + markerline = line(lineprops); + hThis.TargetMarkerHandle = handle(markerline); + + % combine handles + hLines = handle([ ... + cursorline; + topdragline; + bottomdragline; + markerline ]); + end + + % -------------------------------------- + function hCtxtMenu = localCreateUIContextMenu(hThis,~,~) + % LOCALCREATEUICONTEXTMENU + + if ismethod(hThis,'createUIContextMenu') + hCtxtMenu = hThis.createUIContextMenu(); + else + hCtxtMenu = hThis.defaultUIContextMenu(); + end + end + + % -------------------------------------- + function localAddTargetListeners(hThis,~,~) + % LOCALADDTARGETLISTENERS add listeners for Target and its parent axes + + % check Target + hTarget = hThis.Target; + if ~ishandle(hTarget) + return; + end + + % get handles for axes + hAxes = handle(get(hThis,'Parent')); + + % listen for changes to axes' Limits + axesLimProps = [ ... + findprop(hAxes,'XLim'); + findprop(hAxes,'YLim'); + findprop(hAxes,'ZLim')]; + l = event.proplistener(hAxes,axesLimProps,'PostSet',@hThis.localAxesLimUpdate); + + % Update if Target is line(s) and any target ...Data property changes + if ~isTargetAxes(hThis) + for n = 1:length(hTarget) + target_prop = [ ... + findprop(hTarget(n),'XData'); + findprop(hTarget(n),'YData'); + findprop(hTarget(n),'ZData')]; + l(end+1) = event.proplistener(hTarget(n),target_prop,'PostSet',... + @hThis.localTargetDataUpdate); %#ok + end + end + + % Listen to axes pixel bound resize events + axes_prop = findprop(hAxes,'PixelBound'); + l(end+1) = event.proplistener(hAxes,axes_prop, 'PostSet',... + @hThis.localAxesPixelBoundUpdate); + + % Clean up if Cursorbar or its Target is deleted + l(end+1) = event.listener(hThis.Target,'ObjectBeingDestroyed',... + @hThis.localTargetDestroy); + + % Store listeners + hThis.TargetListenerHandles = l; + end + + % -------------------------------------- + function localAddSelfListeners(hThis,~,~) + % LOCALADDSELFLISTENERS add listeners to Cursorbar's properties + + % Visible + l( 1 ) = event.proplistener(hThis,findprop(hThis,'Visible'),... + 'PostSet',@hThis.localSetVisible); + + % ShowText + l(end+1) = event.proplistener(hThis,findprop(hThis,'ShowText'),... + 'PostSet',@hThis.localSetShowText); + + % TargetIntersections + l(end+1) = event.proplistener(hThis,findprop(hThis,'TargetIntersections'),... + 'PostSet',@hThis.localSetTargetIntersections); + + % TextDescription + l(end+1) = event.proplistener(hThis,findprop(hThis,'TextDescription'),... + 'PostSet',@hThis.localSetTextDescription); + + % Orientation + l(end+1) = event.proplistener(hThis,findprop(hThis,'Orientation'),... + 'PostSet',@hThis.localSetOrientation); + + % Location + l(end+1) = event.proplistener(hThis,findprop(hThis,'Location'),... + 'PostSet',@hThis.localSetLocation); + + % Position + l(end+1) = event.proplistener(hThis,findprop(hThis,'Position'),... + 'PostSet',@hThis.localSetPosition); + + % UIContextMenu + l(end+1) = event.proplistener(hThis,findprop(hThis,'UIContextMenu'),... + 'PostSet',@hThis.localSetUIContextMenu); + + % ButtonDownFcn + l(end+1) = event.proplistener(hThis,findprop(hThis,'ButtonDownFcn'),... + 'PostSet', @hThis.localSetButtonDownFcn); + + % Target + l(end+1) = event.proplistener(hThis,findprop(hThis,'Target'),... + 'PreSet', @hThis.localPreSetTarget); + l(end+1) = event.proplistener(hThis,findprop(hThis,'Target'),... + 'PostSet', @hThis.localPostSetTarget); + l(end+1) = event.proplistener(hThis,findprop(hThis,'Target'),... + 'PostSet', @hThis.localAddTargetListeners); + + % Cursorbar appearance properties + p = [ ... + findprop(hThis,'CursorLineColor'); + findprop(hThis,'CursorLineStyle'); + findprop(hThis,'CursorLineWidth'); + findprop(hThis,'TopMarker'); + findprop(hThis,'BottomMarker')]; + l(end+1) = event.proplistener(hThis,p,'PostSet', @hThis.localSetCursorProps); + + % Marker properties + p = [ ... + findprop(hThis,'TargetMarkerStyle');... + findprop(hThis,'TargetMarkerSize'); ... + findprop(hThis,'TargetMarkerEdgeColor'); ... % YD + findprop(hThis,'TargetMarkerFaceColor'); ... % YD + ]; + l(end+1) = event.proplistener(hThis,p,'PostSet',@hThis.localSetMarkerProps); + + % Listen for update event + l(end+1) = event.listener(hThis,'UpdateCursorBar',@hThis.updateDisplay); + + % Clean up if Cursorbar is deleted + l(end+1) = event.listener(hThis,'ObjectBeingDestroyed',... + @hThis.localCursorBarDestroy); + + % Store listeners + hThis.SelfListenerHandles = l; + + end + + % -------------------------------------- + function localAxesPixelBoundUpdate(hThis,~,~) + % LOCALAXESPIXELBOUNDUPDATE + + update(hThis); + end + + % -------------------------------------- + function localSetOrientation(hThis,~,evd) + % LOCALSETORIENTATION + + % get new Orientation value + newval = evd.AffectedObject.Orientation; + + % get DataCursor's Position + pos = hThis.DataCursorHandle.Position; + x = pos(1); + y = pos(2); + + hAxes = get(hThis,'Parent'); + + % get axes' limits + xlimits = get(hAxes,'XLim'); + ylimits = get(hAxes,'YLim'); + + % get axes' directions + xdir = get(hAxes,'XDir'); + ydir = get(hAxes,'YDir'); + + % setting Marker for 'affordances' at ends of Cursorbar + switch newval + case 'vertical' + set(hThis.CursorLineHandle,'XData',[x x],'YData',ylimits); + switch ydir + case 'normal' + set(hThis.BottomHandle,'Marker','^') + set(hThis.TopHandle,'Marker','v') + case 'reverse' + set(hThis.BottomHandle,'Marker','v') + set(hThis.TopHandle,'Marker','^') + end + case 'horizontal' + set(hThis.CursorLineHandle,'XData',xlimits,'YData',[y y]); + switch xdir + case 'normal' + set(hThis.BottomHandle,'Marker','<') + set(hThis.TopHandle,'Marker','>') + case 'reverse' + set(hThis.BottomHandle,'Marker','>') + set(hThis.TopHandle,'Marker','<') + end + otherwise + error(message('MATLAB:graphics:cursorbar:invalidOrientation')) + end + + % update Cursorbar + if ~isempty(hThis.Position) + hThis.Position = hThis.Position; % silently update Location and Position + end + % update(hThis) + + end + + % -------------------------------------- + function localSetLocation(hThis,~,evd) + % LOCALSETLOCATION + + loc = evd.AffectedObject.Location; + + pos = get(hThis,'Position'); + + % during initialization (duplication) the position may not be set yet; + % assert proper length (=3) + if length(pos)<3 + pos(1,3) = 0; + end + + switch get(hThis,'Orientation') + case 'vertical' + pos(1) = loc; + case 'horizontal' + pos(2) = loc; + otherwise % default vertical + pos(1) = loc; + end + + % set(hThis.DataCursorHandle,'Position',pos) + set(hThis,'Position',pos) + + % update(hThis); % set.Position already updates Cursorbar + end + + % -------------------------------------- + function localSetPosition(hThis,~,evd) + % LOCALSETPOSITION + + % return early if not a handle + if ~ishandle(hThis) + return; + end + + % get new Position + pos = evd.AffectedObject.Position; + + % Position should be [X Y] or [X Y Z] + if numel(pos) ~= 2 && numel(pos) ~= 3 + return + end + + x = pos(1); + y = pos(2); + + hCursorLine = hThis.CursorLineHandle; + hTopLine = hThis.TopHandle; + hBottomLine = hThis.BottomHandle; + hAxes = get(hThis,'Parent'); + + switch get(hThis,'Orientation') + case 'vertical' + if isempty(hThis.Location) || hThis.Location ~= x + set(hThis,'Location',x); + end + + yLim = get(hAxes,'YLim'); + set(hCursorLine,'XData',[x x],'YData',yLim); + set(hBottomLine,'XData',x, 'YData',yLim(1)); + set(hTopLine, 'XData',x, 'YData',yLim(2)); + case 'horizontal' + if isempty(hThis.Location) || hThis.Location ~= y + set(hThis,'Location',y); + end + xLim = get(hAxes,'XLim'); + set(hCursorLine,'XData',xLim, 'YData',[y y]); + set(hBottomLine,'XData',xLim(2),'YData',y); + set(hTopLine, 'XData',xLim(1),'YData',y); + end + + % silently update + updateMarkers(hThis); + updateDisplay(hThis); + % defaultUpdateFcn(hThis,obj,evd); + + end + + % -------------------------------------- + function localSetShowText(hThis,obj,evd) + % LOCALSETSHOWTEXT + + validhandles = ishandle(hThis.DisplayHandle); + visibility = evd.AffectedObject.ShowText; + set(hThis.DisplayHandle(validhandles),'Visible',visibility); + % + hThis.updateDisplay(obj,evd); % update display + end + + % -------------------------------------- + function localSetTargetIntersections(hThis,obj,evd) + % LOCALSETTARGETINTERSECTION + + hThis.updateMarkers(); % update markers + hThis.updateDisplay(obj,evd); % update display + end + + % -------------------------------------- + function localSetTextDescription(hThis,obj,evd) + % LOCALSETTEXTDESCRIPTION + + hThis.updateMarkers(); % update markers + hThis.updateDisplay(obj,evd); % update display + end + + % -------------------------------------- + function localSetUIContextMenu(hThis,~,evd) + % LOCALSETUICONTEXTMENU + + contextmenu = evd.AffectedObject.UIContextMenu; + + hndls = [ + hThis.CursorLineHandle; + hThis.TargetMarkerHandle; + hThis.TopHandle; + hThis.BottomHandle; + hThis.GroupHandle]; + + set(hndls,'UIContextMenu',contextmenu); + end + + % -------------------------------------- + function localSetButtonDownFcn(hThis,~,evd) + % LOCALSETBUTTONDOWNFCN + + newVal = evd.AffectedObject.ButtonDownFcn; + + hLines = [ + hThis.CursorLineHandle; + hThis.TargetMarkerHandle; + hThis.TopHandle + hThis.BottomHandle + hThis.GroupHandle]; + + set(hLines,'ButtonDownFcn',newVal); + end + + % -------------------------------------- + function localSetCursorProps(hThis,~,evd) + % LOCALSETCURSORPROPS + + propname = evd.Source.Name; + propval = evd.AffectedObject.(propname); + + switch propname + case 'CursorLineColor' + newpropname = 'Color'; + hLine = [hThis.CursorLineHandle; hThis.TopHandle; hThis.BottomHandle]; + case 'CursorLineStyle' + newpropname = 'LineStyle'; + hLine = hThis.CursorLineHandle; + case 'CursorLineWidth' + newpropname = 'LineWidth'; + hLine = hThis.CursorLineHandle; + case 'TopMarker' + newpropname = 'Marker'; + hLine = hThis.TopHandle; + case 'BottomMarker' + newpropname = 'Marker'; + hLine = hThis.BottomHandle; + end + + set(hLine,newpropname,propval); + end + + % -------------------------------------- + function localSetMarkerProps(hThis,~,evd) + % LOCALSETMARKERPROPS + + propname = evd.Source.Name; + propval = evd.AffectedObject.(propname); + + switch propname + case 'TargetMarkerStyle' + newpropname = 'Marker'; + case 'TargetMarkerSize' + newpropname = 'MarkerSize'; + case 'TargetMarkerEdgeColor' % YD + newpropname = 'MarkerEdgeColor'; + case 'TargetMarkerFaceColor' % YD + newpropname = 'MarkerFaceColor'; + end + + set(hThis.TargetMarkerHandle,newpropname,propval) + end + + % -------------------------------------- + function localPreSetTarget(hThis,~,evd) + % LOCALPRESETTARGET + + % check new Target value + newTarget = evd.AffectedObject.Target; + if ~all(isTargetChart(hThis)) && ~isa(newTarget,'matlab.graphics.axis.Axes') + error(message('MATLAB:cursorbar:InvalidTarget')); + end + + % remove the old container + localRemoveContainer(hThis); + end + + % -------------------------------------- + function localPostSetTarget(hThis,~,~) + % LOCALPOSTSETTARGET + + % set up the container + localAddContainer(hThis); + + % if it's a line, set it close to the current location of the Cursorbar + if isTargetAxes(hThis) + % do nothing for axes, no need to change Position + return + end + + % update the Target...Data + [x,y,z,n] = getTargetXYData(hThis); + hThis.TargetXData = x; + hThis.TargetYData = y; + hThis.TargetZData = z; + hThis.TargetNData = n; + + % update Cursorbar + hThis.update([],[],'-nomove'); + end + + % -------------------------------------- + function localSetVisible(hThis,obj,evd) + % LOCALSETVISIBLE + + % Return early if no DataCursor + if ~isvalid(hThis.DataCursorHandle) || isempty(hThis.DataCursorHandle.Position) + hThis.Visible = 'off'; + hThis.GroupHandle.Visible = 'off'; + hThis.updateDisplay(obj,evd); + return; + end + + newvalue = evd.AffectedObject.Visible; + hThis.GroupHandle.Visible = newvalue; + hThis.updateDisplay(obj,evd); + end + + % -------------------------------------- + function localAddContainer(hThis,hParent) + % LOCALADDCONTAINER Add a CursorbarContainer to the parent + + % inputs + if nargin<2 + hParent = hThis.Parent; % default parent + end + hFig = ancestor(hParent,'figure'); % figure handle + + % store the application data in the parent axes for serialization reasons + key = graphics.internal.CursorbarContainer.Key; % application data key + containers = getappdata(hFig,key); % retrieve Cursorbar containers + % + if isempty(containers) || ~any(containers.hasCursorbar(hThis)) + % create a new container and store + newContainer = graphics.internal.CursorbarContainer(hThis);% container of the current object + containers = [containers newContainer]; % add the current container + % + setappdata(hFig,key,containers); % store all the containers in the parent + hThis.Container = newContainer; % store the new container + end + end + + % -------------------------------------- + function localRemoveContainer(hThis,hParent) + % LOCALREMOVECONTAINER Remove the CursorbarContainer from the parent + + % inputs + if nargin<2 + hParent = hThis.Parent; % default parent + end + hFig = ancestor(hParent,'figure'); % figure handle + + % remove the application data in the parent axes + key = graphics.internal.CursorbarContainer.Key; % application data key + containers = getappdata(hFig,key); % retrieve Cursorbar containers + % + if ~isempty(containers) && any(containers.hasCursorbar(hThis)) + % remove containers from the application data + current = containers.hasCursorbar(hThis); % containers for the current object + setappdata(hFig,key,containers(~current)); % leave only the non-current containers + end + + % delete the old container handle + if isvalid(hThis.Container) + delete(hThis.Container); + end + end + + % -------------------------------------- + function localCursorBarDestroy(hThis,~,~,varargin) + % LOCALCURSORBARDESTROY called when the Cursorbar is destroyed + + % user defined delete function + hThis.localApplyDeleteFcn(hThis,[]); + + % remove cursorbar containers + if ishandle(hThis.Parent) + localRemoveContainer(hThis,hThis.Parent); + end + + % delete all child objects + if ishandle(hThis.CursorLineHandle) + delete(hThis.CursorLineHandle); + end + if ishandle(hThis.TargetMarkerHandle) + delete(hThis.TargetMarkerHandle); + end + if ishandle(hThis.TopHandle) + delete(hThis.TopHandle); + end + if ishandle(hThis.BottomHandle) + delete(hThis.BottomHandle); + end + if isvalid(hThis.DataCursorHandle) + delete(hThis.DataCursorHandle) + end + validhandles = ishandle(hThis.DisplayHandle); + if any(validhandles) && all(isa(hThis.DisplayHandle(validhandles),'matlab.graphics.primitive.Text')) + delete(hThis.DisplayHandle(validhandles)) + end + if ishandle(hThis.GroupHandle) + delete(hThis.GroupHandle) + end + end + + % -------------------------------------- + function localTargetDestroy(hThis,~,evd,varargin) + % LOCALTARGETDESTROY called when the any of the Cursorbar's Target objects are destroyed + + % if there is a single Target, then Cursorbar should be destroyed when it is + % destroyed + if length(hThis.Target) == 1 + delete(hThis); + return + else + % determine which Target was deleted + deletedTarget = evd.Source; + + % remove from Target list + hTargets = handle(hThis.Target); + hTargets(hTargets == deletedTarget) = []; + set(hThis,'Target',hTargets); + + % update the Target_Data + [x,y,z,n] = getTargetXYData(hThis); + hThis.TargetXData = x; + hThis.TargetYData = y; + hThis.TargetZData = z; + hThis.TargetNData = n; + end + + update(hThis,[],[],'-nomove'); + end + + % -------------------------------------- + function localAxesLimUpdate(hThis,~,~) + % LOCALAXESLIMUPDATE update cursor line after limits change + + % get the Cursorbar's orientation + orient = get(hThis,'Orientation'); + + hAxes = handle(get(hThis,'Parent')); + hCursorLine = get(hThis,'CursorLineHandle'); + + switch orient + case 'vertical' + ylim = get(hAxes,'YLim'); + set(hCursorLine,'YData',ylim) + case 'horizontal' + xlim = get(hAxes,'XLim'); + set(hCursorLine,'XData',xlim) + end + end + + % -------------------------------------- + function localTargetDataUpdate(hThis,~,~,varargin) + % LOCALTARGETDATAUPDATE + + hDataCursor = hThis.DataCursorHandle; + + oldpos = hDataCursor.Position; + + % use the old position to determine the new position + [x,y] = closestvertex(hThis,oldpos); + pos = [x y 0]; + hDataCursor.Position = pos; + update(hThis); + end + + % -------------------------------------- + function localCursorButtonDownFcn(hThis,~,~) + % LOCALCURSORBUTTONDOWNFCN click on Cursorbar + + hFig = ancestor(hThis,'Figure'); + + % swap out the WindowButton...Fcns + uistate = struct; + uistate.WindowButtonUpFcn = get(hFig,'WindowButtonUpFcn'); + uistate.WindowButtonMotionFcn = get(hFig,'WindowButtonMotionFcn'); + uistate.Pointer = get(hFig,'Pointer'); + + % save figure's current state + setappdata(hFig,'CursorBarOriginalFigureCallbacks',uistate); + + % modify uistate + uistate.WindowButtonUpFcn = @hThis.localWindowButtonUpFcn; + uistate.WindowButtonMotionFcn = @hThis.localWindowButtonMotionFcn; + uistate.Pointer = 'fleur'; + + % set new state + set(hFig,uistate); + + % send BeginDrag event + notify(hThis,'BeginDrag'); + end + + % -------------------------------------- + function localWindowButtonMotionFcn(hThis,~,~) + % LOCALWINDOWBUTTONMOTIONFCN move Cursorbar + + % update the Cursorbar while moving + update(hThis); + end + + % -------------------------------------- + function localWindowButtonUpFcn(hThis,hFig,~) + % LOCALWINDOWBUTTONUPFCN restore original figure callbacks and pointer + + % get stored callbacks + uistate = getappdata(hFig,'CursorBarOriginalFigureCallbacks'); + + if ~isempty(uistate) + set(hFig,uistate); + end + + % send EndDrag event + notify(hThis,'EndDrag'); + end + + % -------------------------------------- + function localTestUpdate(~,~,evd) + % LOCALTESTUPDATE test for property listeners + + disp(get(evd)) + + end + end + + % ============================================================= % + + %% Folder (Protected Hidden) Methods + methods (Access=protected, Hidden) + % -------------------------------------- + uictxtmenu = defaultUIContextMenu(hThis); + % -------------------------------------- + defaultUpdateFcn(hThis,obj,evd); + % -------------------------------------- + [xIntersect,yIntersect,hIntersect] = getIntersections(hThis,hLines); + % -------------------------------------- + pixperdata = getPixelsPerData(hThis); + % -------------------------------------- + [x,y,z,n] = getTargetXYData(hThis,orient); + % -------------------------------------- + move(hThis,dir); + % -------------------------------------- + moveDataCursor(hThis,hDataCursor,direc); + % -------------------------------------- + update(hThis,obj,evd,varargin) + % -------------------------------------- + updateDataCursor(hThis,hNewDataCursor,target) + % -------------------------------------- + updateDisplay(hThis,obj,evd) + % -------------------------------------- + updateMarkers(hThis) + % -------------------------------------- + updatePosition(hThis,hNewDataCursor) + % -------------------------------------- + hNewDataCursor = createNewDataCursor(hThis,hTarget) + % -------------------------------------- + [x,y,n] = closestvertex(hThis,pos,orient) + end + + % ============================================================= % + + %% Custom Display Methods + + methods(Access = protected) + + % -------------------------------------- + function groups = getScalarPropertyGroups(hThis) %#ok + % GETSCALARPROPERTYGROUPS Construct array of property groups for display of scalar case. + + % Scalar case: change order + propList = { ... + 'Location', ... + 'Position', ... + 'Orientation', ... + ... + 'CursorLineColor', ... + 'CursorLineStyle', ... + 'CursorLineWidth', ... + 'TopMarker', ... + 'BottomMarker', ... + ... + 'TargetMarkerStyle', ... + 'TargetMarkerSize', ... + 'TargetMarkerEdgeColor', ... + 'TargetMarkerFaceColor', ... + ... + 'ShowText', ... + 'TargetIntersections', ... + 'TextDescription' ... + }; + groups = matlab.mixin.util.PropertyGroup(propList); + end + end + + % ============================================================= % + +end + +% ============================================================= % + +%% Subfunctions + +function newME = setmessage(ME,prop) +% SETMESSAGE Sets the error message for set.Property functions. +classLink = sprintf('Cursorbar',mfilename('class')); +% +firstLine = sprintf('While setting the ''%s'' property of %s:',prop,classLink); +messageStr = regexprep(ME.message,'Class',classLink); +identifier = regexprep(ME.identifier,{'\','\.'},{mfilename('class'),':'},'ignorecase'); +% +newME = MException(identifier,'%s\n%s',firstLine,messageStr); +end + +%% EOF diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/closestvertex.m b/Required packages/Cursorbar/+graphics/@Cursorbar/closestvertex.m new file mode 100644 index 0000000..eab58e4 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/closestvertex.m @@ -0,0 +1,99 @@ +function [x,y,n] = closestvertex(hThis,pos,orient) +% CLOSESTVERTEX Return X,Y location of closest Target vertex +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% Change Log: +% 13 Feb 2015: First version posted on the MathWorks file exchange. +% 14 May 2015: Added logarithmic scale support. + +% input check +if nargin<3 || isempty(orient) + orient = hThis.Orientation; +end + +% initialize +hTarget = hThis.Target; +hAxes = hThis.Parent; +% +x = []; +y = []; + +% don't need to find closest vertex if the Target is an axes +if isTargetAxes(hThis) + return +end + +% get XData and YData +x = hThis.TargetXData; +y = hThis.TargetYData; +n = hThis.TargetNData; + +% logarithmic scale requires a logarithmic distance +switch hAxes.XScale + case 'linear' + pos_dist(1) = pos(1); + x_dist = x; + case 'log' + pos_dist(1) = log10(pos(1)); + x_dist = log10(x); +end +% +switch hAxes.YScale + case 'linear' + pos_dist(2) = pos(2); + y_dist = y; + case 'log' + pos_dist(2) = log10(pos(2)); + y_dist = log10(y); +end + +% translate to pixels +pixperdata = getPixelsPerData(hThis); +% +pos_dist = pos_dist .* pixperdata; +x_dist = x_dist * pixperdata(1); +y_dist = y_dist * pixperdata(2); + +% determine distance +is_2D_target = any( strcmp(class(hTarget),graphics.Cursorbar.Permitted2DTargets) ) ... + || strcmp(hThis.TargetIntersections,'single'); +is_single_target = isscalar(hTarget); + +if is_2D_target + % determine distance to the closest target + dist = hypot(pos_dist(1) - x_dist, pos_dist(2) - y_dist); + +elseif is_single_target + % determine distance in a single dimension, dependent on Orientation + switch orient + case 'vertical' + dist = abs(pos_dist(1) - x_dist); + case 'horizontal' + dist = abs(pos_dist(2) - y_dist); + end +else + % determine distance to the closest target, dependent on Orientation + distX = abs(pos_dist(1) - x_dist); + distY = abs(pos_dist(2) - y_dist); + % punish the secondary distance if the primary distance is too large + pixoffset = 3; % the error range + switch orient + case 'vertical' + distY(distX-min(distX)>pixoffset) = Inf; + case 'horizontal' + distX(distY-min(distY)>pixoffset) = Inf; + end + dist = hypot(distX, distY); +end + +% get index for minimum distance +[~,ind] = min(dist); + +% set output variables +x = x(ind); +y = y(ind); +n = n(ind); diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/createNewDataCursor.m b/Required packages/Cursorbar/+graphics/@Cursorbar/createNewDataCursor.m new file mode 100644 index 0000000..64c4de8 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/createNewDataCursor.m @@ -0,0 +1,53 @@ +function hNewDataCursor = createNewDataCursor(hThis,hTarget) +% CREATENEWDATACURSOR Creates a new data cursor +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2015-2016 The MathWorks, Inc. + +% set source +if nargin<2 + hTarget = hThis.Target(1); +end + +% create a Data Cursor +if isTargetAxes(hThis) + % target is an axes: create a dummy line handle + hDummyLineHandle = line(0,0, 'Parent', hThis.GroupHandle, ... + 'Visible','off', 'HandleVisibility','off', 'Clipping','off',... + 'PickableParts','none', 'HitTest','off', 'Interruptible','off'); + hThis.DataCursorDummyTargetHandle = matlab.graphics.chart.primitive.Line(hDummyLineHandle); + % + hNewDataCursor = matlab.graphics.shape.internal.PointDataCursor(hThis.DataCursorDummyTargetHandle); + +elseif isTargetChart(hThis) + % target is a chart: create a direct point data cursor + try % create directly + hNewDataCursor = matlab.graphics.shape.internal.PointDataCursor( hTarget ); + catch % probably, not a DataAnnotatable (matlab.graphics.chart.interaction.DataAnnotatable) + try % create via datacursormode + hDataCursorMode = datacursormode(); + hDataTip = hDataCursorMode.createDatatip( hTarget ); + % + hNewDataCursor = hDataTip.Cursor; + % + delete(hDataTip); % it's services are no longer required + hDataCursorMode.Enable = 'off'; % disable data cursor mode + catch % throw error + error(message('MATLAB:cursorbar:InvalidTarget')); + end + end + +else + % throw error + error(message('MATLAB:cursorbar:InvalidTarget')); +end + +% delete old handle +hOldDataCursor = hThis.DataCursorHandle; +delete(hOldDataCursor); + +% update old handle +hThis.DataCursorHandle = hNewDataCursor; + diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/defaultUIContextMenu.m b/Required packages/Cursorbar/+graphics/@Cursorbar/defaultUIContextMenu.m new file mode 100644 index 0000000..24141b8 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/defaultUIContextMenu.m @@ -0,0 +1,122 @@ +function uictxtmenu = defaultUIContextMenu(hThis) +% DEFAULTUICONTEXTMENU Default Cursorbar UIContextMenu. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% check the figure +hFig = ancestor(hThis,'figure'); +% +if isempty(hFig) || ~ishghandle(hFig) + % probably, happens during loading process + % exit to prevent MATLAB from crushing + uictxtmenu = gobjects(0); + return +end + +% set context menu +uictxtmenu = uicontextmenu('Parent',hFig); +uictxtmenu.Serializable = 'off'; % don't save to file + +% define menu properties +menuprops = struct; +menuprops.Parent = uictxtmenu; +menuprops.Serializable = 'off'; % don't save to file + +% first menu +menuprops.Label = 'Show Text'; +menuprops.Checked = hThis.ShowText; +menuprops.Callback = {@localSetShowText,hThis}; +% +u(1) = uimenu(menuprops); +l(1) = event.proplistener(hThis,findprop(hThis,'ShowText'), ... + 'PostSet',@(obj,evd)localGetShowText(u(1),evd,hThis)); + +% second menu +menuprops.Label = 'Multiple Intersections'; +switch hThis.TargetIntersections + case 'multiple', menuprops.Checked = 'on'; + case 'single', menuprops.Checked = 'off'; +end +menuprops.Callback = {@localSetTargetIntersections,hThis}; +% +u(2) = uimenu(menuprops); +l(2) = event.proplistener(hThis,findprop(hThis,'TargetIntersections'), ... + 'PostSet',@(obj,evd)localGetTargetIntersections(u(2),evd,hThis)); + +% third menu +menuprops.Label = 'Short Description'; +switch hThis.TextDescription + case 'short', menuprops.Checked = 'on'; + case 'long', menuprops.Checked = 'off'; +end +menuprops.Callback = {@localSetTextDescription,hThis}; +% +u(3) = uimenu(menuprops); +l(3) = event.proplistener(hThis,findprop(hThis,'TextDescription'), ... + 'PostSet',@(obj,evd)localGetTextDescription(u(3),evd,hThis)); + +% store listeners +hThis.SelfListenerHandles = [hThis.SelfListenerHandles, l]; + +%% Subfunctions + +function localGetShowText(hMenu,~,hThis) +% LOCALGETSHOWTEXT Get ShowText property. +switch hThis.ShowText + case 'on', hMenu.Checked = 'on'; + case 'off', hMenu.Checked = 'off'; +end + +function localSetShowText(hMenu,~,hThis) +% LOCALSETSHOWTEXT SetShowText Property +switch get(hMenu,'Checked') + case 'on' + set(hMenu,'Checked','off') + set(hThis,'ShowText','off') + case 'off' + set(hMenu,'Checked','on') + set(hThis,'ShowText','on') +end + +% -------------------------------------- + +function localGetTargetIntersections(hMenu,~,hThis) +% LOCALGETTARGETINTERSECTIONS Get TargetIntersections Property +switch hThis.TargetIntersections + case 'multiple', hMenu.Checked = 'on'; + case 'single', hMenu.Checked = 'off'; +end + +function localSetTargetIntersections(hMenu,~,hThis) +% LOCALSETTARGETINTERSECTIONS Set TargetIntersections Property +switch get(hMenu,'Checked') + case 'on' + set(hMenu,'Checked','off') + set(hThis,'TargetIntersections','single') + case 'off' + set(hMenu,'Checked','on') + set(hThis,'TargetIntersections','multiple') +end + +% -------------------------------------- + +function localGetTextDescription(hMenu,~,hThis) +% LOCALGETTEXTDESCRIPTION Get TextDescription Property +switch hThis.TextDescription + case 'short', hMenu.Checked = 'on'; + case 'long', hMenu.Checked = 'off'; +end + +function localSetTextDescription(hMenu,~,hThis) +% LOCALSETTEXTDESCRIPTION Set TextDescription Property +switch get(hMenu,'Checked') + case 'on' + set(hMenu,'Checked','off') + set(hThis,'TextDescription','long') + case 'off' + set(hMenu,'Checked','on') + set(hThis,'TextDescription','short') +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/defaultUpdateFcn.m b/Required packages/Cursorbar/+graphics/@Cursorbar/defaultUpdateFcn.m new file mode 100644 index 0000000..2e2973a --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/defaultUpdateFcn.m @@ -0,0 +1,193 @@ +function defaultUpdateFcn(hThis,~,~) +% DEFAULTUPDATEFCN Default cursorbar UpdateFcn. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% Change Log: +% 13 Feb 2015: First version posted on the MathWorks file exchange. +% 14 May 2015: Added logarithmic scale support. + +hText = get(hThis,'DisplayHandle'); + +if strcmp(hThis.ShowText,'off') || strcmp(hThis.Visible,'off') + if ~isempty(hText) + delete(hText); + hThis.DisplayHandle = gobjects(0); + return + end + return +end + +% get the locations of the markers +if ~all(isvalid(hThis.TargetMarkerHandle)) + return; +end +xData = get(hThis.TargetMarkerHandle,'XData'); +yData = get(hThis.TargetMarkerHandle,'YData'); + +numIntersections = length(xData); + +% get the handles for the text objects, corresponding to each intersection +hAxes = get(hThis,'Parent'); + +%%%%%%%%%%%%% + +AXCOLOR = get(hAxes,'Color'); + +if ischar(AXCOLOR), AXCOLOR = get(hAxes,'Color'); end + +% light colored axes +if sum(AXCOLOR)>1.5 + TEXTCOLOR = [0,0,0]; FACECOLOR = [1 1 238/255]; EDGECOLOR = [.8 .8 .8]; + % dark colored axes (i.e. simulink scopes) +else + TEXTCOLOR = [.8 .8 .6]; FACECOLOR = 48/255*[1 1 1]; EDGECOLOR = [.8 .8 .6]; +end + +%%%%%%%%%%%%% + +% create text objects if necessary +if isempty(hText) || any(~ishandle(hText)) + hText = gobjects(numIntersections,1); + for n = 1:numIntersections + hText(n) = text(xData(n),yData(n),'',... + 'Parent',hThis.GroupHandle, ... % 'Parent',hAxes,... + 'Color',TEXTCOLOR,... + 'EdgeColor',EDGECOLOR,... + 'BackgroundColor',FACECOLOR,... + 'Visible','off'); + end + numText = numIntersections; +else + % if the number of intersections isn't equal to the number of text objects, + % add/delete them as necessary + + set(hText,'Visible','off'); + + numText = length(hText); + + if numText ~= numIntersections + % unequal number of text objects and intersections + delete(hText) + + hText = gobjects(numIntersections,1); + + for n = numIntersections: -1 : 1 + hText(n) = text(xData(n),yData(n),'',... + 'Parent',hThis.GroupHandle, ... % 'Parent',hAxes,... + 'Color',TEXTCOLOR,... + 'EdgeColor',EDGECOLOR,... + 'BackgroundColor',FACECOLOR,... + 'Visible','off'); + end + numText = numIntersections; + end + +end + +% now update the text objects + +set(hText,'Visible','off','Units','data') + +xl = get(hAxes,'XLim'); +yl = get(hAxes,'YLim'); + +xdir = get(hAxes,'XDir'); +ydir = get(hAxes,'YDir'); + +pixperdata = getPixelsPerData(hThis); +pixoffset = 12; + +for n = 1:numText + x = xData(n); + y = yData(n); + + if x >= mean(xl) + if strcmp(xdir,'normal') + halign = 'right'; + xoffset = -pixoffset * 1/pixperdata(1); + else + halign = 'left'; + xoffset = pixoffset * 1/pixperdata(1); + end + else + if strcmp(xdir,'normal') + halign = 'left'; + xoffset = pixoffset * 1/pixperdata(1); + else + halign = 'right'; + xoffset = -pixoffset * 1/pixperdata(1); + end + end + + if y >= mean(yl) + if strcmp(ydir,'normal') + valign = 'top'; + yoffset = -pixoffset * 1/pixperdata(2); + else + valign = 'bottom'; + yoffset = pixoffset * 1/pixperdata(2); + end + else + if strcmp(ydir,'normal') + valign = 'bottom'; + yoffset = pixoffset * 1/pixperdata(2); + else + valign = 'top'; + yoffset = -pixoffset * 1/pixperdata(2); + end + end + + if ~isempty( hThis.TargetZData ) + [~,ind] = min( hypot(hThis.TargetXData-x, hThis.TargetYData-y) ); + ind = ind(1); + z = hThis.TargetZData(ind); + else + z = []; + end + + % assert proper scale + switch [hAxes.XScale '-' hAxes.YScale] + case 'linear-linear' + posoffset = [x+xoffset, y+yoffset, 0]; + case 'log-linear' + posoffset = [x*10^xoffset, y+yoffset, 0]; + case 'linear-log' + posoffset = [x+xoffset, y*10^yoffset, 0]; + case 'log-log' + posoffset = [x*10^xoffset, y*10^yoffset, 0]; + end + + set(hText(n),'Position',posoffset,... + 'String',makeString(x,y,z,hThis.Orientation,hThis.TextDescription),... + 'HorizontalAlignment',halign,... + 'VerticalAlignment',valign); +end + + +set(hThis,'DisplayHandle',hText); + +set(hText,'Visible','on'); + +% -------------------------------------- +function str = makeString(x,y,z,orient,desc) +% MAKESTRING Make the text description string +frmt = '%.3g'; +switch desc + case 'short' + switch orient + case 'vertical' + str = ['Y: ' sprintf(frmt,y)]; + case 'horizontal' + str = ['X: ' sprintf(frmt,x)]; + end + case 'long' + if isempty(z) + str = { ['X: ' sprintf(frmt,x)] , ['Y: ' sprintf(frmt,y)]}; + else + str = { ['X: ' sprintf(frmt,x)] , ['Y: ' sprintf(frmt,y)] , ['Z: ' sprintf(frmt,z)]}; + end +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/drawCrossbar.m b/Required packages/Cursorbar/+graphics/@Cursorbar/drawCrossbar.m new file mode 100644 index 0000000..0ac66d5 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/drawCrossbar.m @@ -0,0 +1,109 @@ +function hThat = drawCrossbar(hThis,varargin) +% DRAWCROSSBAR Draws a linked perpendicular bar. +% +% See also: graphics.Cursorbar.duplicate, graphics.Cursorbar. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2015-2016 The MathWorks, Inc. + +% draw crossbar depending on situation: +if isempty(hThis) + % empty Cursorbar: return empty array + hThat = graphics.Cursorbar.empty(size(hThis)); + return + +elseif ~isscalar(hThis) + % an array of Cursorbars: recursively draw crossbar to each + hThat = arrayfun(@(h)drawCrossbar(h,varargin{:}),hThis,'UniformOutput',0); + hThat = reshape([hThat{:}],size(hThis)); + return + +elseif ~isvalid(hThis) + % deleted Cursorbar: create default deleted object + hThat = graphics.GraphicsPlaceholder; + delete(hThat); + return +end + +% error check +assert( isempty(hThis.PeerHandle) || ~isvalid(hThis.PeerHandle), ... + 'graphics:Cursorbar:drawCrossbar:existingCrossbar', ... + 'A crossbar to this cursorbar already exists!'); + +% duplicate +newOrient = theOtherOrientation(hThis); +hThat = duplicate(hThis,varargin{:},'Orientation',newOrient); + +% set peers +hThat.PeerHandle = hThis; +hThis.PeerHandle = hThat; + +% reset position +hThis.Position = theOtherPosition(hThis); +hThat.Position = theOtherPosition(hThis); + +% set container peers +thisContainer = hThis.Container; +thatContainer = hThat.Container; +% +setPeer( thisContainer, thatContainer ); + +% link +localLinkCrossbarProps(hThis); +localLinkCrossbarProps(hThat); + +end + +% -------------------------------------- +function l = localLinkCrossbarProps(hCB) +% LOCALLINKCROSSBARPROPS Set the property linking + +% set listeners +l( 1 ) = addlistener(hCB,'Position', 'PostSet', ... + @(~,~)set(hCB.PeerHandle, 'Position', hCB.Position)); + +l(end+1) = addlistener(hCB,'Orientation','PostSet', ... + @(~,~)set(hCB.PeerHandle, 'Orientation',theOtherOrientation(hCB))); + +l(end+1) = addlistener(hCB,'ObjectBeingDestroyed', ... + @(~,~)localRemoveContainerPeers(hCB)); + +l(end+1) = addlistener(hCB,'ObjectBeingDestroyed', ... + @(~,~)delete(hCB.PeerHandle.ExternalListenerHandles)); + +% store listeners +hCB.ExternalListenerHandles = l; +end + +% -------------------------------------- +function localRemoveContainerPeers(hThis) +% LOCALREMOVECONTAINERPEERS Removes the peers from the containers +key = graphics.internal.CursorbarContainer.Key; +% +hFig = ancestor(hThis.Parent,'figure'); +thisContainers = getappdata(hFig,key); +thisCurrent = thisContainers( thisContainers.hasCursorbar(hThis) ); +% +removePeer(thisCurrent); +end + +% -------------------------------------- +function orient = theOtherOrientation(hCB) +% THEOTHERORIENTATION Returns the other orientation +switch hCB.Orientation + case 'horizontal', orient='vertical'; + case 'vertical', orient='horizontal'; +end +end + +% -------------------------------------- +function pos = theOtherPosition(hCB) +% THEOTHERPOSITION Returns the other position +pos = hCB.Position; +switch hCB.Orientation + case 'horizontal', pos(1)=hCB.PeerHandle.Location; + case 'vertical', pos(2)=hCB.PeerHandle.Location; +end +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/duplicate.m b/Required packages/Cursorbar/+graphics/@Cursorbar/duplicate.m new file mode 100644 index 0000000..c2425ce --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/duplicate.m @@ -0,0 +1,64 @@ +function hThat = duplicate(hThis,varargin) +% DUPLICATE Duplicate the cursorbar to an identical one. +% +% Duplicate created an identical Cursorbar to the desired by directly +% calling the Cursorbar constructor. Cursorbar has no copy method and does +% not subclass matlab.mixin.Copyable, since the copying procedure in handle +% graphics may result in unexpected behavior. Instead, it uses duplicate as +% a hard-copy method. +% +% See also: graphics.Cursorbar.drawCrossbar, graphics.Cursorbar. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2015-2016 The MathWorks, Inc. + +% duplicate depending on situation: +if isempty(hThis) + % empty Cursorbar: return empty array + hThat = graphics.Cursorbar.empty(size(hThis)); + +elseif ~isscalar(hThis) + % an array of Cursorbars: recursively duplicate each + hThat = arrayfun(@(h)duplicate(h,varargin{:}),hThis,'UniformOutput',0); + hThat = reshape([hThat{:}],size(hThis)); + +elseif ~isvalid(hThis) + % deleted Cursorbar: create default deleted object + hThat = graphics.GraphicsPlaceholder; + delete(hThat); + +else + % everything is okay: duplicate the Cursorbar + hThat = graphics.Cursorbar( hThis.Target, ... + 'BottomMarker', hThis.BottomMarker, ... + 'CreateFcn', hThis.CreateFcn, ... + 'CursorLineColor', hThis.CursorLineColor, ... + 'CursorLineStyle', hThis.CursorLineStyle, ... + 'CursorLineWidth', hThis.CursorLineWidth, ... + 'DeleteFcn', hThis.DeleteFcn, ... + 'DisplayName', hThis.DisplayName, ... + 'FigureCallbacks', hThis.FigureCallbacks, ... + 'HitTest', hThis.HitTest, ... + 'Interruptible', hThis.Interruptible, ... + 'Location', hThis.Location, ... + 'Orientation', hThis.Orientation, ... + 'Parent', hThis.Parent, ... + 'Position', hThis.Position, ... + 'SelectionHighlight', hThis.SelectionHighlight, ... + 'ShowText', hThis.ShowText, ... + 'Tag', hThis.Tag, ... + 'TargetIntersections', hThis.TargetIntersections, ... + 'TargetMarkerEdgeColor', hThis.TargetMarkerEdgeColor, ... + 'TargetMarkerFaceColor', hThis.TargetMarkerFaceColor, ... + 'TargetMarkerSize', hThis.TargetMarkerSize, ... + 'TargetMarkerStyle', hThis.TargetMarkerStyle, ... + 'TextDescription', hThis.TextDescription, ... + 'TopMarker', hThis.TopMarker, ... + 'UserData', hThis.UserData, ... + 'Visible', hThis.Visible, ... + varargin{:}); +end + +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/getCursorInfo.m b/Required packages/Cursorbar/+graphics/@Cursorbar/getCursorInfo.m new file mode 100644 index 0000000..7269e5f --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/getCursorInfo.m @@ -0,0 +1,15 @@ +function info = getCursorInfo(hThis) +% GETCURSORINFO Get datacursor info from cursorbar +% +% See also: graphics.Cursorbar.getMarkerLocations, graphics.Cursorbar. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +info = struct; + +hDC = hThis.DataCursorHandle; + +info.Position = hDC.Position; diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/getIntersections.m b/Required packages/Cursorbar/+graphics/@Cursorbar/getIntersections.m new file mode 100644 index 0000000..533ad7d --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/getIntersections.m @@ -0,0 +1,108 @@ +function [xIntersect,yIntersect,hIntersect] = getIntersections(hThis,hLines) +% GETINTERSECTIONS Return intersection information +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% check inputs +if nargin > 1 + hLines = handle(hLines); + if ~all(isTargetChart(hThis)) + error(message('MATLAB:graphics:cursorbar:invalidInput')); + end +else + hLines = hThis.Target; +end + +xIntersect = []; +yIntersect = []; +hIntersect = []; + +if isTargetAxes(hThis) && nargin < 2 + % Target is an axes, no additional line handles as input, return early + return +end + +% get lines' XData and YData +xData = get(hLines,'XData'); +yData = get(hLines,'YData'); + +numLines = numel(hLines); + +if numLines == 1 + xData = xData(:); + yData = yData(:); + hData = repmat(hLines,size(xData)); +else + xSizes = cellfun('prodofsize',xData); + + % determine new length for NaN separated data vectors + newLength = sum(xSizes) + numLines - 1; + + new_xData = zeros(newLength,1); + new_yData = zeros(newLength,1); + hData = zeros(newLength,1); + + startIndex = 1; + for n = 1:numLines + finishIndex = startIndex + xSizes(n) - 1; + new_xData(startIndex:finishIndex) = xData{n}; + new_yData(startIndex:finishIndex) = yData{n}; + hData(startIndex:finishIndex) = hLines(n); + + if n < numLines + new_xData(finishIndex + 1) = NaN; + new_yData(finishIndex + 1) = NaN; + hData(finishIndex + 1) = NaN; + end + startIndex = finishIndex + 2; + end + xData = new_xData; + yData = new_yData; +end + +xSegs = zeros(length(xData)-1,2); +ySegs = zeros(length(yData)-1,2); + +xSegs(:,1) = xData(1:end-1); +xSegs(:,2) = xData(2:end); + +ySegs(:,1) = yData(1:end-1); +ySegs(:,2) = yData(2:end); + +loc = hThis.Location; + +switch hThis.Orientation + case 'vertical' + btwn = (xSegs(:,1) < loc & loc <= xSegs(:,2)) | (xSegs(:,2) < loc & loc <= xSegs(:,1)); + case 'horizontal' + btwn = (ySegs(:,1) < loc & loc <= ySegs(:,2)) | (ySegs(:,2) < loc & loc <= ySegs(:,1)); +end + +new_xSegs = xSegs(btwn,:); +new_ySegs = ySegs(btwn,:); + +numIntersect = length(find(btwn)); +xIntersect = zeros(numIntersect,1); +yIntersect = zeros(numIntersect,1); + +if numIntersect == 0 + return +end + +switch hThis.Orientation + case 'vertical' + for n = 1:numIntersect + xIntersect(n) = loc; + yIntersect(n) = interp1(new_xSegs(n,:),new_ySegs(n,:),loc); + end + case 'horizontal' + for n = 1:numIntersect + yIntersect(n) = loc; + xIntersect(n) = interp1(new_ySegs(n,:),new_xSegs(n,:),loc); + end +end + +hIntersect = hData(btwn); diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/getMarkerLocations.m b/Required packages/Cursorbar/+graphics/@Cursorbar/getMarkerLocations.m new file mode 100644 index 0000000..e53c7b7 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/getMarkerLocations.m @@ -0,0 +1,14 @@ +function [x,y] = getMarkerLocations(hThis) +% GETMARKERLOCATIONS Return x,y position of the Cursorbar's intersection markers +% +% See also: graphics.Cursorbar.getCursorInfo, graphics.Cursorbar. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +hMarker = hThis.TargetMarkerHandle; + +x = get(hMarker,'XData'); +y = get(hMarker,'YData'); diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/getPixelsPerData.m b/Required packages/Cursorbar/+graphics/@Cursorbar/getPixelsPerData.m new file mode 100644 index 0000000..729f26f --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/getPixelsPerData.m @@ -0,0 +1,32 @@ +function pixperdata = getPixelsPerData(hThis) +% GETPIXELSPERDATA Return pixel-per-data ratio +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% Change Log: +% 13 Feb 2015: First version posted on the MathWorks file exchange. +% 14 May 2015: Added logarithmic scale support. + +hAxes = get(hThis,'Parent'); + +% get axes' limits +xl = get(hAxes,'XLim'); +yl = get(hAxes,'YLim'); + +% get Axes' pixel position +pixpos = getpixelposition(hAxes); + +% assert proper scale +switch [hAxes.XScale '-' hAxes.YScale] + case 'linear-linear' + pixperdata = [ pixpos(3) / (xl(2)-xl(1)), pixpos(4) / (yl(2)-yl(1))]; + case 'log-linear' + pixperdata = [ pixpos(3) / log10(xl(2)/xl(1)), pixpos(4) / (yl(2)-yl(1))]; + case 'linear-log' + pixperdata = [ pixpos(3) / (xl(2)-xl(1)), pixpos(4) / log10(yl(2)/yl(1))]; + case 'log-log' + pixperdata = [ pixpos(3) / log10(xl(2)/xl(1)), pixpos(4) / log10(yl(2)/yl(1))]; +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/getTargetXYData.m b/Required packages/Cursorbar/+graphics/@Cursorbar/getTargetXYData.m new file mode 100644 index 0000000..bd6581c --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/getTargetXYData.m @@ -0,0 +1,103 @@ +function [x,y,z,n] = getTargetXYData(hThis,orient) +% GETTARGETXYDATA Create vectors of Target XData and YData +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% set inputs +if nargin<2 || isempty(orient) + orient = hThis.Orientation; +end +hTarget = hThis.Target; + +x = []; +y = []; +z = []; +n = []; + +% set data +if isTargetAxes(hThis) + return +else + if isa(hTarget,'matlab.graphics.chart.primitive.Histogram') + xDataName = 'BinEdges'; + yDataName = 'Values'; + else + xDataName = 'XData'; + yDataName = 'YData'; + end + % + if numel(hTarget) == 1 + xData = {get(hTarget,xDataName)}; + yData = {get(hTarget,yDataName)}; + else % should all be lines + xData = get(hTarget, xDataName); + yData = get(hTarget, yDataName); + end + % + if isa(hTarget,'matlab.graphics.chart.primitive.Histogram') + xData = cellfun(@(x)x(2:end)-diff(x)/2, xData, 'UniformOutput', 0); % transform to BinCenters + end +end + +% check if CData exists +try + try + zData = {hTarget.ZData}; + catch + zData = {hTarget.CData}; + end + isZData = sum(cellfun('prodofsize',zData))>0; + % + if isZData && ~isequal( cellfun(@numel,xData), cellfun(@numel,zData) ) + [xData, yData] = cellfun( @meshgrid, xData, yData, 'UniformOutput', 0); + xData = cellfun( @(a)a(:).', xData, 'UniformOutput', 0); + yData = cellfun( @(a)a(:).', yData, 'UniformOutput', 0); + end +catch % never mind ... + zData = {}; + isZData = false; +end + +% determine how many vertices each line has +numLineVertices = cellfun('prodofsize',xData); + +% determine the total number of vertices +numAllVertices = sum(numLineVertices); + +% create vectors to hold locations for all vertices +xVertices = zeros(1,numAllVertices); +yVertices = zeros(1,numAllVertices); +zVertices = zeros(1,numAllVertices); +nVertices = zeros(1,numAllVertices); + +% initialize variable to hold the last entered data position +lastDataPos = 0; +for n = 1:length(hTarget) + lenData = length(xData{n}); + xVertices(lastDataPos+1:lastDataPos+lenData) = xData{n}; + yVertices(lastDataPos+1:lastDataPos+lenData) = yData{n}; + if isZData + zVertices(lastDataPos+1:lastDataPos+lenData) = zData{n}; + end + nVertices(lastDataPos+1:lastDataPos+lenData) = n; + lastDataPos = lastDataPos + lenData; +end + +% sort the Target's XData and YData based on the Orientation +switch orient + case 'vertical' + [x,ind] = sort(xVertices); + y = yVertices(ind); + case 'horizontal' + [y,ind] = sort(yVertices); + x = xVertices(ind); +end + +if isZData + z = zVertices(ind); +end + +n = nVertices(ind); diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/isTargetAxes.m b/Required packages/Cursorbar/+graphics/@Cursorbar/isTargetAxes.m new file mode 100644 index 0000000..a5be47f --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/isTargetAxes.m @@ -0,0 +1,21 @@ +function tf = isTargetAxes(hThis) +% ISTARGETAXES Is the Target an axes +% +% See also: graphics.Cursorbar.isTargetChart, graphics.Cursorbar. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +tf = false; + +% return empty if there is no Target +if isempty(hThis.Target) + tf = []; + return +end + +if (length(hThis.Target) == 1) && ishandle(hThis.Target) && isa(hThis.Target,'matlab.graphics.axis.Axes') + tf = true; +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/isTargetChart.m b/Required packages/Cursorbar/+graphics/@Cursorbar/isTargetChart.m new file mode 100644 index 0000000..c212f29 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/isTargetChart.m @@ -0,0 +1,36 @@ +function tf = isTargetChart(hThis,hTarget) +% ISTARGETCHART Is the Target a permitted chart object +% +% See also: graphics.Cursorbar.isTargetAxes, graphics.Cursorbar. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2015-2016 The MathWorks, Inc. + +% set the target +if nargin<2 + hTarget = hThis.Target; +end + +% return empty if there is no Target +if isempty(hTarget) + tf = []; + return +end +% +if ~all(ishandle(hTarget)) + tf = false(size(hTarget)); + return +end + +% check +tf = arrayfun(@isChart,hTarget); + +function tf = isChart(hTarget) +switch class(hTarget) % fastest comparison with switch + case graphics.Cursorbar.PermittedChartTargets + tf = true; + otherwise + tf = false; +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/move.m b/Required packages/Cursorbar/+graphics/@Cursorbar/move.m new file mode 100644 index 0000000..504173a --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/move.m @@ -0,0 +1,16 @@ +function move(hThis,dir) +% MOVE Move the data cursor and update cursorbar +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% Update cursor based on direction +moveDataCursor(hThis.DataCursorHandle,hThis,hThis.DataCursorHandle,dir); + +pos = get(hThis.DataCursorHandle,'Position'); +set(hThis,'Position',pos); + +% throw event indicating that the cursorbar was updated +notify(hThis,'UpdateCursorBar'); diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/moveDataCursor.m b/Required packages/Cursorbar/+graphics/@Cursorbar/moveDataCursor.m new file mode 100644 index 0000000..5afab4e --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/moveDataCursor.m @@ -0,0 +1,187 @@ +function moveDataCursor(hThis,hDataCursor,direc) +% MOVEDATACURSOR Move the data cursor +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% Change Log: +% 13 Feb 2015: First version posted on the MathWorks file exchange. +% 14 May 2015: Added logarithmic scale support. + +pos = hDataCursor.Position; + +hTarget = hThis.Target; +hAxes = get(hThis,'Parent'); + +xdir = get(hAxes,'XDir'); +ydir = get(hAxes,'YDir'); + +if all(isTargetChart(hThis)) + % determine next vertex + x = pos(1); + y = pos(2); + + XData = hThis.TargetXData; + YData = hThis.TargetYData; + + switch hThis.Orientation + case 'vertical' + % determine what the next possible X value is + switch xdir + case 'normal' + switch direc + case 'right' + % find next largest x value + ind = localNextIndex(x,XData,'greater'); + pos(1) = XData(ind); + pos(2) = YData(ind); + case 'left' + % find next smallest x value + ind = localNextIndex(x,XData,'less'); + pos(1) = XData(ind); + pos(2) = YData(ind); + otherwise + % do nothing + end + case 'reverse' + switch direc + case 'right' + % find next smallest x value + ind = localNextIndex(x,XData,'less'); + pos(1) = XData(ind); + pos(2) = YData(ind); + case 'left' + % find next largest x value + ind = localNextIndex(x,XData,'greater'); + pos(1) = XData(ind); + pos(2) = YData(ind); + otherwise + % do nothing + end + end + case 'horizontal' + % determine what the next possible Y value is + switch ydir + case 'normal' + switch direc + case 'up' + % find next largest x value + ind = localNextIndex(y,YData,'greater'); + pos(1) = XData(ind); + pos(2) = YData(ind); + case 'down' + % find next smallest x value + ind = localNextIndex(y,YData,'less'); + pos(1) = XData(ind); + pos(2) = YData(ind); + otherwise + % do nothing + end + case 'reverse' + switch direc + case 'up' + % find next smallest x value + ind = localNextIndex(y,YData,'less'); + pos(1) = XData(ind); + pos(2) = YData(ind); + case 'down' + % find next largest x value + ind = localNextIndex(y,YData,'greater'); + pos(1) = XData(ind); + pos(2) = YData(ind); + otherwise + % do nothing + end + end + end +elseif numel(hTarget) == 1 && isa(hTarget,'matlab.graphics.axis.Axes') + pixperdata = getPixelsPerData(hThis); + switch hThis.Orientation + case 'vertical' + switch xdir + case 'normal' + switch direc + case 'right' + xoffset = + 1/pixperdata(1); + case 'left' + xoffset = - 1/pixperdata(1); + otherwise + % do nothing + end + case 'reverse' + switch direc + case 'right' + xoffset = - 1/pixperdata(1); + case 'left' + xoffset = + 1/pixperdata(1); + otherwise + % do nothing + end + end + case 'horizontal' + switch ydir + case 'normal' + switch direc + case 'up' + yoffset = + 1/pixperdata(2); + case 'down' + yoffset = - 1/pixperdata(2); + otherwise + % do nothing + end + case 'reverse' + switch direc + case 'up' + yoffset = - 1/pixperdata(2); + case 'down' + yoffset = + 1/pixperdata(2); + otherwise + % do nothing + end + end + otherwise + % not vertical or horizontal + end + + % assert proper scale + x = pos(1); + y = pos(2); + % + switch [hAxes.XScale '-' hAxes.YScale] + case 'linear-linear' + pos = [x+xoffset, y+yoffset, 0]; + case 'log-linear' + pos = [x*10^xoffset, y+yoffset, 0]; + case 'linear-log' + pos = [x+xoffset, y*10^yoffset, 0]; + case 'log-log' + pos = [x*10^xoffset, y*10^yoffset, 0]; + end + +else + % not lines or an axes +end + + +hDataCursor.Position = pos; + +function ind = localNextIndex(d,Data,cmp) + +switch cmp + case 'greater' + ind = find(Data > d); + if isempty(ind) + ind = length(Data); + return + end + ind = min(ind); + case 'less' + ind = find(Data < d); + if isempty(ind) + ind = 1; + return + end + ind = max(ind); +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/update.m b/Required packages/Cursorbar/+graphics/@Cursorbar/update.m new file mode 100644 index 0000000..1a79b84 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/update.m @@ -0,0 +1,41 @@ +function update(hThis,~,~,varargin) +% UPDATE Update cursorbar position and string +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + + +% Exit during construction +if hThis.ObjectBeingCreated + return +end + +% Check input +movecb = true; +if nargin >= 4 && ischar(varargin{1}) && strcmp(varargin{1},'-nomove') + movecb = false; +end + +% Create new data cursor +if isvalid(hThis.DataCursorHandle) + hNewDataCursor = hThis.DataCursorHandle; +else + hNewDataCursor = createNewDataCursor(hThis); +end + +% Update cursor based on target +if movecb + updateDataCursor(hThis,hNewDataCursor); + hNewDataCursor = hThis.DataCursorHandle; % in the case it has changed +end + +% Update cursorbar based on cursor +updatePosition(hThis,hNewDataCursor); + +% Update markers +updateMarkers(hThis); + +% Send event indicating that the cursorbar was updated +notify(hThis,'UpdateCursorBar'); diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/updateDataCursor.m b/Required packages/Cursorbar/+graphics/@Cursorbar/updateDataCursor.m new file mode 100644 index 0000000..f80e5e1 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/updateDataCursor.m @@ -0,0 +1,43 @@ +function updateDataCursor(hThis,hNewDataCursor,~) +%UPDATEDATACURSOR Updates DataCursor's position. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +hAxes = get(hThis,'Parent'); +cp = get(hAxes,'CurrentPoint'); +pos = [cp(1,1) cp(1,2) 0]; +hTarget = hThis.Target; + +if isTargetAxes(hThis) + % axes: ignore interpolation, just use the axes' CurrentPoint + hNewDataCursor.DataSource.XData = pos(1); + hNewDataCursor.DataSource.YData = pos(2); + +else + % put the DataCursor in a correct place + [x,y,n] = closestvertex(hThis,pos); + if ~isscalar(hTarget) + if isa(hTarget,'matlab.graphics.chart.interaction.DataAnnotatable') + hNewDataCursor.DataSource = hTarget(n); + else + hNewDataCursor = createNewDataCursor(hThis,hTarget(n)); + end + end + + % update the DataCursor + if strcmp(hAxes.Parent.Type,'figure') + % update directly + hNewDataCursor.Position = [x y 0]; + else + % if the parent is not a figure (e.g., panel), the position of the + % DataCursor is not rendered correctly; thus, a change of parents + % is mandatory + axesPar = hAxes.Parent; + hAxes.Parent = ancestor(hAxes,'figure'); + hNewDataCursor.Position = [x y 0]; + hAxes.Parent = axesPar; + end +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/updateDisplay.m b/Required packages/Cursorbar/+graphics/@Cursorbar/updateDisplay.m new file mode 100644 index 0000000..9e4cbe7 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/updateDisplay.m @@ -0,0 +1,33 @@ +function updateDisplay(hThis,~,~) +% UPDATEDISPLAY Updates DisplayHandle. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% exit during construction +if hThis.ObjectBeingCreated + return +end + +% update text handles +hText = get(hThis,'DisplayHandle'); +% +if strcmp(hThis.ShowText,'off') || strcmp(hThis.Visible,'off') + if ~isempty(hText) + delete(hText); + hThis.DisplayHandle = gobjects(0); + return + end + return +end + +% update +defaultUpdateFcn(hThis); + +if ~isempty(hThis.UpdateFcn) + hThis.localApplyUpdateFcn(hThis,[]); +end + + diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/updateMarkers.m b/Required packages/Cursorbar/+graphics/@Cursorbar/updateMarkers.m new file mode 100644 index 0000000..e2f127f --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/updateMarkers.m @@ -0,0 +1,55 @@ +function updateMarkers(hThis) +% UPDATEMARKERS Updates data markers. +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% exit during construction +if hThis.ObjectBeingCreated + return +end + +% get line handles +hTarget = hThis.Target; + +% get current position +pos = get(hThis,'Position'); +if isempty(pos), return; end % probably, at startup + +% determine which vertices will be intersected +switch hThis.TargetIntersections + case 'multiple' % find all intersection based on the Orientation + switch hThis.Orientation + case 'vertical' + ind = find(hThis.TargetXData == pos(1)); % find only the identical positions + if isempty(ind) + [~,ind] = min( abs(hThis.TargetXData - pos(1)) ); % find the closest ones + end + case 'horizontal' + ind = find(hThis.TargetYData == pos(2)); % find only the identical positions + if isempty(ind) + [~,ind] = min( abs(hThis.TargetYData - pos(2)) ); % find the closest ones + end + end + case 'single' % just the closest ones + [~,ind] = min( hypot(hThis.TargetXData-pos(1), hThis.TargetYData-pos(2)) ); + if ~isempty(ind) + ind = ind(1); + end +end + +% set the target markers +if all(isvalid(hThis.TargetMarkerHandle)) + if all(isvalid(hTarget)) && ~isa(hTarget,'matlab.graphics.axis.Axes') + set(hThis.TargetMarkerHandle,'Visible','on',... + 'XData',hThis.TargetXData(ind),... + 'YData',hThis.TargetYData(ind)); + else + % + set(hThis.TargetMarkerHandle,'Visible','off',... + 'XData',[],... + 'YData',[]); + end +end diff --git a/Required packages/Cursorbar/+graphics/@Cursorbar/updatePosition.m b/Required packages/Cursorbar/+graphics/@Cursorbar/updatePosition.m new file mode 100644 index 0000000..b8cfe0c --- /dev/null +++ b/Required packages/Cursorbar/+graphics/@Cursorbar/updatePosition.m @@ -0,0 +1,36 @@ +function updatePosition(hThis,hNewDataCursor) +% UPDATEPOSITION Update cursorbar position based on data cursor +% +% Thanks to Yaroslav Don for his assistance in updating cursorbar for +% MATLAB Graphics and for his contribution of new functionality. + +% Copyright 2003-2016 The MathWorks, Inc. + +% Set parameters +pos = hNewDataCursor.Position; +hAxes = hThis.Parent; +ok = false; + +% See if the cursor position is empty or outside the axis limits +xlm = get(hAxes,'XLim'); +ylm = get(hAxes,'YLim'); +zlm = get(hAxes,'ZLim'); +% +if ~isempty(pos) && ... + (pos(1) >= min([xlm Inf])) && (pos(1) <= max([xlm -Inf])) && ... + (pos(2) >= min([ylm Inf])) && (pos(2) <= max([ylm -Inf])) + if length(pos) > 2 + if pos(3) >= min([zlm Inf]) && pos(3) <= max([zlm -Inf]) + ok =true; + end + else + pos(3) = 0; + ok = true; + end +end + +% Update DataCursorHandle and Position +if ok + hThis.DataCursorHandle = hNewDataCursor; + hThis.Position = pos; +end diff --git a/Required packages/Cursorbar/+graphics/Graphics.m b/Required packages/Cursorbar/+graphics/Graphics.m new file mode 100644 index 0000000..a653740 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/Graphics.m @@ -0,0 +1,187 @@ +classdef (Abstract) Graphics < handle & matlab.mixin.Heterogeneous & matlab.mixin.CustomDisplay + % Graphics Common base class for graphics objects + % + % The graphics.Graphics class is the base class of all graphics objects. + % Because graphics objects are part of a heterogeneous hierarchy, you + % can create arrays of mixed classes (for example, an array can contain + % lines, surfaces, axes, and other graphics objects). + % + % The class of an array of mixed objects is graphics.Graphics because + % this class is common to all graphics objects. + % + % Graphics requires the new MATLAB graphics system that + % was introduced in R2014b + % + % Inherited matlab.mixin.CustomDisplay Methods: + % details - Fully detailed formal object display. + % disp - Simple informal object display. + % display - Print variable name and display object. + % + % Inherited matlab.mixin.Heterogeneous Methods: + % cat - Concatenation for heterogeneous arrays. + % horzcat - Horizontal concatenation for + % heterogeneous arrays. + % vertcat - Vertical concatenation for + % heterogeneous arrays. + % + % Protected Methods: + % getDefaultScalarElement - Define default element for array + % operations. + % + % Inherited handle Methods: + % addlistener - Add listener for event. + % delete - Delete a handle object. + % eq - Test handle equality. + % findobj - Find objects with specified property + % values. + % findprop - Find property of MATLAB handle object. + % ge - Greater than or equal relation. + % gt - Greater than relation. + % isvalid - Test handle validity. + % le - Less than or equal relation for handles. + % lt - Less than relation for handles. + % ne - Not equal relation for handles. + % notify - Notify listeners of event. + % + % Inherited handle Events: + % ObjectBeingDestroyed - Notifies listeners that a particular + % object has been destroyed. + % Web: + % Undocumented Matlab: Undocumented cursorbar object. + % + % See also: graphics.GraphicsPlaceholder, graphics.Cursorbar. + % + % Thanks to Yaroslav Don for his assistance in updating cursorbar for + % MATLAB Graphics and for his contribution of new functionality. + + % Copyright 2016 The MathWorks, Inc. + + %% Main methods + + methods + function hThis = Graphics() + % Graphics A Graphics constructor. + % + % See also: Graphics. + + % Check MATLAB Graphics system version + if verLessThan('matlab','8.4.0') + error('graphics:Graphics:Graphics:oldVersion', ... + 'Graphics requires the new MATLAB graphics system that was introduced in R2014b.'); + end + end + end + + %% Heterogeneous methods + + methods (Static, Sealed, Access = protected) + function defaultObject = getDefaultScalarElement + defaultObject = graphics.GraphicsPlaceholder; + end + end + + %% Custom Display Methods + + methods (Access = protected, Sealed) + + % -------------------------------------- + function header = getHeader(hThis) + if ~isscalar(hThis) + % Non-scalar case: call superclass method + headerStr = getHeader@matlab.mixin.CustomDisplay(hThis); + if ismatrix(hThis) && ~isempty(hThis) + header = regexprep(headerStr,' with( no)? properties[\.:]',':'); + else + header = regexprep(headerStr,' with( no)? properties[\.:]','.'); + end + header = regexprep(header,'heterogeneous |heterogeneous ',''); + else + % Scalar case: check if a new header is required + if isprop(hThis,'Tag') + tagStr = hThis.Tag; + else + tagStr = ''; + end + % + if isempty(tagStr) + % No tag: call superclass method + header = getHeader@matlab.mixin.CustomDisplay(hThis); + else + % Use the tag + headerStr = matlab.mixin.CustomDisplay.getClassNameForHeader(hThis); + header = sprintf(' %s (%s) with properties:\n',headerStr,tagStr); + end + end + end + + % -------------------------------------- + function groups = getPropertyGroups(hThis) + % GETPROPERTYGROUPS Construct array of property groups. + if isscalar(hThis) + % Scalar case: call unsealed getScalarPropertyGroups + groups = getScalarPropertyGroups(hThis); + else + % Non-scalar case: empty list + groups = matlab.mixin.util.PropertyGroup({}); + end + end + + % -------------------------------------- + function footer = getFooter(hThis) + % GETFOOTER Build and return display footer text. + + if isscalar(hThis) + % Scalar case: prompt to show all properties + % similarly to graphics objects + if isempty(properties(hThis)) + % No properties: call superclass method + footer = getFooter@matlab.mixin.CustomDisplay(hThis); + return; + end + % + iname = inputname(1); + if isempty(iname) + iname = 'ans'; % ans is the default input name + end + % + footer = sprintf(... + [' Show all properties\n'], ... + iname,iname,iname,class(hThis),iname); + elseif ismatrix(hThis) && ~isempty(hThis) + % Non-scalar matrix case: show object's classes + % extract naked class name + txt = arrayfun(@class,hThis,'Uni',0); + txt = regexprep(txt,'^.*\.',''); + % add spaces and end-of-line + len = max(cellfun(@length,txt(:))); + txt = cellfun(@(s)sprintf(' %-*s',len,s),txt,'Uni',0); + txt(:,end) = strcat(txt(:,end),{sprintf('\n')}); + % finalize + footer = cell2mat(txt)'; + else + % Non-scalar case: call superclass method + footer = getFooter@matlab.mixin.CustomDisplay(hThis); + end + end + end + + % ============================================================= % + + methods (Access = protected) + function groups = getScalarPropertyGroups(hThis) %#ok + % GETSCALARPROPERTYGROUPS Construct array of property groups for display of scalar case. + + % default is empty + groups = matlab.mixin.util.PropertyGroup({}); + end + + end + +end + diff --git a/Required packages/Cursorbar/+graphics/GraphicsPlaceholder.m b/Required packages/Cursorbar/+graphics/GraphicsPlaceholder.m new file mode 100644 index 0000000..f0c4608 --- /dev/null +++ b/Required packages/Cursorbar/+graphics/GraphicsPlaceholder.m @@ -0,0 +1,85 @@ +classdef (ConstructOnLoad=true) GraphicsPlaceholder < graphics.Graphics + % GraphicsPlaceholder Default graphics object. + % + % The graphics.GraphicsPlaceholder class defines the default graphics + % object. Instances of this class appear as: + % + % * Elements of pre-allocated arrays created with hobjects. + % * Unassigned array element placeholders + % * Graphics object properties that hold object handles, but are set + % to empty values + % * Empty values returned by functions that return object handles (for + % example, findobj). + % + % Usage: + % graphics.GraphicsPlaceholder() - Creates a GraphicsPlaceholder. + % + % Example: + % x = linspace(0,20,101); + % y = sin(x); + % % + % hPlot = plot(x,y); + % hCBar(3) = cursorbar(hPlot); + % hGPHolder = hCBar(1) + % + % GraphicsPlaceholder Constructor: + % GraphicsPlaceholder - GraphicsPlaceholder constructor. + % + % Inherited matlab.mixin.CustomDisplay Methods: + % details - Fully detailed formal object display. + % disp - Simple informal object display. + % display - Print variable name and display object. + % + % Inherited matlab.mixin.Heterogeneous Methods: + % cat - Concatenation for heterogeneous arrays. + % horzcat - Horizontal concatenation for + % heterogeneous arrays. + % vertcat - Vertical concatenation for + % heterogeneous arrays. + % + % Inherited handle Methods: + % addlistener - Add listener for event. + % delete - Delete a handle object. + % eq - Test handle equality. + % findobj - Find objects with specified property + % values. + % findprop - Find property of MATLAB handle object. + % ge - Greater than or equal relation. + % gt - Greater than relation. + % isvalid - Test handle validity. + % le - Less than or equal relation for handles. + % lt - Less than relation for handles. + % ne - Not equal relation for handles. + % notify - Notify listeners of event. + % + % Inherited handle Events: + % ObjectBeingDestroyed - Notifies listeners that a particular + % object has been destroyed. + % Web: + % Undocumented Matlab: Undocumented cursorbar object. + % + % See also: graphics.Graphics, hobjects. + % + % Thanks to Yaroslav Don for his assistance in updating cursorbar for + % MATLAB Graphics and for his contribution of new functionality. + + % Copyright 2016 The MathWorks, Inc. + + %% Main methods + + methods + function hThis = GraphicsPlaceholder() + % GRAPHICSPLACEHOLDER A GraphicsPlaceholder constructor. + % + % See also: GraphicsPlaceholder. + + % Check MATLAB Graphics system version + if verLessThan('matlab','8.4.0') + error('graphics:GraphicsPlaceholder:GraphicsPlaceholder:oldVersion', ... + 'GraphicsPlaceholder requires the new MATLAB graphics system that was introduced in R2014b.'); + end + end + end + +end + diff --git a/Required packages/Cursorbar/crossbar.m b/Required packages/Cursorbar/crossbar.m new file mode 100644 index 0000000..7e13f29 --- /dev/null +++ b/Required packages/Cursorbar/crossbar.m @@ -0,0 +1,96 @@ +function [hCursorbar, hCrossbar] = crossbar(hTarget,varargin) +% CROSSBAR Creates two perpendicular linked cursorbars. +% +% The cursorbar can be dragged interactively across the axes. If +% attached to a plot, the cursor points are updated as well. The +% cursorbar can be either horizontal or vertical. +% +% The two crossed cursorbars are linked in position. Dragging one will +% update the position of the other to the cursor's location as well. +% +% Cursorbar requires the new MATLAB graphics system that was +% introduced in R2014b +% +% Usage: +% crossbar(hTarget) - Creates two perpendicular linked +% cursorbars on a target Axes or Chart. +% crossbar(hTarget, ...) - Creates two perpendicular linked +% cursorbars on a target Axes or Chart +% with additional property-value pairs. +% hCursorbars = crossbar(...) - Returns the handles to the two +% cursorbars. +% [hCo,hCross]= crossbar(...) - Returns the handles to the main +% cursorbar and to the crossed one. +% +% See graphics.Cursorbar for the full list of Cursorbar's properties. +% +% Example 1: Simple Crossbars +% x = linspace(-10,10,101); +% y = erf(x/5); +% % +% h = plot(x,y); +% crossbar(h); +% +% Example 2: Update Properties +% x = linspace(-10,10,49); +% M = peaks(length(x)); +% % +% h = imagesc(x,x,M); +% [cb,cr] = crossbar(h,'ShowText','off','TargetMarkerStyle','none'); +% % +% set(cr,'ShowText','on','TargetIntersections','single', ... +% 'TextDescription','long'); +% set([cb; cr], {'CursorLineColor'},{[1.0 0.8 0.8];[1.0 1.0 0.8];}); +% % +% cb.Position = [-7 3 0]; +% +% Example 3: Link Cursorbars +% t = linspace(0,12*pi,10001)'; +% x = 2*cos(t) + 2*cos(t/6); +% y = 2*sin(t) - 2*sin(t/6); +% % +% h = plot(x,y,'LineWidth',2); +% axis([-4 4 -4 4]); +% cb1 = crossbar(h,'CursorLineColor',[1 0 0],'Position',[-1 -1 0], ... +% 'TargetIntersections','single','CursorLineStyle','--'); +% cb2 = crossbar(h,'CursorLineColor',[1 0 1],'Position',[ 1 1 0], ... +% 'TargetIntersections','single','CursorLineStyle','--'); +% % +% l(1)=addlistener( cb1(1),'Location','PostSet', ... +% @(~,~) set ( cb2(1),'Location',cb1(1).Location+2)); +% l(2)=addlistener( cb1(2),'Location','PostSet', ... +% @(~,~) set ( cb2(2),'Location',cb1(2).Location+2)); +% l(3)=addlistener( cb2(1),'Location','PostSet', ... +% @(~,~) set ( cb1(1),'Location',cb2(1).Location-2)); +% l(4)=addlistener( cb2(2),'Location','PostSet', ... +% @(~,~) set ( cb1(2),'Location',cb2(2).Location-2)); +% +% See also: cursorbar, hobjects, graphics.Cursorbar. + +% Copyright 2016 The MathWorks, Inc. + +% Check MATLAB Graphics system version +if verLessThan('matlab','8.4.0') + error('crossbar:oldVersion', ... + 'Crossbar requires the new MATLAB graphics system that was introduced in R2014b.'); +end + +% error check +narginchk (1,Inf); +nargoutchk(0,2); + +% draw cursorbar +hTemp(1) = graphics.Cursorbar(hTarget,varargin{:}); +hTemp(2) = drawCrossbar(hTemp(1), varargin{:}); + +% output +switch nargout + case 0 + % never mind ... + case 1 + hCursorbar = hTemp; + case 2 + hCursorbar = hTemp(1); + hCrossbar = hTemp(2); +end + diff --git a/Required packages/Cursorbar/cursorbar.m b/Required packages/Cursorbar/cursorbar.m new file mode 100644 index 0000000..e2bee3c --- /dev/null +++ b/Required packages/Cursorbar/cursorbar.m @@ -0,0 +1,174 @@ +function hCursorbar = cursorbar(hTarget,varargin) +% CURSORBAR Creates a cursor line attached to an axes or lines. +% +% The cursorbar can be dragged interactively across the axes. If +% attached to a plot, the cursor points are updated as well. The +% cursorbar can be either horizontal or vertical. +% +% Cursorbar requires the new MATLAB graphics system that was +% introduced in R2014b +% +% Usage: +% cursorbar(hTarget) - Creates a cursorbar on a target Axes +% or Chart. +% cursorbar(hTarget, ...) - Creates a cursorbar on a target Axes +% or Chart with additional property- +% value pairs. +% hCursorbar = cursorbar(...) - Returns the handle to the Cursorbar. +% +% See graphics.Cursorbar for the full list of Cursorbar's properties. +% +% Example 1: Simple Cursorbar +% x = linspace(0,20,101); +% y = sin(x); +% % +% h = plot(x,y); +% cursorbar(h); +% +% Example 2: Target Axes +% x = linspace(-2,2,101)'; +% Y = [sin(x), 1-x.^2/2, erf(x), ones(size(x))]; +% % +% area(x,abs(Y)); +% cursorbar(gca,'CursorLineColor',[0.02 0.75 0.27]); +% set(gca,'Color','r') +% +% Example 3: Stem Plot +% x = 1:19; +% Y = interp1(1:5,magic(5),linspace(1,5,19),'pchip'); +% % +% h = stem(x,Y); +% cb = cursorbar(h); +% cb.TargetMarkerStyle = 'x'; +% +% Example 4: Logarithmic YScale +% x = linspace(0,4,41)'; +% Y = [exp(2*x)/4, exp(x/10)+1/160*exp(3*x), x.^2+1]; +% % +% h = stairs(x,Y,'LineWidth',2); +% % +% ax = gca; +% ax.YScale = 'log'; +% ax.YLim(2) = 1000; +% grid on; +% % +% cursorbar(h,'Location',2.7) +% +% Example 5: Crossbar +% x = linspace(-10,10,49); +% M = peaks(length(x)); +% % +% h = imagesc(x,x,M); +% cb = cursorbar(h,'ShowText','off','TargetMarkerStyle','none'); +% % +% cr = drawCrossbar(cb); +% set(cr,'ShowText','on','TargetIntersections','single', ... +% 'TextDescription','long'); +% set([cb; cr], {'CursorLineColor'},{[1.0 0.8 0.8];[1.0 1.0 0.8];}); +% % +% cb.Position = [-7 3 0]; +% +% Example 6: Preallocation +% x = linspace(-3,3,101); +% y = exp(-x.^2/2); +% % +% h = plot(x,y); +% for i=5:-1:1, +% cb(i) = cursorbar( h, 'Location',i-3, ... +% 'CursorLineColor',[(1-i/5) 0 i/5]); +% end +% +% Example 7: Listeners +% t = linspace(0,32*pi,10001)'; +% x = 2*cos(t) + 2*cos(t/16); +% y = 2*sin(t) - 2*sin(t/16); +% % +% ax= axes('XLim',[-4 4],'YLim',[-4 4],'NextPlot','add'); +% h = plot(x,y,'Color',[0.929 0.694 0.125]); +% % +% for i=5:-1:1, +% cb(i) = cursorbar( h, 'Location',i-3, 'ShowText','off', ... +% 'CursorLineColor',[(1-i/5) i/5 0]); +% end +% % +% % add listeners +% for i=1:5, +% j = mod(i,5)+1; +% addlistener ( cb(i),'Location','PostSet', ... +% @(~,~)set(cb(j),'Location',cb(i).Location+j-i)); +% end +% % +% addlistener(cb,'BeginDrag',@(~,~)set(ax,'Color',[.9 .8 .9])); +% addlistener(cb,'EndDrag' ,@(~,~)set(ax,'Color','w')); +% addlistener(cb,'UpdateCursorBar', ... +% @(~,~)set(h,'LineWidth',abs(cb(3).Location)+1)); +% +% Example 8: Save and Load +% % draw Cursorbars +% x = linspace(-4,4,101); +% y = cos(x); +% h = plot(x,y); +% % +% cb(1) = cursorbar(h,'Location',2.50,'CursorLineColor',[1 0 0]); +% cb(2) = cursorbar(h,'Location',-.25,'CursorLineColor',[0 1 0],... +% 'Orientation','horizontal'); +% cb(3) = drawCrossbar(cb(2)); +% % +% % save and load +% tempname = 'temp_cb.fig'; +% savefig(gcf,tempname); +% % +% open(tempname); +% +% Example 9: Marker Styles +% % create line plot +% x = linspace(0,14,201); +% y = sin(2*pi*x/3); +% % +% h = plot(x,y,':k','LineWidth',2); +% ylim([-1.2 1.2]); +% % +% % define colors +% topMarkers = 'x+*o.sdv^>0 + % create a full array + hCBar(nel) = graphics.GraphicsPlaceholder; + hCBar = reshape(hCBar,siz); +else + % create an empty array + hCBar = graphics.GraphicsPlaceholder.empty(siz); +end + +end diff --git a/Required packages/layout/+uiextras/BoxPanel.m b/Required packages/layout/+uiextras/BoxPanel.m new file mode 100644 index 0000000..fadf095 --- /dev/null +++ b/Required packages/layout/+uiextras/BoxPanel.m @@ -0,0 +1,139 @@ +classdef BoxPanel < uix.BoxPanel + %uiextras.BoxPanel Show one element inside a box panel + % + % obj = uiextras.BoxPanel() creates a box-styled panel object with + % automatic management of the contained widget or layout. The + % properties available are largely the same as the builtin UIPANEL + % object. Where more than one child is added, the currently visible + % child is determined using the SelectedChild property. + % + % obj = uiextras.BoxPanel(param,value,...) also sets one or more + % property values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> p = uiextras.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'r' ) + % + % >> f = figure(); + % >> p = uiextras.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 ); + % >> b = uiextras.HBox( 'Parent', p, 'Spacing', 5 ); + % >> uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} ); + % >> uicontrol( 'Style', 'frame', 'Parent', b, 'Background', 'b' ); + % >> set( b, 'Sizes', [100 -1] ); + % >> p.FontSize = 12; + % >> p.FontWeight = 'bold'; + % >> p.HelpFcn = @(x,y) disp('Help me!'); + % + % See also: uiextras.Panel + % uiextras.TabPanel + % uiextras.HBoxFlex + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 979 $ $Date: 2014-09-28 14:26:12 -0400 (Sun, 28 Sep 2014) $ + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + IsDocked + IsMinimized + SelectedChild % deprecated + end + + methods + + function obj = BoxPanel( varargin ) + + % Call uix constructor + obj@uix.BoxPanel( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.IsDocked( obj ) + + % Get + value = obj.Docked; + + end % get.IsDocked + + function set.IsDocked( obj, value ) + + % Get + obj.Docked = value; + + end % set.IsDocked + + function value = get.IsMinimized( obj ) + + % Get + value = obj.Minimized; + + end % get.IsMinimized + + function set.IsMinimized( obj, value ) + + % Get + obj.Minimized = value; + + end % set.IsMinimized + + function value = get.SelectedChild( obj ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''SelectedChild'' will be removed in a future release.' ) + + % Get + if isempty( obj.Contents_ ) + value = []; + else + value = 1; + end + + end % get.SelectedChild + + function set.SelectedChild( ~, ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''SelectedChild'' will be removed in a future release.' ) + + end % set.SelectedChild + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/CardPanel.m b/Required packages/layout/+uiextras/CardPanel.m new file mode 100644 index 0000000..3b13c44 --- /dev/null +++ b/Required packages/layout/+uiextras/CardPanel.m @@ -0,0 +1,93 @@ +classdef CardPanel < uix.CardPanel + %uiextras.CardPanel Show one element (card) from a list + % + % obj = uiextras.CardPanel() creates a new card panel which allows + % selection between the different child objects contained, making the + % selected child fill the space available and all other children + % invisible. This is commonly used for creating wizards or quick + % switching between different views of a single data-set. + % + % obj = uiextras.CardPanel(param,value,...) also sets one or more + % property values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> p = uiextras.CardPanel( 'Parent', f, 'Padding', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'r' ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'b' ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'g' ); + % >> p.SelectedChild = 2; + % + % See also: uiextras.Panel + % uiextras.BoxPanel + % uiextras.TabPanel + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 979 $ $Date: 2014-09-28 14:26:12 -0400 (Sun, 28 Sep 2014) $ + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + SelectedChild + end + + methods + + function obj = CardPanel( varargin ) + + % Call uix constructor + obj@uix.CardPanel( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.SelectedChild( obj ) + + % Get + value = obj.Selection; + + end % get.SelectedChild + + function set.SelectedChild( obj, value ) + + % Set + obj.Selection = value; + + end % set.SelectedChild + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/Empty.m b/Required packages/layout/+uiextras/Empty.m new file mode 100644 index 0000000..ed34711 --- /dev/null +++ b/Required packages/layout/+uiextras/Empty.m @@ -0,0 +1,30 @@ +function obj = Empty( varargin ) +%uiextras.Empty Create an empty space +% +% obj = uiextras.Empty() creates an empty space that can be used to add +% gaps between elements in layouts. +% +% obj = uiextras.Empty(param,value,...) also sets one or more property +% values. +% +% See the documentation for more detail and the list of properties. +% +% Examples: +% >> f = figure(); +% >> box = uiextras.HBox( 'Parent', f ); +% >> uicontrol( 'Parent', box, 'Background', 'r' ) +% >> uiextras.Empty( 'Parent', box ) +% >> uicontrol( 'Parent', box, 'Background', 'b' ) + +% Copyright 2009-2014 The MathWorks, Inc. +% $Revision: 1115 $ $Date: 2015-05-28 15:16:22 +0100 (Thu, 28 May 2015) $ + +% Call uix construction function +obj = uix.Empty( varargin{:} ); + +% Auto-parent +if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); +end + +end % uiextras.Empty \ No newline at end of file diff --git a/Required packages/layout/+uiextras/Grid.m b/Required packages/layout/+uiextras/Grid.m new file mode 100644 index 0000000..55d89f6 --- /dev/null +++ b/Required packages/layout/+uiextras/Grid.m @@ -0,0 +1,143 @@ +classdef Grid < uix.Grid + %uiextras.Grid Container with contents arranged in a grid + % + % obj = uiextras.Grid() creates a new new grid layout with all + % properties set to defaults. The number of rows and columns to use + % is determined from the number of elements in the RowSizes and + % ColumnSizes properties respectively. Child elements are arranged + % down column one first, then column two etc. If there are + % insufficient columns then a new one is added. The output is a new + % layout object that can be used as the parent for other + % user-interface components. The output is a new layout object that + % can be used as the parent for other user-interface components. + % + % obj = uiextras.Grid(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> g = uiextras.Grid( 'Parent', f, 'Spacing', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'r' ) + % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'b' ) + % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'g' ) + % >> uiextras.Empty( 'Parent', g ) + % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'c' ) + % >> uicontrol( 'Style', 'frame', 'Parent', g, 'Background', 'y' ) + % >> set( g, 'ColumnSizes', [-1 100 -2], 'RowSizes', [-1 100] ); + % + % See also: uiextras.GridFlex + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 1077 $ $Date: 2015-03-19 16:44:14 +0000 (Thu, 19 Mar 2015) $ + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + RowSizes % heights of contents, in pixels and/or weights + MinimumRowSizes % minimum heights of contents, in pixels + ColumnSizes % widths of contents, in pixels and/or weights + MinimumColumnSizes % minimum widths of contents, in pixels + end + + methods + + function obj = Grid( varargin ) + + % Call uix constructor + obj@uix.Grid( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.RowSizes( obj ) + + % Get + value = obj.Heights; + + end % get.RowSizes + + function set.RowSizes( obj, value ) + + % Set + obj.Heights = value; + + end % set.RowSizes + + function value = get.MinimumRowSizes( obj ) + + % Get + value = obj.MinimumHeights; + + end % get.MinimumRowSizes + + function set.MinimumRowSizes( obj, value ) + + % Set + obj.MinimumHeights = value; + + end % set.MinimumRowSizes + + function value = get.ColumnSizes( obj ) + + % Get + value = obj.Widths; + + end % get.ColumnSizes + + function set.ColumnSizes( obj, value ) + + % Get + obj.Widths = value; + + end % set.ColumnSizes + + function value = get.MinimumColumnSizes( obj ) + + % Get + value = obj.MinimumWidths; + + end % get.MinimumColumnSizes + + function set.MinimumColumnSizes( obj, value ) + + % Get + obj.MinimumWidths = value; + + end % set.MinimumColumnSizes + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/GridFlex.m b/Required packages/layout/+uiextras/GridFlex.m new file mode 100644 index 0000000..6901bc1 --- /dev/null +++ b/Required packages/layout/+uiextras/GridFlex.m @@ -0,0 +1,161 @@ +classdef GridFlex < uix.GridFlex + %uiextras.GridFlex Container with contents arranged in a resizable grid + % + % obj = uiextras.GridFlex() creates a new new grid layout with + % draggable dividers between elements. The number of rows and columns + % to use is determined from the number of elements in the RowSizes + % and ColumnSizes properties respectively. Child elements are + % arranged down column one first, then column two etc. If there are + % insufficient columns then a new one is added. The output is a new + % layout object that can be used as the parent for other + % user-interface components. The output is a new layout object that + % can be used as the parent for other user-interface components. + % + % obj = uiextras.GridFlex(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> g = uiextras.GridFlex( 'Parent', f, 'Spacing', 5 ); + % >> uicontrol( 'Parent', g, 'Background', 'r' ) + % >> uicontrol( 'Parent', g, 'Background', 'b' ) + % >> uicontrol( 'Parent', g, 'Background', 'g' ) + % >> uiextras.Empty( 'Parent', g ) + % >> uicontrol( 'Parent', g, 'Background', 'c' ) + % >> uicontrol( 'Parent', g, 'Background', 'y' ) + % >> set( g, 'ColumnSizes', [-1 100 -2], 'RowSizes', [-1 -2] ); + % + % See also: uiextras.Grid + % uiextras.HBoxFlex + % uiextras.VBoxFlex + % uiextras.Empty + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 1062 $ $Date: 2014-10-30 13:30:17 +0000 (Thu, 30 Oct 2014) $ + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + RowSizes % heights of contents, in pixels and/or weights + MinimumRowSizes % minimum heights of contents, in pixels + ColumnSizes % widths of contents, in pixels and/or weights + MinimumColumnSizes % minimum widths of contents, in pixels + ShowMarkings + end + + methods + + function obj = GridFlex( varargin ) + + % Call uix constructor + obj@uix.GridFlex( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.RowSizes( obj ) + + % Get + value = obj.Heights; + + end % get.RowSizes + + function set.RowSizes( obj, value ) + + % Set + obj.Heights = value; + + end % set.RowSizes + + function value = get.MinimumRowSizes( obj ) + + % Get + value = obj.MinimumHeights; + + end % get.MinimumRowSizes + + function set.MinimumRowSizes( obj, value ) + + % Set + obj.MinimumHeights = value; + + end % set.MinimumRowSizes + + function value = get.ColumnSizes( obj ) + + % Get + value = obj.Widths; + + end % get.ColumnSizes + + function set.ColumnSizes( obj, value ) + + % Get + obj.Widths = value; + + end % set.ColumnSizes + + function value = get.MinimumColumnSizes( obj ) + + % Get + value = obj.MinimumWidths; + + end % get.MinimumColumnSizes + + function set.MinimumColumnSizes( obj, value ) + + % Get + obj.MinimumWidths = value; + + end % set.MinimumColumnSizes + + function value = get.ShowMarkings( obj ) + + % Get + value = obj.DividerMarkings; + + end % get.ShowMarkings + + function set.ShowMarkings( obj, value ) + + % Set + obj.DividerMarkings = value; + + end % set.ShowMarkings + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/HBox.m b/Required packages/layout/+uiextras/HBox.m new file mode 100644 index 0000000..24ab270 --- /dev/null +++ b/Required packages/layout/+uiextras/HBox.m @@ -0,0 +1,114 @@ +classdef HBox < uix.HBox + %uiextras.HBox Arrange elements in a single horizontal row + % + % obj = uiextras.HBox() creates a new horizontal box layout with + % all parameters set to defaults. The output is a new layout object + % that can be used as the parent for other user-interface components. + % + % obj = uiextras.HBox(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> b = uiextras.HBox( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'Background', 'r' ) + % >> uicontrol( 'Parent', b, 'Background', 'b' ) + % >> uicontrol( 'Parent', b, 'Background', 'g' ) + % >> set( b, 'Sizes', [-1 100 -2], 'Spacing', 5 ); + % + % >> f = figure(); + % >> b1 = uiextras.VBox( 'Parent', f ); + % >> b2 = uiextras.HBox( 'Parent', b1, 'Padding', 5, 'Spacing', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', b1, 'Background', 'r' ) + % >> uicontrol( 'Parent', b2, 'String', 'Button1' ) + % >> uicontrol( 'Parent', b2, 'String', 'Button2' ) + % >> set( b1, 'Sizes', [30 -1] ); + % + % See also: uiextras.VBox + % uiextras.HBoxFlex + % uiextras.Grid + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 1077 $ $Date: 2015-03-19 16:44:14 +0000 (Thu, 19 Mar 2015) $ + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + Sizes + MinimumSizes + end + + methods + + function obj = HBox( varargin ) + + % Call uix constructor + obj@uix.HBox( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.Sizes( obj ) + + % Get + value = transpose( obj.Widths ); + + end % get.Sizes + + function set.Sizes( obj, value ) + + % Set + obj.Widths = value; + + end % set.Sizes + + function value = get.MinimumSizes( obj ) + + % Get + value = transpose( obj.MinimumWidths ); + + end % get.MinimumSizes + + function set.MinimumSizes( obj, value ) + + % Get + obj.MinimumWidths = value; + + end % set.MinimumSizes + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/HBoxFlex.m b/Required packages/layout/+uiextras/HBoxFlex.m new file mode 100644 index 0000000..4c22909 --- /dev/null +++ b/Required packages/layout/+uiextras/HBoxFlex.m @@ -0,0 +1,123 @@ +classdef HBoxFlex < uix.HBoxFlex + %uiextras.HBoxFlex A dynamically resizable horizontal layout + % + % obj = uiextras.HBoxFlex() creates a new dynamically resizable + % horizontal box layout with all parameters set to defaults. The + % output is a new layout object that can be used as the parent for + % other user-interface components. + % + % obj = uiextras.HBoxFlex(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure( 'Name', 'uiextras.HBoxFlex example' ); + % >> b = uiextras.HBoxFlex( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'Background', 'r' ) + % >> uicontrol( 'Parent', b, 'Background', 'b' ) + % >> uicontrol( 'Parent', b, 'Background', 'g' ) + % >> uicontrol( 'Parent', b, 'Background', 'y' ) + % >> set( b, 'Sizes', [-1 100 -2 -1], 'Spacing', 5 ); + % + % See also: uiextras.VBoxFlex + % uiextras.HBox + % uiextras.Grid + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 979 $ $Date: 2014-09-28 14:26:12 -0400 (Sun, 28 Sep 2014) $ + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + Sizes + MinimumSizes + ShowMarkings + end + + methods + + function obj = HBoxFlex( varargin ) + + % Call uix constructor + obj@uix.HBoxFlex( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.Sizes( obj ) + + % Get + value = transpose( obj.Widths ); + + end % get.Sizes + + function set.Sizes( obj, value ) + + % Set + obj.Widths = value; + + end % set.Sizes + + function value = get.MinimumSizes( obj ) + + % Get + value = transpose( obj.MinimumWidths ); + + end % get.MinimumSizes + + function set.MinimumSizes( obj, value ) + + % Get + obj.MinimumWidths = value; + + end % set.MinimumSizes + + function value = get.ShowMarkings( obj ) + + % Get + value = obj.DividerMarkings; + + end % get.ShowMarkings + + function set.ShowMarkings( obj, value ) + + % Set + obj.DividerMarkings = value; + + end % set.ShowMarkings + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/HButtonBox.m b/Required packages/layout/+uiextras/HButtonBox.m new file mode 100644 index 0000000..26ae9e8 --- /dev/null +++ b/Required packages/layout/+uiextras/HButtonBox.m @@ -0,0 +1,46 @@ +classdef HButtonBox < uix.HButtonBox + %uiextras.HButtonBox Arrange buttons horizontally in a single row + % + % obj = uiextras.HButtonBox() is a type of HBox specialised for + % arranging a row of buttons, check-boxes or similar graphical + % elements. All buttons are given equal size and by default are + % centered in the drawing area. The justification can be changed as + % required. + % + % obj = uiextras.HButtonBox(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> b = uiextras.HButtonBox( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'String', 'One' ); + % >> uicontrol( 'Parent', b, 'String', 'Two' ); + % >> uicontrol( 'Parent', b, 'String', 'Three' ); + % >> set( b, 'ButtonSize', [130 35], 'Spacing', 5 ); + % + % See also: uiextras.VButtonBox + % uiextras.HBox + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 1077 $ $Date: 2015-03-19 16:44:14 +0000 (Thu, 19 Mar 2015) $ + + methods + + function obj = HButtonBox( varargin ) + %uiextras.HButtonBox Create a new horizontal button box + + % Call uix constructor + obj@uix.HButtonBox( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/Panel.m b/Required packages/layout/+uiextras/Panel.m new file mode 100644 index 0000000..af3e8d4 --- /dev/null +++ b/Required packages/layout/+uiextras/Panel.m @@ -0,0 +1,106 @@ +classdef Panel < uix.Panel + %uiextras.Panel Show one element inside a panel + % + % obj = uiextras.Panel() creates a standard UIPANEL object but with + % automatic management of the contained widget or layout. The + % properties available are largely the same as the builtin UIPANEL + % object. Where more than one child is added, the currently visible + % child is determined using the SelectedChild property. + % + % obj = uiextras.Panel(param,value,...) also sets one or more + % property values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> p = uiextras.Panel( 'Parent', f, 'Title', 'A Panel', 'Padding', 5 ); + % >> uicontrol( 'Parent', p, 'Background', 'r' ) + % + % >> f = figure(); + % >> p = uiextras.Panel( 'Parent', f, 'Title', 'A Panel', 'Padding', 5 ); + % >> b = uiextras.HBox( 'Parent', p, 'Spacing', 5 ); + % >> uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} ); + % >> uicontrol( 'Parent', b, 'Background', 'b' ); + % >> set( b, 'Sizes', [100 -1] ); + % + % See also: uipanel + % uiextras.BoxPanel + % uiextras.HBox + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 979 $ $Date: 2014-09-28 14:26:12 -0400 (Sun, 28 Sep 2014) $ + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + SelectedChild + end + + methods + + function obj = Panel( varargin ) + + % Call uix constructor + obj@uix.Panel( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.SelectedChild( obj ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''SelectedChild'' will be removed in a future release.' ) + + % Get + if isempty( obj.Contents_ ) + value = []; + else + value = 1; + end + + end % get.SelectedChild + + function set.SelectedChild( ~, ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''SelectedChild'' will be removed in a future release.' ) + + end % set.SelectedChild + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/TabPanel.m b/Required packages/layout/+uiextras/TabPanel.m new file mode 100644 index 0000000..a1b8e5d --- /dev/null +++ b/Required packages/layout/+uiextras/TabPanel.m @@ -0,0 +1,224 @@ +classdef TabPanel < uix.TabPanel + %TabPanel Show one element inside a tabbed panel + % + % obj = uiextras.TabPanel() creates a panel with tabs along one edge + % to allow selection between the different child objects contained. + % + % obj = uiextras.TabPanel(param,value,...) also sets one or more + % property values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> p = uiextras.TabPanel( 'Parent', f, 'Padding', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'r' ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'b' ); + % >> uicontrol( 'Style', 'frame', 'Parent', p, 'Background', 'g' ); + % >> p.TabNames = {'Red', 'Blue', 'Green'}; + % >> p.SelectedChild = 2; + % + % See also: uiextras.Panel + % uiextras.BoxPanel + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 979 $ $Date: 2014-09-28 14:26:12 -0400 (Sun, 28 Sep 2014) $ + + properties( Hidden, Access = public, Dependent ) + Callback + end + + properties( Access = private ) + Callback_ = '' % backing for Callback + end + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + SelectedChild + TabEnable + TabNames + TabPosition + TabSize + end + + properties( Access = private ) + SelectionChangedListener % listener + end + + methods + + function obj = TabPanel( varargin ) + + % Call uix constructor + obj@uix.TabPanel( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + % Create listeners + selectionChangedListener = event.listener( obj, ... + 'SelectionChanged', @obj.onSelectionChanged ); + + % Store properties + obj.SelectionChangedListener = selectionChangedListener; + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.Callback( obj ) + + % Get + value = obj.Callback_; + + end % get.Callback + + function set.Callback( obj, value ) + + % Check + if ischar( value ) % string + % OK + elseif isa( value, 'function_handle' ) && ... + isequal( size( value ), [1 1] ) % function handle + % OK + elseif iscell( value ) && ndims( value ) == 2 && ... + size( value, 1 ) == 1 && size( value, 2 ) > 0 && ... + isa( value{1}, 'function_handle' ) && ... + isequal( size( value{1} ), [1 1] ) %#ok % cell callback + % OK + else + error( 'uiextras:InvalidPropertyValue', ... + 'Property ''Callback'' must be a valid callback.' ) + end + + % Set + obj.Callback_ = value; + + end % set.Callback + + function value = get.SelectedChild( obj ) + + % Get + value = obj.Selection; + + end % get.SelectedChild + + function set.SelectedChild( obj, value ) + + % Set + obj.Selection = value; + + end % set.SelectedChild + + function value = get.TabEnable( obj ) + + % Get + value = transpose( obj.TabEnables ); + + end % get.TabEnable + + function set.TabEnable( obj, value ) + + % Set + obj.TabEnables = value; + + end % set.TabEnable + + function value = get.TabNames( obj ) + + % Get + value = transpose( obj.TabTitles ); + + end % get.TabNames + + function set.TabNames( obj, value ) + + % Set + obj.TabTitles = value; + + end % set.TabNames + + function value = get.TabPosition( obj ) + + % Get + value = obj.TabLocation; + + end % get.TabPosition + + function set.TabPosition( obj, value ) + + % Set + obj.TabLocation = value; + + end % set.TabPosition + + function value = get.TabSize( obj ) + + % Get + value = obj.TabWidth; + + end % get.TabSize + + function set.TabSize( obj, value ) + + % Set + obj.TabWidth = value; + + end % set.TabSize + + end % accessors + + methods( Access = private ) + + function onSelectionChanged( obj, source, eventData ) + + % Create legacy event data structure + oldEventData = struct( 'Source', eventData.Source, ... + 'PreviousChild', eventData.OldValue, ... + 'SelectedChild', eventData.NewValue ); + + % Call callback + callback = obj.Callback_; + if ischar( callback ) && isequal( callback, '' ) + % do nothing + elseif ischar( callback ) + feval( callback, source, oldEventData ) + elseif isa( callback, 'function_handle' ) + callback( source, oldEventData ) + elseif iscell( callback ) + feval( callback{1}, source, oldEventData, callback{2:end} ) + end + + end % onSelectionChanged + + end % event handlers + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/VBox.m b/Required packages/layout/+uiextras/VBox.m new file mode 100644 index 0000000..ee6572f --- /dev/null +++ b/Required packages/layout/+uiextras/VBox.m @@ -0,0 +1,114 @@ +classdef VBox < uix.VBox + %uiextras.VBox Arrange elements vertically in a single column + % + % obj = uiextras.VBox() creates a new vertical box layout with all + % parameters set to defaults. The output is a new layout object that + % can be used as the parent for other user-interface components. + % + % obj = uiextras.VBox(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> b = uiextras.VBox( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'Background', 'r' ) + % >> uicontrol( 'Parent', b, 'Background', 'b' ) + % >> uicontrol( 'Parent', b, 'Background', 'g' ) + % >> set( b, 'Sizes', [-1 100 -2], 'Spacing', 5 ); + % + % >> f = figure(); + % >> b1 = uiextras.VBox( 'Parent', f ); + % >> b2 = uiextras.HBox( 'Parent', b1, 'Padding', 5, 'Spacing', 5 ); + % >> uicontrol( 'Style', 'frame', 'Parent', b1, 'Background', 'r' ) + % >> uicontrol( 'Parent', b2, 'String', 'Button1' ) + % >> uicontrol( 'Parent', b2, 'String', 'Button2' ) + % >> set( b1, 'Sizes', [30 -1] ); + % + % See also: uiextras.HBox + % uiextras.VBoxFlex + % uiextras.Grid + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 1077 $ $Date: 2015-03-19 16:44:14 +0000 (Thu, 19 Mar 2015) $ + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + Sizes + MinimumSizes + end + + methods + + function obj = VBox( varargin ) + + % Call uix constructor + obj@uix.VBox( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.Sizes( obj ) + + % Get + value = transpose( obj.Heights ); + + end % get.Sizes + + function set.Sizes( obj, value ) + + % Set + obj.Heights = value; + + end % set.Sizes + + function value = get.MinimumSizes( obj ) + + % Get + value = transpose( obj.MinimumHeights ); + + end % get.MinimumSizes + + function set.MinimumSizes( obj, value ) + + % Get + obj.MinimumHeights = value; + + end % set.MinimumSizes + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/VBoxFlex.m b/Required packages/layout/+uiextras/VBoxFlex.m new file mode 100644 index 0000000..12750dd --- /dev/null +++ b/Required packages/layout/+uiextras/VBoxFlex.m @@ -0,0 +1,123 @@ +classdef VBoxFlex < uix.VBoxFlex + %uiextras.VBoxFlex A dynamically resizable vertical layout + % + % obj = uiextras.VBoxFlex() creates a new dynamically resizable + % vertical box layout with all parameters set to defaults. The output + % is a new layout object that can be used as the parent for other + % user-interface components. + % + % obj = uiextras.VBoxFlex(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure( 'Name', 'uiextras.VBoxFlex example' ); + % >> b = uiextras.VBoxFlex( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'Background', 'r' ) + % >> uicontrol( 'Parent', b, 'Background', 'b' ) + % >> uicontrol( 'Parent', b, 'Background', 'g' ) + % >> uicontrol( 'Parent', b, 'Background', 'y' ) + % >> set( b, 'Sizes', [-1 100 -2 -1], 'Spacing', 5 ); + % + % See also: uiextras.HBoxFlex + % uiextras.VBox + % uiextras.Grid + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 979 $ $Date: 2014-09-28 14:26:12 -0400 (Sun, 28 Sep 2014) $ + + properties( Hidden, Access = public, Dependent ) + Enable % deprecated + Sizes + MinimumSizes + ShowMarkings + end + + methods + + function obj = VBoxFlex( varargin ) + + % Call uix constructor + obj@uix.VBoxFlex( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structors + + methods + + function value = get.Enable( ~ ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + % Return + value = 'on'; + + end % get.Enable + + function set.Enable( ~, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uiextras:InvalidPropertyValue', ... + 'Property ''Enable'' must be ''on'' or ''off''.' ) + + % Warn + % warning( 'uiextras:Deprecated', ... + % 'Property ''Enable'' will be removed in a future release.' ) + + end % set.Enable + + function value = get.Sizes( obj ) + + % Get + value = transpose( obj.Heights ); + + end % get.Sizes + + function set.Sizes( obj, value ) + + % Set + obj.Heights = value; + + end % set.Sizes + + function value = get.MinimumSizes( obj ) + + % Get + value = transpose( obj.MinimumHeights ); + + end % get.MinimumSizes + + function set.MinimumSizes( obj, value ) + + % Get + obj.MinimumHeights = value; + + end % set.MinimumSizes + + function value = get.ShowMarkings( obj ) + + % Get + value = obj.DividerMarkings; + + end % get.ShowMarkings + + function set.ShowMarkings( obj, value ) + + % Set + obj.DividerMarkings = value; + + end % set.ShowMarkings + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/VButtonBox.m b/Required packages/layout/+uiextras/VButtonBox.m new file mode 100644 index 0000000..9e56b4c --- /dev/null +++ b/Required packages/layout/+uiextras/VButtonBox.m @@ -0,0 +1,46 @@ +classdef VButtonBox < uix.VButtonBox + %uiextras.VButtonBox Arrange buttons vertically in a single column + % + % obj = uiextras.VButtonBox() is a type of VBox specialised for + % arranging a column of buttons, check-boxes or similar graphical + % elements. All buttons are given equal size and by default are + % centered in the drawing area. The justification can be changed as + % required. + % + % obj = uiextras.VButtonBox(param,value,...) also sets one or more + % parameter values. + % + % See the documentation for more detail and the list of properties. + % + % Examples: + % >> f = figure(); + % >> b = uiextras.VButtonBox( 'Parent', f ); + % >> uicontrol( 'Parent', b, 'String', 'One' ); + % >> uicontrol( 'Parent', b, 'String', 'Two' ); + % >> uicontrol( 'Parent', b, 'String', 'Three' ); + % >> set( b, 'ButtonSize', [130 35], 'Spacing', 5 ); + % + % See also: uiextras.HButtonBox + % uiextras.VBox + + % Copyright 2009-2014 The MathWorks, Inc. + % $Revision: 1077 $ $Date: 2015-03-19 16:44:14 +0000 (Thu, 19 Mar 2015) $ + + methods + + function obj = VButtonBox( varargin ) + %uiextras.VButtonBox Create a new horizontal button box + + % Call uix constructor + obj@uix.VButtonBox( varargin{:} ) + + % Auto-parent + if ~ismember( 'Parent', varargin(1:2:end) ) + obj.Parent = gcf(); + end + + end % constructor + + end % structor + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uiextras/get.m b/Required packages/layout/+uiextras/get.m new file mode 100644 index 0000000..d67e525 --- /dev/null +++ b/Required packages/layout/+uiextras/get.m @@ -0,0 +1,15 @@ +function varargout = get( ~, ~ ) %#ok +%uiextras.get Retrieve a default property value from a parent object +% +% This functionality has been removed. + +% Copyright 2009-2014 The MathWorks, Inc. +% $Revision: 979 $ $Date: 2014-09-28 14:26:12 -0400 (Sun, 28 Sep 2014) $ + +% Check inputs +narginchk( 2, 2 ) + +% Error +error( 'uiextras:Deprecated', 'uiextras.get has been removed.' ) + +end % uiextras.get \ No newline at end of file diff --git a/Required packages/layout/+uiextras/set.m b/Required packages/layout/+uiextras/set.m new file mode 100644 index 0000000..3fcfca6 --- /dev/null +++ b/Required packages/layout/+uiextras/set.m @@ -0,0 +1,15 @@ +function set( ~, ~, ~ ) +%uiextras.set Store a default property value in a parent object +% +% This functionality has been removed. + +% Copyright 2009-2014 The MathWorks, Inc. +% $Revision: 979 $ $Date: 2014-09-28 14:26:12 -0400 (Sun, 28 Sep 2014) $ + +% Check inputs +narginchk( 3, 3 ) + +% Warn +warning( 'uiextras:Deprecated', 'uiextras.set has been removed.' ) + +end % uiextras.set \ No newline at end of file diff --git a/Required packages/layout/+uiextras/unset.m b/Required packages/layout/+uiextras/unset.m new file mode 100644 index 0000000..dbda510 --- /dev/null +++ b/Required packages/layout/+uiextras/unset.m @@ -0,0 +1,15 @@ +function unset( ~, ~, ~ ) +%uiextras.unset Clear a default property value from a parent object +% +% This functionality has been removed. + +% Copyright 2009-2014 The MathWorks, Inc. +% $Revision: 979 $ $Date: 2014-09-28 14:26:12 -0400 (Sun, 28 Sep 2014) $ + +% Check inputs +narginchk( 2, 2 ) + +% Warn +warning( 'uiextras:Deprecated', 'uiextras.unset has been removed.' ) + +end % uiextras.unset \ No newline at end of file diff --git a/Required packages/layout/+uix/+mixin/Container.m b/Required packages/layout/+uix/+mixin/Container.m new file mode 100644 index 0000000..046f566 --- /dev/null +++ b/Required packages/layout/+uix/+mixin/Container.m @@ -0,0 +1,297 @@ +classdef Container < handle + %uix.mixin.Container Container mixin + % + % uix.mixin.Container is a mixin class used by containers to provide + % various properties and template methods. + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1358 $ $Date: 2016-09-14 11:34:17 +0100 (Wed, 14 Sep 2016) $ + + properties( Dependent, Access = public ) + Contents % contents in layout order + end + + properties( Access = public, Dependent, AbortSet ) + Padding % space around contents, in pixels + end + + properties( Access = protected ) + Contents_ = gobjects( [0 1] ) % backing for Contents + Padding_ = 0 % backing for Padding + end + + properties( Dependent, Access = protected ) + Dirty % needs redraw + end + + properties( Access = private ) + Dirty_ = false % backing for Dirty + FigureObserver % observer + FigureListener % listener + ChildObserver % observer + ChildAddedListener % listener + ChildRemovedListener % listener + SizeChangedListener % listener + ActivePositionPropertyListeners = cell( [0 1] ) % listeners + end + + methods + + function obj = Container() + %uix.mixin.Container Initialize + % + % c@uix.mixin.Container() initializes the container c. + + % Create observers and listeners + figureObserver = uix.FigureObserver( obj ); + figureListener = event.listener( figureObserver, ... + 'FigureChanged', @obj.onFigureChanged ); + childObserver = uix.ChildObserver( obj ); + childAddedListener = event.listener( ... + childObserver, 'ChildAdded', @obj.onChildAdded ); + childRemovedListener = event.listener( ... + childObserver, 'ChildRemoved', @obj.onChildRemoved ); + sizeChangedListener = event.listener( ... + obj, 'SizeChanged', @obj.onSizeChanged ); + + % Store observers and listeners + obj.FigureObserver = figureObserver; + obj.FigureListener = figureListener; + obj.ChildObserver = childObserver; + obj.ChildAddedListener = childAddedListener; + obj.ChildRemovedListener = childRemovedListener; + obj.SizeChangedListener = sizeChangedListener; + + % Track usage + obj.track() + + end % constructor + + end % structors + + methods + + function value = get.Contents( obj ) + + value = obj.Contents_; + + end % get.Contents + + function set.Contents( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + [tf, indices] = ismember( value, obj.Contents_ ); + assert( isequal( size( obj.Contents_ ), size( value ) ) && ... + numel( value ) == numel( unique( value ) ) && all( tf ), ... + 'uix:InvalidOperation', ... + 'Property ''Contents'' may only be set to a permutation of itself.' ) + + % Call reorder + obj.reorder( indices ) + + end % set.Contents + + function value = get.Padding( obj ) + + value = obj.Padding_; + + end % get.Padding + + function set.Padding( obj, value ) + + % Check + assert( isa( value, 'double' ) && isscalar( value ) && ... + isreal( value ) && ~isinf( value ) && ... + ~isnan( value ) && value >= 0, ... + 'uix:InvalidPropertyValue', ... + 'Property ''Padding'' must be a non-negative scalar.' ) + + % Set + obj.Padding_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Padding + + function value = get.Dirty( obj ) + + value = obj.Dirty_; + + end % get.Dirty + + function set.Dirty( obj, value ) + + if value + if obj.isDrawable() % drawable + obj.redraw() % redraw now + else % not drawable + obj.Dirty_ = true; % flag for future redraw + end + end + + end % set.Dirty + + end % accessors + + methods( Access = private, Sealed ) + + function onFigureChanged( obj, ~, eventData ) + %onFigureChanged Event handler + + % Call template method + obj.reparent( eventData.OldFigure, eventData.NewFigure ) + + % Redraw if possible and if dirty + if obj.Dirty_ && obj.isDrawable() + obj.redraw() + obj.Dirty_ = false; + end + + end % onFigureChanged + + function onChildAdded( obj, ~, eventData ) + %onChildAdded Event handler + + % Call template method + obj.addChild( eventData.Child ) + + end % onChildAdded + + function onChildRemoved( obj, ~, eventData ) + %onChildRemoved Event handler + + % Do nothing if container is being deleted + if strcmp( obj.BeingDeleted, 'on' ), return, end + + % Call template method + obj.removeChild( eventData.Child ) + + end % onChildRemoved + + function onSizeChanged( obj, ~, ~ ) + %onSizeChanged Event handler + + % Mark as dirty + obj.Dirty = true; + + end % onSizeChanged + + function onActivePositionPropertyChanged( obj, ~, ~ ) + %onActivePositionPropertyChanged Event handler + + % Mark as dirty + obj.Dirty = true; + + end % onActivePositionPropertyChanged + + end % event handlers + + methods( Abstract, Access = protected ) + + redraw( obj ) + + end % abstract template methods + + methods( Access = protected ) + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Add to contents + obj.Contents_(end+1,:) = child; + + % Add listeners + if isa( child, 'matlab.graphics.axis.Axes' ) + obj.ActivePositionPropertyListeners{end+1,:} = ... + event.proplistener( child, ... + findprop( child, 'ActivePositionProperty' ), ... + 'PostSet', @obj.onActivePositionPropertyChanged ); + else + obj.ActivePositionPropertyListeners{end+1,:} = []; + end + + % Mark as dirty + obj.Dirty = true; + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Remove from contents + contents = obj.Contents_; + tf = contents == child; + obj.Contents_(tf,:) = []; + + % Remove listeners + obj.ActivePositionPropertyListeners(tf,:) = []; + + % Mark as dirty + obj.Dirty = true; + + end % removeChild + + function reparent( obj, oldFigure, newFigure ) %#ok + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + end % reparent + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder contents + obj.Contents_ = obj.Contents_(indices,:); + + % Reorder listeners + obj.ActivePositionPropertyListeners = ... + obj.ActivePositionPropertyListeners(indices,:); + + % Mark as dirty + obj.Dirty = true; + + end % reorder + + function tf = isDrawable( obj ) + %isDrawable Test for drawability + % + % c.isDrawable() is true if the container c is drawable, and + % false otherwise. To be drawable, a container must be + % rooted. + + tf = ~isempty( obj.FigureObserver.Figure ); + + end % isDrawable + + function track( obj ) + %track Track usage + + persistent TRACKED % single shot + if isempty( TRACKED ) + v = ver( 'layout' ); + try %#ok + uix.tracking( 'UA-82270656-2', v(1).Version, class( obj ) ) + end + TRACKED = true; + end + + end % track + + end % template methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/+mixin/Flex.m b/Required packages/layout/+uix/+mixin/Flex.m new file mode 100644 index 0000000..a25229c --- /dev/null +++ b/Required packages/layout/+uix/+mixin/Flex.m @@ -0,0 +1,71 @@ +classdef Flex < handle + %uix.mixin.Flex Flex mixin + % + % uix.mixin.Flex is a mixin class used by flex containers to provide + % various properties and helper methods. + + % Copyright 2016 The MathWorks, Inc. + % $Revision: 1435 $ $Date: 2016-11-17 17:50:34 +0000 (Thu, 17 Nov 2016) $ + + properties( GetAccess = protected, SetAccess = private ) + Pointer = 'unset' % mouse pointer + end + + properties( Access = private ) + Figure = gobjects( 0 ); % mouse pointer figure + Token = -1 % mouse pointer token + end + + methods + + function delete( obj ) + %delete Destructor + + % Clean up + if ~strcmp( obj.Pointer, 'unset' ) + obj.unsetPointer() + end + + end % destructor + + end % structors + + methods( Access = protected ) + + function setPointer( obj, figure, pointer ) + %setPointer Set pointer + % + % c.setPointer(f,p) sets the pointer for the figure f to p. + + % If set, unset + if obj.Token ~= -1 + obj.unsetPointer() + end + + % Set + obj.Token = uix.PointerManager.setPointer( figure, pointer ); + obj.Figure = figure; + obj.Pointer = pointer; + + end % setPointer + + function unsetPointer( obj ) + %unsetPointer Unset pointer + % + % c.unsetPointer() undoes the previous pointer set. + + % Check + assert( obj.Token ~= -1, 'uix:InvalidOperation', ... + 'Pointer is already unset.' ) + + % Unset + uix.PointerManager.unsetPointer( obj.Figure, obj.Token ); + obj.Figure = gobjects( 0 ); + obj.Pointer = 'unset'; + obj.Token = -1; + + end % unsetPointer + + end % helper methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/+mixin/Panel.m b/Required packages/layout/+uix/+mixin/Panel.m new file mode 100644 index 0000000..d2f5ccd --- /dev/null +++ b/Required packages/layout/+uix/+mixin/Panel.m @@ -0,0 +1,188 @@ +classdef Panel < uix.mixin.Container + %uix.mixin.Panel Panel mixin + % + % uix.mixin.Panel is a mixin class used by panels to provide various + % properties and template methods. + + % Copyright 2009-2015 The MathWorks, Inc. + % $Revision: 1435 $ $Date: 2016-11-17 17:50:34 +0000 (Thu, 17 Nov 2016) $ + + properties( Access = public, Dependent, AbortSet ) + Selection % selected contents + end + + properties( Access = protected ) + Selection_ = 0 % backing for Selection + end + + properties( Access = protected ) + G1218142 = false % bug flag + end + + events( NotifyAccess = protected ) + SelectionChanged % selection changed + end + + methods + + function value = get.Selection( obj ) + + value = obj.Selection_; + + end % get.Selection + + function set.Selection( obj, value ) + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Selection'' must be of type double.' ) + assert( isequal( size( value ), [1 1] ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''Selection'' must be scalar.' ) + assert( isreal( value ) && rem( value, 1 ) == 0, ... + 'uix:InvalidPropertyValue', ... + 'Property ''Selection'' must be an integer.' ) + n = numel( obj.Contents_ ); + if n == 0 + assert( value == 0, 'uix:InvalidPropertyValue', ... + 'Property ''Selection'' must be 0 for a container with no children.' ) + else + assert( value >= 1 && value <= n, 'uix:InvalidPropertyValue', ... + 'Property ''Selection'' must be between 1 and the number of children.' ) + end + + % Set + oldSelection = obj.Selection_; + newSelection = value; + obj.Selection_ = newSelection; + + % Show selected child + obj.showSelection() + + % Mark as dirty + obj.Dirty = true; + + % Raise event + notify( obj, 'SelectionChanged', ... + uix.SelectionData( oldSelection, newSelection ) ) + + end % set.Selection + + end % accessors + + methods( Access = protected ) + + function addChild( obj, child ) + + % Check for bug + if verLessThan( 'MATLAB', '8.5' ) && strcmp( child.Visible, 'off' ) + obj.G1218142 = true; + end + + % Select new content + oldSelection = obj.Selection_; + newSelection = numel( obj.Contents_ ) + 1; + obj.Selection_ = newSelection; + + % Call superclass method + addChild@uix.mixin.Container( obj, child ) + + % Show selected child + obj.showSelection() + + % Notify selection change + obj.notify( 'SelectionChanged', ... + uix.SelectionData( oldSelection, newSelection ) ) + + end % addChild + + function removeChild( obj, child ) + + % Adjust selection if required + contents = obj.Contents_; + index = find( contents == child ); + oldSelection = obj.Selection_; + if index < oldSelection + newSelection = oldSelection - 1; + elseif index == oldSelection + newSelection = min( oldSelection, numel( contents ) - 1 ); + else % index > oldSelection + newSelection = oldSelection; + end + obj.Selection_ = newSelection; + + % Call superclass method + removeChild@uix.mixin.Container( obj, child ) + + % Show selected child + obj.showSelection() + + % Notify selection change + if oldSelection ~= newSelection + obj.notify( 'SelectionChanged', ... + uix.SelectionData( oldSelection, newSelection ) ) + end + + end % removeChild + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder + selection = obj.Selection_; + if selection ~= 0 + obj.Selection_ = find( indices == selection ); + end + + % Call superclass method + reorder@uix.mixin.Container( obj, indices ) + + end % reorder + + function showSelection( obj ) + %showSelection Show selected child, hide the others + % + % c.showSelection() shows the selected child of the container + % c, and hides the others. + + % Set positions and visibility + selection = obj.Selection_; + children = obj.Contents_; + for ii = 1:numel( children ) + child = children(ii); + if ii == selection + if obj.G1218142 + warning( 'uix:G1218142', ... + 'Selected child of %s is not visible due to bug G1218142. The child will become visible at the next redraw.', ... + class( obj ) ) + obj.G1218142 = false; + else + child.Visible = 'on'; + end + if isa( child, 'matlab.graphics.axis.Axes' ) + child.ContentsVisible = 'on'; + end + else + child.Visible = 'off'; + if isa( child, 'matlab.graphics.axis.Axes' ) + child.ContentsVisible = 'off'; + end + % As a remedy for g1100294, move off-screen too + margin = 1000; + if isa( child, 'matlab.graphics.axis.Axes' ) ... + && strcmp(child.ActivePositionProperty, 'outerposition' ) + child.OuterPosition(1) = -child.OuterPosition(3)-margin; + else + child.Position(1) = -child.Position(3)-margin; + end + end + end + + end % showSelection + + end % template methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/Box.m b/Required packages/layout/+uix/Box.m new file mode 100644 index 0000000..8cc14dd --- /dev/null +++ b/Required packages/layout/+uix/Box.m @@ -0,0 +1,45 @@ +classdef Box < uix.Container & uix.mixin.Container + %uix.Box Box and grid base class + % + % uix.Box is a base class for containers with spacing between + % contents. + + % Copyright 2009-2015 The MathWorks, Inc. + % $Revision: 1165 $ $Date: 2015-12-06 03:09:17 -0500 (Sun, 06 Dec 2015) $ + + properties( Access = public, Dependent, AbortSet ) + Spacing = 0 % space between contents, in pixels + end + + properties( Access = protected ) + Spacing_ = 0 % backing for Spacing + end + + methods + + function value = get.Spacing( obj ) + + value = obj.Spacing_; + + end % get.Spacing + + function set.Spacing( obj, value ) + + % Check + assert( isa( value, 'double' ) && isscalar( value ) && ... + isreal( value ) && ~isinf( value ) && ... + ~isnan( value ) && value >= 0, ... + 'uix:InvalidPropertyValue', ... + 'Property ''Spacing'' must be a non-negative scalar.' ) + + % Set + obj.Spacing_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Spacing + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/BoxPanel.m b/Required packages/layout/+uix/BoxPanel.m new file mode 100644 index 0000000..0f1b9d1 --- /dev/null +++ b/Required packages/layout/+uix/BoxPanel.m @@ -0,0 +1,551 @@ +classdef BoxPanel < uix.Panel & uix.mixin.Panel + %uix.BoxPanel Box panel + % + % p = uix.BoxPanel(p1,v1,p2,v2,...) constructs a box panel and sets + % parameter p1 to value v1, etc. + % + % A box panel is a decorated container with a title box, border, and + % buttons to dock and undock, minimize, get help, and close. A box + % panel shows one of its contents and hides the others. + % + % See also: uix.Panel, uipanel, uix.CardPanel + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + properties( Dependent ) + TitleColor % title background color [RGB] + Minimized % minimized [true|false] + MinimizeFcn % minimize callback + Docked % docked [true|false] + DockFcn % dock callback + HelpFcn % help callback + CloseRequestFcn % close request callback + end + + properties( Dependent, SetAccess = private ) + TitleHeight % title panel height [pixels] + end + + properties( Access = private ) + TitleBox % title bar box + TitleText % title text label + EmptyTitle = '' % title when empty, [] otherwise + TitleAccess = 'public' % 'private' when getting or setting Title, 'public' otherwise + TitleHeight_ = -1 % cache of title text height (-1 denotes stale cache) + MinimizeButton % title button + DockButton % title button + HelpButton % title button + CloseButton % title button + Docked_ = true % backing for Docked + Minimized_ = false % backing for Minimized + end + + properties( Constant, Access = private ) + NullTitle = char.empty( [2 0] ) % an obscure empty string, the actual panel Title + BlankTitle = ' ' % a non-empty blank string, the empty uicontrol String + end + + methods + + function obj = BoxPanel( varargin ) + %uix.BoxPanel Box panel constructor + % + % p = uix.BoxPanel() constructs a box panel. + % + % p = uix.BoxPanel(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Define default colors + foregroundColor = [1 1 1]; + backgroundColor = [0.05 0.25 0.5]; + + % Set default colors + obj.ForegroundColor = foregroundColor; + + % Create panels and decorations + titleBox = uix.HBox( 'Internal', true, 'Parent', obj, ... + 'Units', 'pixels', 'BackgroundColor', backgroundColor ); + titleText = uix.Text( 'Parent', titleBox, ... + 'ForegroundColor', foregroundColor, ... + 'BackgroundColor', backgroundColor, ... + 'String', obj.BlankTitle, 'HorizontalAlignment', 'left' ); + + % Create buttons + minimizeButton = uix.Text( ... + 'ForegroundColor', foregroundColor, ... + 'BackgroundColor', backgroundColor, ... + 'FontWeight', 'bold', 'Enable', 'on' ); + dockButton = uix.Text( ... + 'ForegroundColor', foregroundColor, ... + 'BackgroundColor', backgroundColor, ... + 'FontWeight', 'bold', 'Enable', 'on' ); + helpButton = uix.Text( ... + 'ForegroundColor', foregroundColor, ... + 'BackgroundColor', backgroundColor, ... + 'FontWeight', 'bold', 'String', '?', ... + 'TooltipString', 'Get help on this panel', 'Enable', 'on' ); + closeButton = uix.Text( ... + 'ForegroundColor', foregroundColor, ... + 'BackgroundColor', backgroundColor, ... + 'FontWeight', 'bold', 'String', char( 215 ), ... + 'TooltipString', 'Close this panel', 'Enable', 'on' ); + + % Store properties + obj.Title = obj.NullTitle; + obj.TitleBox = titleBox; + obj.TitleText = titleText; + obj.MinimizeButton = minimizeButton; + obj.DockButton = dockButton; + obj.HelpButton = helpButton; + obj.CloseButton = closeButton; + + % Create listeners + addlistener( obj, 'BorderWidth', 'PostSet', ... + @obj.onBorderWidthChanged ); + addlistener( obj, 'BorderType', 'PostSet', ... + @obj.onBorderTypeChanged ); + addlistener( obj, 'FontAngle', 'PostSet', ... + @obj.onFontAngleChanged ); + addlistener( obj, 'FontName', 'PostSet', ... + @obj.onFontNameChanged ); + addlistener( obj, 'FontSize', 'PostSet', ... + @obj.onFontSizeChanged ); + addlistener( obj, 'FontUnits', 'PostSet', ... + @obj.onFontUnitsChanged ); + addlistener( obj, 'FontWeight', 'PostSet', ... + @obj.onFontWeightChanged ); + addlistener( obj, 'ForegroundColor', 'PostSet', ... + @obj.onForegroundColorChanged ); + addlistener( obj, 'Title', 'PreGet', ... + @obj.onTitleReturning ); + addlistener( obj, 'Title', 'PostGet', ... + @obj.onTitleReturned ); + addlistener( obj, 'Title', 'PostSet', ... + @obj.onTitleChanged ); + + % Draw buttons + obj.redrawButtons() + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods + + function value = get.TitleColor( obj ) + + value = obj.TitleBox.BackgroundColor; + + end % get.TitleColor + + function set.TitleColor( obj, value ) + + % Set + obj.TitleBox.BackgroundColor = value; + obj.TitleText.BackgroundColor = value; + obj.MinimizeButton.BackgroundColor = value; + obj.DockButton.BackgroundColor = value; + obj.HelpButton.BackgroundColor = value; + obj.CloseButton.BackgroundColor = value; + + end % set.TitleColor + + function value = get.CloseRequestFcn( obj ) + + value = obj.CloseButton.Callback; + + end % get.CloseRequestFcn + + function set.CloseRequestFcn( obj, value ) + + % Set + obj.CloseButton.Callback = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.CloseRequestFcn + + function value = get.DockFcn( obj ) + + value = obj.DockButton.Callback; + + end % get.DockFcn + + function set.DockFcn( obj, value ) + + % Set + obj.DockButton.Callback = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.DockFcn + + function value = get.HelpFcn( obj ) + + value = obj.HelpButton.Callback; + + end % get.HelpFcn + + function set.HelpFcn( obj, value ) + + % Set + obj.HelpButton.Callback = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.HelpFcn + + function value = get.MinimizeFcn( obj ) + + value = obj.MinimizeButton.Callback; + + end % get.MinimizeFcn + + function set.MinimizeFcn( obj, value ) + + % Set + obj.MinimizeButton.Callback = value; + obj.TitleText.Callback = value; + if isempty( value ) + obj.TitleText.Enable = 'inactive'; + else + obj.TitleText.Enable = 'on'; + end + + % Mark as dirty + obj.redrawButtons() + + end % set.MinimizeFcn + + function value = get.Docked( obj ) + + value = obj.Docked_; + + end % get.Docked + + function set.Docked( obj, value ) + + % Check + assert( islogical( value ) && isequal( size( value ), [1 1] ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''Docked'' must be true or false.' ) + + % Set + obj.Docked_ = value; + + % Mark as dirty + obj.redrawButtons() + + end % set.Docked + + function value = get.Minimized( obj ) + + value = obj.Minimized_; + + end % get.Minimized + + function set.Minimized( obj, value ) + + % Check + assert( islogical( value ) && isequal( size( value ), [1 1] ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''Minimized'' must be true or false.' ) + + % Set + obj.Minimized_ = value; + + % Show selected child + obj.showSelection() + + % Mark as dirty + obj.Dirty = true; + + end % set.Minimized + + function value = get.TitleHeight( obj ) + + value = obj.TitleBox.Position(4); + + end % get.TitleHeight + + end % accessors + + methods( Access = private ) + + function onBorderWidthChanged( obj, ~, ~ ) + + % Mark as dirty + obj.Dirty = true; + + end % onBorderWidthChanged + + function onBorderTypeChanged( obj, ~, ~ ) + + % Mark as dirty + obj.Dirty = true; + + end % onBorderTypeChanged + + function onFontAngleChanged( obj, ~, ~ ) + + obj.TitleText.FontAngle = obj.FontAngle; + + end % onFontAngleChanged + + function onFontNameChanged( obj, ~, ~ ) + + % Set + obj.TitleText.FontName = obj.FontName; + + % Mark as dirty + obj.TitleHeight_ = -1; + obj.Dirty = true; + + end % onFontNameChanged + + function onFontSizeChanged( obj, ~, ~ ) + + % Set + fontSize = obj.FontSize; + obj.TitleText.FontSize = fontSize; + obj.HelpButton.FontSize = fontSize; + obj.CloseButton.FontSize = fontSize; + obj.DockButton.FontSize = fontSize; + obj.MinimizeButton.FontSize = fontSize; + + % Mark as dirty + obj.TitleHeight_ = -1; + obj.Dirty = true; + + end % onFontSizeChanged + + function onFontUnitsChanged( obj, ~, ~ ) + + fontUnits = obj.FontUnits; + obj.TitleText.FontUnits = fontUnits; + obj.HelpButton.FontUnits = fontUnits; + obj.CloseButton.FontUnits = fontUnits; + obj.DockButton.FontUnits = fontUnits; + obj.MinimizeButton.FontUnits = fontUnits; + + end % onFontUnitsChanged + + function onFontWeightChanged( obj, ~, ~ ) + + obj.TitleText.FontWeight = obj.FontWeight; + + end % onFontWeightChanged + + function onForegroundColorChanged( obj, ~, ~ ) + + foregroundColor = obj.ForegroundColor; + obj.TitleText.ForegroundColor = foregroundColor; + obj.MinimizeButton.ForegroundColor = foregroundColor; + obj.DockButton.ForegroundColor = foregroundColor; + obj.HelpButton.ForegroundColor = foregroundColor; + obj.CloseButton.ForegroundColor = foregroundColor; + + end % onForegroundColorChanged + + function onTitleReturning( obj, ~, ~ ) + + if strcmp( obj.TitleAccess, 'public' ) + + obj.TitleAccess = 'private'; % start + if ischar( obj.EmptyTitle ) + obj.Title = obj.EmptyTitle; + else + obj.Title = obj.TitleText.String; + end + + end + + end % onTitleReturning + + function onTitleReturned( obj, ~, ~ ) + + obj.Title = obj.NullTitle; % unset Title + obj.TitleAccess = 'public'; % finish + + end % onTitleReturned + + function onTitleChanged( obj, ~, ~ ) + + if strcmp( obj.TitleAccess, 'public' ) + + % Set + obj.TitleAccess = 'private'; % start + title = obj.Title; + if isempty( title ) + obj.EmptyTitle = title; % store + obj.TitleText.String = obj.BlankTitle; % set String to blank + else + obj.EmptyTitle = []; % not empty + obj.TitleText.String = title; % set String to title + end + obj.Title = obj.NullTitle; % unset Title + obj.TitleAccess = 'public'; % finish + + % Mark as dirty + obj.TitleHeight_ = -1; + obj.Dirty = true; + + end + + end % onTitleChanged + + end % property event handlers + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + % + % p.redraw() redraws the panel. + % + % See also: redrawButtons + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + tX = 1; + tW = max( bounds(3), 1 ); + tH = obj.TitleHeight_; % title height + if tH == -1 % cache stale, refresh + tH = ceil( obj.TitleText.Extent(4) ); + obj.TitleHeight_ = tH; % store + end + tY = 1 + bounds(4) - tH; + p = obj.Padding_; + cX = 1 + p; + cW = max( bounds(3) - 2 * p, 1 ); + cH = max( bounds(4) - tH - 2 * p, 1 ); + cY = tY - p - cH; + contentsPosition = [cX cY cW cH]; + + % Redraw contents + selection = obj.Selection_; + if selection ~= 0 + uix.setPosition( obj.Contents_(selection), contentsPosition, 'pixels' ) + end + obj.TitleBox.Position = [tX tY tW tH]; + obj.redrawButtons() + + end % redraw + + function showSelection( obj ) + %showSelection Show selected child, hide the others + % + % c.showSelection() shows the selected child of the container + % c, and hides the others. + + % Call superclass method + showSelection@uix.mixin.Panel( obj ) + + % If minimized, hide selected contents too + selection = obj.Selection_; + if selection ~= 0 && obj.Minimized_ + child = obj.Contents_(selection); + child.Visible = 'off'; + if isa( child, 'matlab.graphics.axis.Axes' ) + child.ContentsVisible = 'off'; + end + % As a remedy for g1100294, move off-screen too + margin = 1000; + if isa( child, 'matlab.graphics.axis.Axes' ) ... + && strcmp(child.ActivePositionProperty, 'outerposition' ) + child.OuterPosition(1) = -child.OuterPosition(3)-margin; + else + child.Position(1) = -child.Position(3)-margin; + end + end + + end % showSelection + + end % template methods + + methods( Access = private ) + + function redrawButtons( obj ) + %redrawButtons Redraw buttons + % + % p.redrawButtons() redraws the titlebar buttons. + % + % Buttons use unicode arrow symbols: + % https://en.wikipedia.org/wiki/Arrow_%28symbol%29#Arrows_in_Unicode + + % Retrieve button box and buttons + box = obj.TitleBox; + titleText = obj.TitleText; + minimizeButton = obj.MinimizeButton; + dockButton = obj.DockButton; + helpButton = obj.HelpButton; + closeButton = obj.CloseButton; + + % Detach all buttons + titleText.Parent = []; + minimizeButton.Parent = []; + dockButton.Parent = []; + helpButton.Parent = []; + closeButton.Parent = []; + + % Attach active buttons + titleText.Parent = box; + minimize = ~isempty( obj.MinimizeFcn ); + if minimize + minimizeButton.Parent = box; + box.Widths(end) = minimizeButton.Extent(3); + end + dock = ~isempty( obj.DockFcn ); + if dock + dockButton.Parent = box; + box.Widths(end) = dockButton.Extent(3); + end + help = ~isempty( obj.HelpFcn ); + if help + helpButton.Parent = box; + box.Widths(end) = helpButton.Extent(3); + end + close = ~isempty( obj.CloseRequestFcn ); + if close + closeButton.Parent = box; + box.Widths(end) = closeButton.Extent(3); + end + + % Update icons + if obj.Minimized_ + minimizeButton.String = char( 9662 ); + minimizeButton.TooltipString = 'Expand this panel'; + else + minimizeButton.String = char( 9652 ); + minimizeButton.TooltipString = 'Collapse this panel'; + end + if obj.Docked_ + dockButton.String = char( 8599 ); + dockButton.TooltipString = 'Undock this panel'; + else + dockButton.String = char( 8600 ); + dockButton.TooltipString = 'Dock this panel'; + end + + end % redrawButtons + + end % helper methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/ButtonBox.m b/Required packages/layout/+uix/ButtonBox.m new file mode 100644 index 0000000..18f13ee --- /dev/null +++ b/Required packages/layout/+uix/ButtonBox.m @@ -0,0 +1,96 @@ +classdef ButtonBox < uix.Box + %uix.ButtonBox Button box base class + % + % uix.ButtonBox is a base class for containers that lay out buttons. + + % Copyright 2009-2015 The MathWorks, Inc. + % $Revision: 1165 $ $Date: 2015-12-06 03:09:17 -0500 (Sun, 06 Dec 2015) $ + + properties( Access = public, Dependent, AbortSet ) + ButtonSize % button size, in pixels + HorizontalAlignment % horizontal alignment [left|center|right] + VerticalAlignment % vertical alignment [top|middle|bottom] + end + + properties( Access = protected ) + ButtonSize_ = [60 20] % backing for ButtonSize + HorizontalAlignment_ = 'center' % backing for HorizontalAlignment + VerticalAlignment_ = 'middle' % backing for VerticalAlignment + end + + methods + + function value = get.ButtonSize( obj ) + + value = obj.ButtonSize_; + + end % get.ButtonSize + + function set.ButtonSize( obj, value ) + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''ButtonSize'' must be of type double.' ) + assert( isequal( size( value ), [1 2] ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''ButtonSize'' must by 1-by-2.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ) && ~any( value <= 0 ), ... + 'uix:InvalidPropertyValue', ... + 'Elements of property ''ButtonSize'' must be real, finite and positive.' ) + + % Set + obj.ButtonSize_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.ButtonSize + + function value = get.HorizontalAlignment( obj ) + + value = obj.HorizontalAlignment_; + + end % get.HorizontalAlignment + + function set.HorizontalAlignment( obj, value ) + + % Check + assert( ischar( value ), 'uix:InvalidPropertyValue', ... + 'Property ''HorizontalAlignment'' must be a string.' ) + assert( any( strcmp( value, {'left';'center';'right'} ) ), ... + 'Property ''HorizontalAlignment'' must be ''left'', ''center'' or ''right''.' ) + + % Set + obj.HorizontalAlignment_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.HorizontalAlignment + + function value = get.VerticalAlignment( obj ) + + value = obj.VerticalAlignment_; + + end % get.VerticalAlignment + + function set.VerticalAlignment( obj, value ) + + % Check + assert( ischar( value ), 'uix:InvalidPropertyValue', ... + 'Property ''VerticalAlignment'' must be a string.' ) + assert( any( strcmp( value, {'top';'middle';'bottom'} ) ), ... + 'Property ''VerticalAlignment'' must be ''top'', ''middle'' or ''bottom''.' ) + + % Set + obj.VerticalAlignment_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.VerticalAlignment + + end % accessors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/CardPanel.m b/Required packages/layout/+uix/CardPanel.m new file mode 100644 index 0000000..fbfd469 --- /dev/null +++ b/Required packages/layout/+uix/CardPanel.m @@ -0,0 +1,64 @@ +classdef CardPanel < uix.Container & uix.mixin.Panel + %uix.CardPanel Card panel + % + % b = uix.CardPanel(p1,v1,p2,v2,...) constructs a card panel and sets + % parameter p1 to value v1, etc. + % + % A card panel is a standard container (uicontainer) that shows one + % its contents and hides the others. + % + % See also: uix.Panel, uix.BoxPanel, uix.TabPanel, uicontainer + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + methods + + function obj = CardPanel( varargin ) + %uix.CardPanel Card panel constructor + % + % p = uix.CardPanel() constructs a card panel. + % + % p = uix.CardPanel(p1,v1,p2,v2,...) sets parameter p1 to + % value v1, etc. + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + padding = obj.Padding_; + xSizes = uix.calcPixelSizes( bounds(3), -1, 1, padding, 0 ); + ySizes = uix.calcPixelSizes( bounds(4), -1, 1, padding, 0 ); + position = [padding+1 padding+1 xSizes ySizes]; + + % Redraw contents + selection = obj.Selection_; + if selection ~= 0 + uix.setPosition( obj.Contents_(selection), position, 'pixels' ) + end + + end % redraw + + end % template methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/ChildEvent.m b/Required packages/layout/+uix/ChildEvent.m new file mode 100644 index 0000000..e4a7e24 --- /dev/null +++ b/Required packages/layout/+uix/ChildEvent.m @@ -0,0 +1,28 @@ +classdef( Hidden, Sealed ) ChildEvent < event.EventData + %uix.ChildEvent Event data for child event + % + % e = uix.ChildEvent(c) creates event data including the child c. + + % Copyright 2009-2015 The MathWorks, Inc. + % $Revision: 1165 $ $Date: 2015-12-06 03:09:17 -0500 (Sun, 06 Dec 2015) $ + + properties( SetAccess = private ) + Child % child + end + + methods + + function obj = ChildEvent( child ) + %uix.ChildEvent Event data for child event + % + % e = uix.ChildEvent(c) creates event data including the child + % c. + + % Set properties + obj.Child = child; + + end % constructor + + end % structors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/ChildObserver.m b/Required packages/layout/+uix/ChildObserver.m new file mode 100644 index 0000000..a01e34f --- /dev/null +++ b/Required packages/layout/+uix/ChildObserver.m @@ -0,0 +1,220 @@ +classdef ( Hidden, Sealed ) ChildObserver < handle + %uix.ChildObserver Child observer + % + % co = uix.ChildObserver(o) creates a child observer for the graphics + % object o. A child observer raises events when objects are added to + % and removed from the property Children of o. + % + % See also: uix.Node + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + properties( Access = private ) + Root % root node + end + + events( NotifyAccess = private ) + ChildAdded % child added + ChildRemoved % child removed + end + + methods + + function obj = ChildObserver( oRoot ) + %uix.ChildObserver Child observer + % + % co = uix.ChildObserver(o) creates a child observer for the + % graphics object o. A child observer raises events when + % objects are added to and removed from the property Children + % of o. + + % Check + assert( iscontent( oRoot ) && ... + isequal( size( oRoot ), [1 1] ), 'uix.InvalidArgument', ... + 'Object must be a graphics object.' ) + + % Create root node + nRoot = uix.Node( oRoot ); + childAddedListener = event.listener( oRoot, ... + 'ObjectChildAdded', ... + @(~,e)obj.addChild(nRoot,e.Child) ); + childAddedListener.Recursive = true; + nRoot.addprop( 'ChildAddedListener' ); + nRoot.ChildAddedListener = childAddedListener; + childRemovedListener = event.listener( oRoot, ... + 'ObjectChildRemoved', ... + @(~,e)obj.removeChild(nRoot,e.Child) ); + childRemovedListener.Recursive = true; + nRoot.addprop( 'ChildRemovedListener' ); + nRoot.ChildRemovedListener = childRemovedListener; + + % Add children + oChildren = hgGetTrueChildren( oRoot ); + for ii = 1:numel( oChildren ) + obj.addChild( nRoot, oChildren(ii) ) + end + + % Store properties + obj.Root = nRoot; + + end % constructor + + end % structors + + methods( Access = private ) + + function addChild( obj, nParent, oChild ) + %addChild Add child object to parent node + % + % co.addChild(np,oc) adds the child object oc to the parent + % node np, either as part of construction of the child + % observer co, or in response to an ObjectChildAdded event on + % an object of interest to co. This may lead to ChildAdded + % events being raised on co. + + % Create child node + nChild = uix.Node( oChild ); + nParent.addChild( nChild ) + if iscontent( oChild ) + % Add Internal PreSet property listener + internalPreSetListener = event.proplistener( oChild, ... + findprop( oChild, 'Internal' ), 'PreSet', ... + @(~,~)obj.preSetInternal(nChild) ); + nChild.addprop( 'InternalPreSetListener' ); + nChild.InternalPreSetListener = internalPreSetListener; + % Add Internal PostSet property listener + internalPostSetListener = event.proplistener( oChild, ... + findprop( oChild, 'Internal' ), 'PostSet', ... + @(~,~)obj.postSetInternal(nChild) ); + nChild.addprop( 'InternalPostSetListener' ); + nChild.InternalPostSetListener = internalPostSetListener; + else + % Add ObjectChildAdded listener + childAddedListener = event.listener( oChild, ... + 'ObjectChildAdded', ... + @(~,e)obj.addChild(nChild,e.Child) ); + nChild.addprop( 'ChildAddedListener' ); + nChild.ChildAddedListener = childAddedListener; + % Add ObjectChildRemoved listener + childRemovedListener = event.listener( oChild, ... + 'ObjectChildRemoved', ... + @(~,e)obj.removeChild(nChild,e.Child) ); + nChild.addprop( 'ChildRemovedListener' ); + nChild.ChildRemovedListener = childRemovedListener; + end + + % Raise ChildAdded event + if iscontent( oChild ) && oChild.Internal == false + notify( obj, 'ChildAdded', uix.ChildEvent( oChild ) ) + end + + % Add grandchildren + if ~iscontent( oChild ) + oGrandchildren = hgGetTrueChildren( oChild ); + for ii = 1:numel( oGrandchildren ) + obj.addChild( nChild, oGrandchildren(ii) ) + end + end + + end % addChild + + function removeChild( obj, nParent, oChild ) + %removeChild Remove child object from parent node + % + % co.removeChild(np,oc) removes the child object oc from the + % parent node np, in response to an ObjectChildRemoved event + % on an object of interest to co. This may lead to + % ChildRemoved events being raised on co. + + % Get child node + nChildren = nParent.Children; + tf = oChild == [nChildren.Object]; + nChild = nChildren(tf); + + % Raise ChildRemoved event(s) + notifyChildRemoved( nChild ) + + % Delete child node + delete( nChild ) + + function notifyChildRemoved( nc ) + + % Process child nodes + ngc = nc.Children; + for ii = 1:numel( ngc ) + notifyChildRemoved( ngc(ii) ) + end + + % Process this node + oc = nc.Object; + if iscontent( oc ) && oc.Internal == false + notify( obj, 'ChildRemoved', uix.ChildEvent( oc ) ) + end + + end % notifyChildRemoved + + end % removeChild + + function preSetInternal( ~, nChild ) + %preSetInternal Perform property PreSet tasks + % + % co.preSetInternal(n) caches the previous value of the + % property Internal of the object referenced by the node n, to + % enable PostSet tasks to identify whether the value changed. + % This is necessary since Internal AbortSet is false. + + oldInternal = nChild.Object.Internal; + nChild.addprop( 'OldInternal' ); + nChild.OldInternal = oldInternal; + + end % preSetInternal + + function postSetInternal( obj, nChild ) + %postSetInternal Perform property PostSet tasks + % + % co.postSetInternal(n) raises a ChildAdded or ChildRemoved + % event on the child observer co in response to a change of + % the value of the property Internal of the object referenced + % by the node n. + + % Retrieve old and new values + oChild = nChild.Object; + newInternal = oChild.Internal; + oldInternal = nChild.OldInternal; + + % Clean up node + delete( findprop( nChild, 'OldInternal' ) ) + + % Raise event + switch newInternal + case oldInternal % no change + % no event + case true % false to true + notify( obj, 'ChildRemoved', uix.ChildEvent( oChild ) ) + case false % true to false + notify( obj, 'ChildAdded', uix.ChildEvent( oChild ) ) + end + + end % postSetInternal + + end % event handlers + +end % classdef + +function tf = iscontent( o ) +%iscontent True for graphics that can be Contents (and can be Children) +% +% uix.ChildObserver needs to determine which objects can be Contents, +% which is equivalent to can be Children if HandleVisibility is 'on' and +% Internal is false. Prior to R2016a, this condition could be checked +% using isgraphics. From R2016a, isgraphics returns true for a wider +% range of objects, including some that can never by Contents, e.g., +% JavaCanvas. Therefore this function checks whether an object is of type +% matlab.graphics.internal.GraphicsBaseFunctions, which is what isgraphics +% did prior to R2016a. + +tf = isa( o, 'matlab.graphics.internal.GraphicsBaseFunctions' ) &&... + isprop( o, 'Position' ); + +end % iscontent \ No newline at end of file diff --git a/Required packages/layout/+uix/Container.m b/Required packages/layout/+uix/Container.m new file mode 100644 index 0000000..1650685 --- /dev/null +++ b/Required packages/layout/+uix/Container.m @@ -0,0 +1,9 @@ +classdef Container < matlab.ui.container.internal.UIContainer + %uix.Container Container base class + % + % uix.Container is base class for containers that extend uicontainer. + + % Copyright 2009-2015 The MathWorks, Inc. + % $Revision: 1137 $ $Date: 2015-05-29 21:48:21 +0100 (Fri, 29 May 2015) $ + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/Divider.m b/Required packages/layout/+uix/Divider.m new file mode 100644 index 0000000..f846948 --- /dev/null +++ b/Required packages/layout/+uix/Divider.m @@ -0,0 +1,344 @@ +classdef Divider < matlab.mixin.SetGet + %uix.Divider Draggable divider + % + % d = uix.Divider() creates a divider. + % + % d = uix.Divider(p1,v1,p2,v2,...) creates a divider and sets + % specified property p1 to value v1, etc. + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + properties( Dependent ) + Parent % parent + Units % units [inches|centimeters|characters|normalized|points|pixels] + Position % position + Visible % visible [on|off] + BackgroundColor % background color [RGB] + HighlightColor % border highlight color [RGB] + ShadowColor % border shadow color [RGB] + Orientation % orientation [vertical|horizontal] + Markings % markings [pixels] + end + + properties( Access = private ) + Control % uicontrol + BackgroundColor_ = get( 0, 'DefaultUicontrolBackgroundColor' ) % backing for BackgroundColor + HighlightColor_ = [1 1 1] % backing for HighlightColor + ShadowColor_ = [0.7 0.7 0.7] % backing for ShadowColor + Orientation_ = 'vertical' % backing for Orientation + Markings_ = zeros( [0 1] ) % backing for Markings + SizeChangedListener % listener + end + + methods + + function obj = Divider( varargin ) + %uix.Divider Draggable divider + % + % d = uix.Divider() creates a divider. + % + % d = uix.Divider(p1,v1,p2,v2,...) creates a dividerand sets + % specified property p1 to value v1, etc. + + % Create control + control = matlab.ui.control.UIControl( ... + 'Style', 'checkbox', 'Internal', true, ... + 'Enable', 'inactive', 'DeleteFcn', @obj.onDeleted,... + 'Tag', 'uix.Divider' ); + + % Store control + obj.Control = control; + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + % Force update + obj.update() + + % Create listener + sizeChangedListener = event.listener( control, 'SizeChanged', ... + @obj.onSizeChanged ); + + % Store listener + obj.SizeChangedListener = sizeChangedListener; + + end % constructor + + function delete( obj ) + %delete Destructor + + control = obj.Control; + if isgraphics( control ) && strcmp( control.BeingDeleted, 'off' ) + delete( control ) + end + + end % destructor + + end % structors + + methods + + function value = get.Parent( obj ) + + value = obj.Control.Parent; + + end % get.Parent + + function set.Parent( obj, value ) + + obj.Control.Parent = value; + + end % set.Parent + + function value = get.Units( obj ) + + value = obj.Control.Units; + + end % get.Units + + function set.Units( obj, value ) + + obj.Control.Units = value; + + end % set.Units + + function value = get.Position( obj ) + + value = obj.Control.Position; + + end % get.Position + + function set.Position( obj, value ) + + obj.Control.Position = value; + + end % set.Position + + function value = get.Visible( obj ) + + value = obj.Control.Visible; + + end % get.Visible + + function set.Visible( obj, value ) + + obj.Control.Visible = value; + + end % set.Visible + + function value = get.BackgroundColor( obj ) + + value = obj.BackgroundColor_; + + end % get.BackgroundColor + + function set.BackgroundColor( obj, value ) + + % Check + assert( isa( value, 'double' ) && ... + isequal( size( value ), [1 3] ) && ... + all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidArgument', ... + 'Property ''BackgroundColor'' must be a valid colorspec.' ) + + % Set + obj.BackgroundColor_ = value; + + % Update + obj.update() + + end % set.BackgroundColor + + function value = get.HighlightColor( obj ) + + value = obj.HighlightColor_; + + end % get.HighlightColor + + function set.HighlightColor( obj, value ) + + % Check + assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ... + all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''HighlightColor'' must be an RGB triple.' ) + + % Set + obj.HighlightColor_ = value; + + % Update + obj.update() + + end % set.HighlightColor + + function value = get.ShadowColor( obj ) + + value = obj.ShadowColor_; + + end % get.ShadowColor + + function set.ShadowColor( obj, value ) + + % Check + assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ... + all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''ShadowColor'' must be an RGB triple.' ) + + % Set + obj.ShadowColor_ = value; + + % Update + obj.update() + + end % set.ShadowColor + + function value = get.Orientation( obj ) + + value = obj.Orientation_; + + end % get.Orientation + + function set.Orientation( obj, value ) + + % Check + assert( ischar( value ) && ismember( value, ... + {'horizontal','vertical'} ) ) + + % Set + obj.Orientation_ = value; + + % Update + obj.update() + + end % set.Orientation + + function value = get.Markings( obj ) + + value = obj.Markings_; + + end % get.Markings + + function set.Markings( obj, value ) + + % Check + assert( isa( value, 'double' ) && ndims( value ) == 2 && ... + size( value, 2 ) == 1 && all( isreal( value ) ) && ... + all( ~isinf( value ) ) && all( ~isnan( value ) ) && ... + all( value > 0 ), 'uix:InvalidPropertyValue', ... + 'Property ''Markings'' must be a vector of positive values.' ) %#ok + + % Set + obj.Markings_ = value; + + % Update + obj.update() + + end % set.Markings + + end % accessors + + methods + + function tf = isMouseOver( obj, eventData ) + %isMouseOver Test for mouse over + % + % tf = d.isMouseOver(wmd) tests whether the WindowMouseData + % wmd is consistent with the mouse pointer being over the + % divider d. + + tf = reshape( [obj.Control] == eventData.HitObject, size( obj ) ); + + end % isMouseOver + + end % methods + + methods( Access = private ) + + function onDeleted( obj, ~, ~ ) + %onDeleted Event handler + + % Call destructor + obj.delete() + + end % onDeleted + + function onSizeChanged( obj, ~, ~ ) + %onSizeChanged Event handler + + % Update + obj.update() + + end % onSizeChanged + + end % event handlers + + methods( Access = private ) + + function update( obj ) + %update Update divider + % + % d.update() updates the divider markings. + + % Get properties + control = obj.Control; + position = control.Position; + backgroundColor = obj.BackgroundColor; + highlightColor = obj.HighlightColor; + shadowColor = obj.ShadowColor; + orientation = obj.Orientation; + markings = obj.Markings; + + % Assemble mask + mask = zeros( floor( position([4 3]) ) - [1 1] ); % initialize + switch orientation + case 'vertical' + markings(markings < 4) = []; + markings(markings > position(4)-6) = []; + for ii = 1:numel( markings ) + marking = markings(ii); + mask(floor( marking ) + [-3 0 3],1:end-1) = 1; + mask(floor( marking ) + [-2 1 4],1:end-1) = 2; + end + case 'horizontal' + markings(markings < 4) = []; + markings(markings > position(3)-6) = []; + for ii = 1:numel( markings ) + marking = markings(ii); + mask(2:end,floor( marking ) + [-3 0 3]) = 1; + mask(2:end,floor( marking ) + [-2 1 4]) = 2; + end + end + + % Assemble color data + cData1 = repmat( backgroundColor(1), size( mask ) ); + cData1(mask==1) = highlightColor(1); + cData1(mask==2) = shadowColor(1); + cData2 = repmat( backgroundColor(2), size( mask ) ); + cData2(mask==1) = highlightColor(2); + cData2(mask==2) = shadowColor(2); + cData3 = repmat( backgroundColor(3), size( mask ) ); + cData3(mask==1) = highlightColor(3); + cData3(mask==2) = shadowColor(3); + cData = cat( 3, cData1, cData2, cData3 ); + + % Set properties + control.ForegroundColor = backgroundColor; + control.BackgroundColor = backgroundColor; + control.CData = cData; + + end % update + + end % methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/Empty.m b/Required packages/layout/+uix/Empty.m new file mode 100644 index 0000000..e9b36f8 --- /dev/null +++ b/Required packages/layout/+uix/Empty.m @@ -0,0 +1,102 @@ +function obj = Empty( varargin ) +%uix.Empty Create an empty space +% +% obj = uix.Empty() creates an empty space that can be used to add gaps +% between elements in layouts. +% +% obj = uix.Empty(param,value,...) also sets one or more property +% values. +% +% See the documentation for more detail and the list of properties. +% +% Examples: +% >> f = figure(); +% >> box = uix.HBox( 'Parent', f ); +% >> uicontrol( 'Parent', box, 'Background', 'r' ) +% >> uix.Empty( 'Parent', box ) +% >> uicontrol( 'Parent', box, 'Background', 'b' ) + +% Copyright 2009-2016 The MathWorks, Inc. +% $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + +% Create uicontainer +obj = matlab.ui.container.internal.UIContainer( 'Tag', 'empty', varargin{:} ); + +% Create property for Parent listener +p = addprop( obj, 'ParentListener' ); +p.Hidden = true; + +% Create Parent listener +obj.ParentListener = event.proplistener( obj, ... + findprop( obj, 'Parent' ), 'PostSet', @(~,~)onParentChanged(obj) ); + +% Create property for Parent color listener +p = addprop( obj, 'ParentColorListener' ); +p.Hidden = true; + +% Initialize color and listener +updateColor( obj ) +updateListener( obj ) + +end % uix.Empty + +function onParentChanged( obj ) +%onParentColorChanged Event handler + +% Update color and listener +updateColor( obj ) +updateListener( obj ) + +end % onParentChanged + +function onParentColorChanged( obj ) +%onParentColorChanged Event handler + +% Update color +updateColor( obj ) + +end % onParentColorChanged + +function name = getColorProperty( obj ) +%getColorProperty Get color property + +names = {'Color','BackgroundColor'}; % possible names +for ii = 1:numel( names ) % loop over possible names + name = names{ii}; + if isprop( obj, name ) + return + end +end +error( 'Cannot find color property for %s.', class( obj ) ) + +end % getColorProperty + +function updateColor( obj ) +%updateColor Set uicontainer BackgroundColor to match Parent + +parent = obj.Parent; +if isempty( parent ), return, end +property = getColorProperty( parent ); +color = parent.( property ); +try + obj.BackgroundColor = color; +catch e + warning( e.identifier, e.message ) % rethrow as warning +end + +end % updateColor + +function updateListener( obj ) +%updateListener Create listener to parent color property + +parent = obj.Parent; +if isempty( parent ) + obj.ParentColorListener = []; +else + property = getColorProperty( parent ); + obj.ParentColorListener = event.proplistener( parent, ... + findprop( parent, property ), 'PostSet', ... + @(~,~)onParentColorChanged(obj) ); +end + +end % updateListener \ No newline at end of file diff --git a/Required packages/layout/+uix/FigureData.m b/Required packages/layout/+uix/FigureData.m new file mode 100644 index 0000000..0db2249 --- /dev/null +++ b/Required packages/layout/+uix/FigureData.m @@ -0,0 +1,26 @@ +classdef ( Hidden, Sealed ) FigureData < event.EventData + %uix.FigureData Event data for FigureChanged on uix.FigureObserver + + % Copyright 2014-2015 The MathWorks, Inc. + % $Revision: 1435 $ $Date: 2016-11-17 17:50:34 +0000 (Thu, 17 Nov 2016) $ + + properties( SetAccess = private ) + OldFigure % old figure + NewFigure % new figure + end + + methods( Access = ?uix.FigureObserver ) + + function obj = FigureData( oldFigure, newFigure ) + %uix.FigureData Create event data + % + % d = uix.FigureData(oldFigure,newFigure) + + obj.OldFigure = oldFigure; + obj.NewFigure = newFigure; + + end % constructor + + end % methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/FigureObserver.m b/Required packages/layout/+uix/FigureObserver.m new file mode 100644 index 0000000..644edfd --- /dev/null +++ b/Required packages/layout/+uix/FigureObserver.m @@ -0,0 +1,98 @@ +classdef ( Hidden, Sealed ) FigureObserver < handle + %uix.FigureObserver Figure observer + % + % A figure observer raises an event FigureChanged when the figure + % ancestor of a subject changes. + + % Copyright 2014-2015 The MathWorks, Inc. + % $Revision: 1435 $ $Date: 2016-11-17 17:50:34 +0000 (Thu, 17 Nov 2016) $ + + properties( SetAccess = private ) + Subject % subject + Figure % figure ancestor + end + + properties( Access = private ) + PreSetListeners % listeners to Parent PreGet + PostSetListeners % listeners to Parent PreGet + OldFigure = gobjects( 0 ) % previous figure ancestor + end + + events( NotifyAccess = private ) + FigureChanged + end + + methods + + function obj = FigureObserver( subject ) + %uix.FigureObserver Create figure observer + % + % o = uix.FigureObserver(s) creates a figure observer for the + % subject s. + + % Check + validateattributes( subject, {'matlab.graphics.Graphics'}, ... + {'scalar'}, '', 'subject' ) + + % Store subject + obj.Subject = subject; + + % Set up object + obj.update() + + end % constructor + + end % structors + + methods( Access = private ) + + function update( obj ) + %update Update listeners and Figure property + + % Create fresh listeners + obj.PreSetListeners = event.proplistener.empty( [1 0] ); % clear + obj.PostSetListeners = event.proplistener.empty( [1 0] ); % clear + o = obj.Subject; + while ~isempty( o ) && ~isa( o, 'matlab.ui.Figure' ) + obj.PreSetListeners(end+1) = event.proplistener( o, ... + findprop( o, 'Parent' ), 'PreSet', @obj.onParentPreSet ); + obj.PostSetListeners(end+1) = event.proplistener( o, ... + findprop( o, 'Parent' ), 'PostSet', @obj.onParentPostSet ); + o = o.Parent; + end + + % Store figure + obj.Figure = o; + + end % update + + function onParentPreSet( obj, ~, ~ ) + %onParentPreSet Event handler + + % Store old figure + obj.OldFigure = obj.Figure; + + end % onParentPreSet + + function onParentPostSet( obj, ~, ~ ) + %onParentPostSet Event handler + + % Update object + obj.update() + + % Raise event + oldFigure = obj.OldFigure; + newFigure = obj.Figure; + if ~isequal( oldFigure, newFigure ) + notify( obj, 'FigureChanged', ... + uix.FigureData( oldFigure, newFigure ) ) + end + + % Clear old figure + obj.OldFigure = gobjects( 0 ); + + end % onParentPostSet + + end % private methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/Grid.m b/Required packages/layout/+uix/Grid.m new file mode 100644 index 0000000..e63b06a --- /dev/null +++ b/Required packages/layout/+uix/Grid.m @@ -0,0 +1,321 @@ +classdef Grid < uix.Box + %uix.Grid Grid + % + % b = uix.Grid(p1,v1,p2,v2,...) constructs a grid and sets parameter + % p1 to value v1, etc. + % + % A grid lays out contents from top to bottom and left to right. + % + % See also: uix.HBox, uix.VBox, uix.GridFlex + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + properties( Access = public, Dependent, AbortSet ) + Widths % widths of contents, in pixels and/or weights + MinimumWidths % minimum widths of contents, in pixels + Heights % heights of contents, in pixels and/or weights + MinimumHeights % minimum heights of contents, in pixels + end + + properties( Access = protected ) + Widths_ = zeros( [0 1] ) % backing for Widths + MinimumWidths_ = zeros( [0 1] ) % backing for MinimumWidths + Heights_ = zeros( [0 1] ) % backing for Heights + MinimumHeights_ = zeros( [0 1] ) % backing for MinimumHeights + end + + methods + + function obj = Grid( varargin ) + %uix.Grid Grid constructor + % + % b = uix.Grid() constructs a grid. + % + % b = uix.Grid(p1,v1,p2,v2,...) sets parameter p1 to value v1, + % etc. + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods + + function value = get.Widths( obj ) + + value = obj.Widths_; + + end % get.Widths + + function set.Widths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Widths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Widths'' must be real and finite.' ) + n = numel( obj.Contents_ ); + b = numel( obj.Widths_ ); + q = numel( obj.Heights_ ); + c = numel( value ); + r = ceil( n / c ); + if c < min( [1 n] ) + error( 'uix:InvalidPropertyValue' , ... + 'Property ''Widths'' must be non-empty for non-empty contents.' ) + elseif ceil( n / r ) < c + error( 'uix:InvalidPropertyValue' , ... + 'Size of property ''Widths'' must not lead to empty columns.' ) + elseif c > n + error( 'uix:InvalidPropertyValue' , ... + 'Size of property ''Widths'' must be no larger than size of contents.' ) + end + + % Set + obj.Widths_ = value; + if c < b % number of columns decreasing + obj.MinimumWidths_(c+1:end,:) = []; + if r > q % number of rows increasing + obj.Heights_(end+1:r,:) = -1; + obj.MinimumHeights_(end+1:r,:) = 1; + end + elseif c > b % number of columns increasing + obj.MinimumWidths_(end+1:c,:) = -1; + if r < q % number of rows decreasing + obj.Heights_(r+1:end,:) = []; + obj.MinimumHeights_(r+1:end,:) = []; + end + end + + % Mark as dirty + obj.Dirty = true; + + end % set.Widths + + function value = get.MinimumWidths( obj ) + + value = obj.MinimumWidths_; + + end % get.MinimumWidths + + function set.MinimumWidths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumWidths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumWidths'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Widths_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumWidths'' must match size of contents.' ) + + % Set + obj.MinimumWidths_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumWidths + + function value = get.Heights( obj ) + + value = obj.Heights_; + + end % get.Heights + + function set.Heights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Heights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Heights'' must be real and finite.' ) + n = numel( obj.Contents_ ); + b = numel( obj.Widths_ ); + q = numel( obj.Heights_ ); + r = numel( value ); + c = ceil( n / r ); + if r < min( [1 n] ) + error( 'uix:InvalidPropertyValue' , ... + 'Property ''Heights'' must be non-empty for non-empty contents.' ) + elseif r > n + error( 'uix:InvalidPropertyValue' , ... + 'Size of property ''Heights'' must be no larger than size of contents.' ) + end + + % Set + obj.Heights_ = value; + if r < q % number of rows decreasing + obj.MinimumHeights_(r+1:end,:) = []; + if c > b % number of columns increasing + obj.Widths_(end+1:c,:) = -1; + obj.MinimumWidths_(end+1:c,:) = 1; + end + elseif r > q % number of rows increasing + obj.MinimumHeights_(end+1:r,:) = 1; + if c < b % number of columns decreasing + obj.Widths_(c+1:end,:) = []; + obj.MinimumWidths_(c+1:end,:) = []; + end + end + + % Mark as dirty + obj.Dirty = true; + + end % set.Heights + + function value = get.MinimumHeights( obj ) + + value = obj.MinimumHeights_; + + end % get.MinimumHeights + + function set.MinimumHeights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumHeights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumHeights'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Heights_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumHeights'' must match size of contents.' ) + + % Set + obj.MinimumHeights_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumHeights + + end % accessors + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + % + % c.redraw() redraws the container c. + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + widths = obj.Widths_; + minimumWidths = obj.MinimumWidths_; + heights = obj.Heights_; + minimumHeights = obj.MinimumHeights_; + padding = obj.Padding_; + spacing = obj.Spacing_; + c = numel( widths ); + r = numel( heights ); + n = numel( obj.Contents_ ); + xSizes = uix.calcPixelSizes( bounds(3), widths, ... + minimumWidths, padding, spacing ); + xPositions = [cumsum( [0; xSizes(1:end-1,:)] ) + padding + ... + spacing * transpose( 0:c-1 ) + 1, xSizes]; + ySizes = uix.calcPixelSizes( bounds(4), heights, ... + minimumHeights, padding, spacing ); + yPositions = [bounds(4) - cumsum( ySizes ) - padding - ... + spacing * transpose( 0:r-1 ) + 1, ySizes]; + [iy, ix] = ind2sub( [r c], transpose( 1:n ) ); + positions = [xPositions(ix,1), yPositions(iy,1), ... + xPositions(ix,2), yPositions(iy,2)]; + + % Set positions + children = obj.Contents_; + for ii = 1:numel( children ) + uix.setPosition( children(ii), positions(ii,:), 'pixels' ) + end + + end % redraw + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Add column and even a row if necessary + n = numel( obj.Contents_ ); + c = numel( obj.Widths_ ); + r = numel( obj.Heights_ ); + if n == 0 + obj.Widths_(end+1,:) = -1; + obj.MinimumWidths_(end+1,:) = 1; + obj.Heights_(end+1,:) = -1; + obj.MinimumHeights_(end+1,:) = 1; + elseif ceil( (n+1)/r ) > c + obj.Widths_(end+1,:) = -1; + obj.MinimumWidths_(end+1,:) = 1; + end + + % Call superclass method + addChild@uix.Box( obj, child ) + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Remove column and even row if necessary + n = numel( obj.Contents_ ); + c = numel( obj.Widths_ ); + r = numel( obj.Heights_ ); + if n == 1 + obj.Widths_(end,:) = []; + obj.MinimumWidths_(end,:) = []; + obj.Heights_(end,:) = []; + obj.MinimumHeights_(end,:) = []; + elseif c == 1 + obj.Heights_(end,:) = []; + obj.MinimumHeights_(end,:) = []; + elseif ceil( (n-1)/r ) < c + obj.Widths_(end,:) = []; + obj.MinimumWidths_(end,:) = []; + end + + % Call superclass method + removeChild@uix.Box( obj, child ) + + end % removeChild + + end % template methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/GridFlex.m b/Required packages/layout/+uix/GridFlex.m new file mode 100644 index 0000000..00bdc6a --- /dev/null +++ b/Required packages/layout/+uix/GridFlex.m @@ -0,0 +1,467 @@ +classdef GridFlex < uix.Grid & uix.mixin.Flex + %uix.GridFlex Flexible grid + % + % b = uix.GridFlex(p1,v1,p2,v2,...) constructs a flexible grid and + % sets parameter p1 to value v1, etc. + % + % A grid lays out contents from top to bottom and left to right. + % Users can resize contents by dragging the dividers. + % + % See also: uix.HBoxFlex, uix.VBoxFlex, uix.Grid + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + properties( Access = public, Dependent, AbortSet ) + DividerMarkings % divider markings [on|off] + end + + properties( Access = private ) + RowDividers = uix.Divider.empty( [0 1] ) + ColumnDividers = uix.Divider.empty( [0 1] ) + FrontDivider % front divider + DividerMarkings_ = 'on' % backing for DividerMarkings + MousePressListener = event.listener.empty( [0 0] ) % mouse press listener + MouseReleaseListener = event.listener.empty( [0 0] ) % mouse release listener + MouseMotionListener = event.listener.empty( [0 0] ) % mouse motion listener + ActiveDivider = 0 % active divider index + ActiveDividerPosition = [NaN NaN NaN NaN] % active divider position + MousePressLocation = [NaN NaN] % mouse press location + BackgroundColorListener % background color listener + end + + methods + + function obj = GridFlex( varargin ) + %uix.GridFlex Flexible grid constructor + % + % b = uix.GridFlex() constructs a flexible grid. + % + % b = uix.GridFlex(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Create front divider + frontDivider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'vertical', ... + 'BackgroundColor', obj.BackgroundColor * 0.75, ... + 'Visible', 'off' ); + + % Create listeners + backgroundColorListener = event.proplistener( obj, ... + findprop( obj, 'BackgroundColor' ), 'PostSet', ... + @obj.onBackgroundColorChange ); + + % Store properties + obj.FrontDivider = frontDivider; + obj.BackgroundColorListener = backgroundColorListener; + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods + + function value = get.DividerMarkings( obj ) + + value = obj.DividerMarkings_; + + end % get.DividerMarkings + + function set.DividerMarkings( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uix:InvalidArgument', ... + 'Property ''DividerMarkings'' must be ''on'' or ''off'.' ) + + % Set + obj.DividerMarkings_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.DividerMarkings + + end % accessors + + methods( Access = protected ) + + function onMousePress( obj, source, eventData ) + %onMousePress Handler for WindowMousePress events + + % Check whether mouse is over a divider + locr = find( obj.RowDividers.isMouseOver( eventData ) ); + locc = find( obj.ColumnDividers.isMouseOver( eventData ) ); + if ~isempty( locr ) + loc = locr; + divider = obj.RowDividers(locr); + elseif ~isempty( locc ) + loc = -locc; + divider = obj.ColumnDividers(locc); + else + return + end + + % Capture state at button down + obj.ActiveDivider = loc; + obj.ActiveDividerPosition = divider.Position; + root = groot(); + obj.MousePressLocation = root.PointerLocation; + + % Make sure the pointer is appropriate + obj.updateMousePointer( source, eventData ); + + % Activate divider + frontDivider = obj.FrontDivider; + frontDivider.Position = divider.Position; + frontDivider.Orientation = divider.Orientation; + divider.Visible = 'off'; + frontDivider.Parent = []; + frontDivider.Parent = obj; + frontDivider.Visible = 'on'; + + end % onMousePress + + function onMouseRelease( obj, ~, ~ ) + %onMousePress Handler for WindowMouseRelease events + + % Compute new positions + loc = obj.ActiveDivider; + if loc > 0 + root = groot(); + delta = root.PointerLocation(2) - obj.MousePressLocation(2); + ih = loc; + jh = loc + 1; + ic = loc; + jc = loc + 1; + divider = obj.RowDividers(loc); + contents = obj.Contents_; + oldPixelHeights = [contents(ic).Position(4); contents(jc).Position(4)]; + minimumHeights = obj.MinimumHeights_(ih:jh,:); + if delta < 0 % limit to minimum distance from lower neighbor + delta = max( delta, minimumHeights(2) - oldPixelHeights(2) ); + else % limit to minimum distance from upper neighbor + delta = min( delta, oldPixelHeights(1) - minimumHeights(1) ); + end + oldHeights = obj.Heights_(loc:loc+1); + newPixelHeights = oldPixelHeights - delta * [1;-1]; + if oldHeights(1) < 0 && oldHeights(2) < 0 % weight, weight + newHeights = oldHeights .* newPixelHeights ./ oldPixelHeights; + elseif oldHeights(1) < 0 && oldHeights(2) >= 0 % weight, pixels + newHeights = [oldHeights(1) * newPixelHeights(1) / ... + oldPixelHeights(1); newPixelHeights(2)]; + elseif oldHeights(1) >= 0 && oldHeights(2) < 0 % pixels, weight + newHeights = [newPixelHeights(1); oldHeights(2) * ... + newPixelHeights(2) / oldPixelHeights(2)]; + else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels + newHeights = newPixelHeights; + end + obj.Heights_(loc:loc+1) = newHeights; + elseif loc < 0 + root = groot(); + delta = root.PointerLocation(1) - obj.MousePressLocation(1); + iw = -loc; + jw = -loc + 1; + r = numel( obj.Heights_ ); + ic = r * (-loc-1) + 1; + jc = r * -loc + 1; + divider = obj.ColumnDividers(iw); + contents = obj.Contents_; + oldPixelWidths = [contents(ic).Position(3); contents(jc).Position(3)]; + minimumWidths = obj.MinimumWidths_(iw:jw,:); + if delta < 0 % limit to minimum distance from left neighbor + delta = max( delta, minimumWidths(1) - oldPixelWidths(1) ); + else % limit to minimum distance from right neighbor + delta = min( delta, oldPixelWidths(2) - minimumWidths(2) ); + end + oldWidths = obj.Widths_(iw:jw); + newPixelWidths = oldPixelWidths + delta * [1;-1]; + if oldWidths(1) < 0 && oldWidths(2) < 0 % weight, weight + newWidths = oldWidths .* newPixelWidths ./ oldPixelWidths; + elseif oldWidths(1) < 0 && oldWidths(2) >= 0 % weight, pixels + newWidths = [oldWidths(1) * newPixelWidths(1) / ... + oldPixelWidths(1); newPixelWidths(2)]; + elseif oldWidths(1) >= 0 && oldWidths(2) < 0 % pixels, weight + newWidths = [newPixelWidths(1); oldWidths(2) * ... + newPixelWidths(2) / oldPixelWidths(2)]; + else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels + newWidths = newPixelWidths; + end + obj.Widths_(iw:jw) = newWidths; + else + return + end + + % Deactivate divider + obj.FrontDivider.Visible = 'off'; + divider.Visible = 'on'; + + % Reset state at button down + obj.ActiveDivider = 0; + obj.ActiveDividerPosition = [NaN NaN NaN NaN]; + obj.MousePressLocation = [NaN NaN]; + + % Mark as dirty + obj.Dirty = true; + + end % onMouseRelease + + function onMouseMotion( obj, source, eventData ) + %onMouseMotion Handler for WindowMouseMotion events + + loc = obj.ActiveDivider; + if loc == 0 % hovering, update pointer + obj.updateMousePointer( source, eventData ); + elseif loc > 0 % dragging row divider + root = groot(); + delta = root.PointerLocation(2) - obj.MousePressLocation(2); + ih = loc; + jh = loc + 1; + ic = loc; + jc = loc + 1; + contents = obj.Contents_; + oldPixelHeights = [contents(ic).Position(4); contents(jc).Position(4)]; + minimumHeights = obj.MinimumHeights_(ih:jh,:); + if delta < 0 % limit to minimum distance from lower neighbor + delta = max( delta, minimumHeights(2) - oldPixelHeights(2) ); + else % limit to minimum distance from upper neighbor + delta = min( delta, oldPixelHeights(1) - minimumHeights(1) ); + end + obj.FrontDivider.Position = ... + obj.ActiveDividerPosition + [0 delta 0 0]; + else % loc < 0, dragging column divider + root = groot(); + delta = root.PointerLocation(1) - obj.MousePressLocation(1); + iw = -loc; + jw = -loc + 1; + r = numel( obj.Heights_ ); + ic = r * (-loc-1) + 1; + jc = r * -loc + 1; + contents = obj.Contents_; + oldPixelWidths = [contents(ic).Position(3); contents(jc).Position(3)]; + minimumWidths = obj.MinimumWidths_(iw:jw,:); + if delta < 0 % limit to minimum distance from left neighbor + delta = max( delta, minimumWidths(1) - oldPixelWidths(1) ); + else % limit to minimum distance from right neighbor + delta = min( delta, oldPixelWidths(2) - minimumWidths(2) ); + end + obj.FrontDivider.Position = ... + obj.ActiveDividerPosition + [delta 0 0 0]; + end + + end % onMouseMotion + + function onBackgroundColorChange( obj, ~, ~ ) + %onBackgroundColorChange Handler for BackgroundColor changes + + backgroundColor = obj.BackgroundColor; + highlightColor = min( [backgroundColor / 0.75; 1 1 1] ); + shadowColor = max( [backgroundColor * 0.75; 0 0 0] ); + rowDividers = obj.RowDividers; + for ii = 1:numel( rowDividers ) + rowDivider = rowDividers(ii); + rowDivider.BackgroundColor = backgroundColor; + rowDivider.HighlightColor = highlightColor; + rowDivider.ShadowColor = shadowColor; + end + columnDividers = obj.ColumnDividers; + for jj = 1:numel( columnDividers ) + columnDivider = columnDividers(jj); + columnDivider.BackgroundColor = backgroundColor; + columnDivider.HighlightColor = highlightColor; + columnDivider.ShadowColor = shadowColor; + end + frontDivider = obj.FrontDivider; + frontDivider.BackgroundColor = shadowColor; + + end % onBackgroundColorChange + + end % event handlers + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw contents + % + % c.redraw() redraws the container c. + + % Call superclass method + redraw@uix.Grid( obj ) + + % Create or destroy column dividers + b = numel( obj.ColumnDividers ); % current number of dividers + c = max( [numel( obj.Widths_ )-1 0] ); % required number of dividers + if b < c % create + for ii = b+1:c + columnDivider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'vertical', ... + 'BackgroundColor', obj.BackgroundColor ); + obj.ColumnDividers(ii,:) = columnDivider; + end + elseif b > c % destroy + % Destroy dividers + delete( obj.ColumnDividers(c+1:b,:) ) + obj.ColumnDividers(c+1:b,:) = []; + % Update pointer + if c == 0 && strcmp( obj.Pointer, 'left' ) + obj.unsetPointer() + end + end + + % Create or destroy row dividers + q = numel( obj.RowDividers ); % current number of dividers + r = max( [numel( obj.Heights_ )-1 0] ); % required number of dividers + if q < r % create + for ii = q+1:r + columnDivider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'horizontal', ... + 'BackgroundColor', obj.BackgroundColor ); + obj.RowDividers(ii,:) = columnDivider; + end + % Bring front divider to the front + frontDivider = obj.FrontDivider; + frontDivider.Parent = []; + frontDivider.Parent = obj; + elseif q > r % destroy + % Destroy dividers + delete( obj.RowDividers(r+1:q,:) ) + obj.RowDividers(r+1:q,:) = []; + % Update pointer + if r == 0 && strcmp( obj.Pointer, 'top' ) + obj.unsetPointer() + end + end + + % Compute container bounds + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + + % Retrieve size properties + widths = obj.Widths_; + minimumWidths = obj.MinimumWidths_; + heights = obj.Heights_; + minimumHeights = obj.MinimumHeights_; + padding = obj.Padding_; + spacing = obj.Spacing_; + + % Compute row divider positions + xRowPositions = [padding + 1, max( bounds(3) - 2 * padding, 1 )]; + xRowPositions = repmat( xRowPositions, [r 1] ); + yRowSizes = uix.calcPixelSizes( bounds(4), heights, ... + minimumHeights, padding, spacing ); + yRowPositions = [bounds(4) - cumsum( yRowSizes(1:r,:) ) - padding - ... + spacing * transpose( 1:r ) + 1, repmat( spacing, [r 1] )]; + rowPositions = [xRowPositions(:,1), yRowPositions(:,1), ... + xRowPositions(:,2), yRowPositions(:,2)]; + + % Compute column divider positions + xColumnSizes = uix.calcPixelSizes( bounds(3), widths, ... + minimumWidths, padding, spacing ); + xColumnPositions = [cumsum( xColumnSizes(1:c,:) ) + padding + ... + spacing * transpose( 0:c-1 ) + 1, repmat( spacing, [c 1] )]; + yColumnPositions = [padding + 1, max( bounds(4) - 2 * padding, 1 )]; + yColumnPositions = repmat( yColumnPositions, [c 1] ); + columnPositions = [xColumnPositions(:,1), yColumnPositions(:,1), ... + xColumnPositions(:,2), yColumnPositions(:,2)]; + + % Position row dividers + for ii = 1:r + rowDivider = obj.RowDividers(ii); + rowDivider.Position = rowPositions(ii,:); + switch obj.DividerMarkings_ + case 'on' + rowDivider.Markings = cumsum( xColumnSizes ) + ... + spacing * transpose( 0:c ) - xColumnSizes / 2; + case 'off' + rowDivider.Markings = zeros( [0 1] ); + end + end + + % Position column dividers + for ii = 1:c + columnDivider = obj.ColumnDividers(ii); + columnDivider.Position = columnPositions(ii,:); + switch obj.DividerMarkings_ + case 'on' + columnDivider.Markings = cumsum( yRowSizes ) + ... + spacing * transpose( 0:r ) - yRowSizes / 2; + case 'off' + columnDivider.Markings = zeros( [0 1] ); + end + end + + end % redraw + + function reparent( obj, oldFigure, newFigure ) + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + % Update listeners + if isempty( newFigure ) + mousePressListener = event.listener.empty( [0 0] ); + mouseReleaseListener = event.listener.empty( [0 0] ); + mouseMotionListener = event.listener.empty( [0 0] ); + else + mousePressListener = event.listener( newFigure, ... + 'WindowMousePress', @obj.onMousePress ); + mouseReleaseListener = event.listener( newFigure, ... + 'WindowMouseRelease', @obj.onMouseRelease ); + mouseMotionListener = event.listener( newFigure, ... + 'WindowMouseMotion', @obj.onMouseMotion ); + end + obj.MousePressListener = mousePressListener; + obj.MouseReleaseListener = mouseReleaseListener; + obj.MouseMotionListener = mouseMotionListener; + + % Call superclass method + reparent@uix.Grid( obj, oldFigure, newFigure ) + + % Update pointer + if ~isempty( oldFigure ) && ~strcmp( obj.Pointer, 'unset' ) + obj.unsetPointer() + end + + end % reparent + + end % template methods + + methods( Access = protected ) + + function updateMousePointer ( obj, source, eventData ) + + oldPointer = obj.Pointer; + if any( obj.RowDividers.isMouseOver( eventData ) ) + newPointer = 'top'; + elseif any( obj.ColumnDividers.isMouseOver( eventData ) ) + newPointer = 'left'; + else + newPointer = 'unset'; + end + switch newPointer + case oldPointer % no change + % do nothing + case 'unset' % change, unset + obj.unsetPointer() + otherwise % change, set + obj.setPointer( source, newPointer ) + end + + end % updateMousePointer + + end % helpers methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/HBox.m b/Required packages/layout/+uix/HBox.m new file mode 100644 index 0000000..4de5110 --- /dev/null +++ b/Required packages/layout/+uix/HBox.m @@ -0,0 +1,194 @@ +classdef HBox < uix.Box + %uix.HBox Horizontal box + % + % b = uix.HBox(p1,v1,p2,v2,...) constructs a horizontal box and sets + % parameter p1 to value v1, etc. + % + % A horizontal box lays out contents from left to right. + % + % See also: uix.VBox, uix.Grid, uix.HButtonBox, uix.HBoxFlex + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + properties( Access = public, Dependent, AbortSet ) + Widths % widths of contents, in pixels and/or weights + MinimumWidths % minimum widths of contents, in pixels + end + + properties( Access = protected ) + Widths_ = zeros( [0 1] ) % backing for Widths + MinimumWidths_ = zeros( [0 1] ) % backing for MinimumWidths + end + + methods + + function obj = HBox( varargin ) + %uix.HBox Horizontal box constructor + % + % b = uix.HBox() constructs a horizontal box. + % + % b = uix.HBox(p1,v1,p2,v2,...) sets parameter p1 to value v1, + % etc. + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods + + function value = get.Widths( obj ) + + value = obj.Widths_; + + end % get.Widths + + function set.Widths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Widths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Widths'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''Widths'' must match size of contents.' ) + + % Set + obj.Widths_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Widths + + function value = get.MinimumWidths( obj ) + + value = obj.MinimumWidths_; + + end % get.MinimumWidths + + function set.MinimumWidths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumWidths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumWidths'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Widths_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumWidths'' must match size of contents.' ) + + % Set + obj.MinimumWidths_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumWidths + + end % accessors + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + % + % c.redraw() redraws the container c. + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + widths = obj.Widths_; + minimumWidths = obj.MinimumWidths_; + padding = obj.Padding_; + spacing = obj.Spacing_; + c = numel( widths ); + xSizes = uix.calcPixelSizes( bounds(3), widths, ... + minimumWidths, padding, spacing ); + xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + padding + ... + spacing * transpose( 0:c-1 ) + 1, xSizes]; + yPositions = [padding + 1, max( bounds(4) - 2 * padding, 1 )]; + yPositions = repmat( yPositions, [c 1] ); + positions = [xPositions(:,1), yPositions(:,1), ... + xPositions(:,2), yPositions(:,2)]; + + % Set positions + children = obj.Contents_; + for ii = 1:numel( children ) + uix.setPosition( children(ii), positions(ii,:), 'pixels' ) + end + + end % redraw + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Add to sizes + obj.Widths_(end+1,:) = -1; + obj.MinimumWidths_(end+1,:) = 1; + + % Call superclass method + addChild@uix.Box( obj, child ) + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Remove from sizes + tf = obj.Contents_ == child; + obj.Widths_(tf,:) = []; + obj.MinimumWidths_(tf,:) = []; + + % Call superclass method + removeChild@uix.Box( obj, child ) + + end % removeChild + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder + obj.Widths_ = obj.Widths_(indices,:); + obj.MinimumWidths_ = obj.MinimumWidths_(indices,:); + + % Call superclass method + reorder@uix.Box( obj, indices ) + + end % reorder + + end % template methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/HBoxFlex.m b/Required packages/layout/+uix/HBoxFlex.m new file mode 100644 index 0000000..9c72347 --- /dev/null +++ b/Required packages/layout/+uix/HBoxFlex.m @@ -0,0 +1,349 @@ +classdef HBoxFlex < uix.HBox & uix.mixin.Flex + %uix.HBoxFlex Flexible horizontal box + % + % b = uix.HBoxFlex(p1,v1,p2,v2,...) constructs a flexible horizontal + % box and sets parameter p1 to value v1, etc. + % + % A horizontal box lays out contents from left to right. Users can + % resize contents by dragging the dividers. + % + % See also: uix.VBoxFlex, uix.GridFlex, uix.HBox, uix.HButtonBox + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + properties( Access = public, Dependent, AbortSet ) + DividerMarkings % divider markings [on|off] + end + + properties( Access = private ) + ColumnDividers = uix.Divider.empty( [0 1] ) % column dividers + FrontDivider % front divider + DividerMarkings_ = 'on' % backing for DividerMarkings + MousePressListener = event.listener.empty( [0 0] ) % mouse press listener + MouseReleaseListener = event.listener.empty( [0 0] ) % mouse release listener + MouseMotionListener = event.listener.empty( [0 0] ) % mouse motion listener + ActiveDivider = 0 % active divider index + ActiveDividerPosition = [NaN NaN NaN NaN] % active divider position + MousePressLocation = [NaN NaN] % mouse press location + BackgroundColorListener % background color listener + end + + methods + + function obj = HBoxFlex( varargin ) + %uix.HBoxFlex Flexible horizontal box constructor + % + % b = uix.HBoxFlex() constructs a flexible horizontal box. + % + % b = uix.HBoxFlex(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Create front divider + frontDivider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'vertical', ... + 'BackgroundColor', obj.BackgroundColor * 0.75, ... + 'Visible', 'off' ); + + % Create listeners + backgroundColorListener = event.proplistener( obj, ... + findprop( obj, 'BackgroundColor' ), 'PostSet', ... + @obj.onBackgroundColorChange ); + + % Store properties + obj.FrontDivider = frontDivider; + obj.BackgroundColorListener = backgroundColorListener; + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods + + function value = get.DividerMarkings( obj ) + + value = obj.DividerMarkings_; + + end % get.DividerMarkings + + function set.DividerMarkings( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uix:InvalidArgument', ... + 'Property ''DividerMarkings'' must be ''on'' or ''off'.' ) + + % Set + obj.DividerMarkings_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.DividerMarkings + + end % accessors + + methods( Access = protected ) + + function onMousePress( obj, source, eventData ) + %onMousePress Handler for WindowMousePress events + + % Check whether mouse is over a divider + loc = find( obj.ColumnDividers.isMouseOver( eventData ) ); + if isempty( loc ), return, end + + % Capture state at button down + divider = obj.ColumnDividers(loc); + obj.ActiveDivider = loc; + obj.ActiveDividerPosition = divider.Position; + root = groot(); + obj.MousePressLocation = root.PointerLocation; + + % Make sure the pointer is appropriate + obj.updateMousePointer( source, eventData ); + + % Activate divider + frontDivider = obj.FrontDivider; + frontDivider.Position = divider.Position; + divider.Visible = 'off'; + frontDivider.Parent = []; + frontDivider.Parent = obj; + frontDivider.Visible = 'on'; + + end % onMousePress + + function onMouseRelease( obj, ~, ~ ) + %onMousePress Handler for WindowMouseRelease events + + % Compute new positions + loc = obj.ActiveDivider; + if loc > 0 + root = groot(); + delta = root.PointerLocation(1) - obj.MousePressLocation(1); + iw = loc; + jw = loc + 1; + ic = loc; + jc = loc + 1; + divider = obj.ColumnDividers(loc); + contents = obj.Contents_; + oldPixelWidths = [contents(ic).Position(3); contents(jc).Position(3)]; + minimumWidths = obj.MinimumWidths_(iw:jw,:); + if delta < 0 % limit to minimum distance from left neighbor + delta = max( delta, minimumWidths(1) - oldPixelWidths(1) ); + else % limit to minimum distance from right neighbor + delta = min( delta, oldPixelWidths(2) - minimumWidths(2) ); + end + oldWidths = obj.Widths_(iw:jw); + newPixelWidths = oldPixelWidths + delta * [1;-1]; + if oldWidths(1) < 0 && oldWidths(2) < 0 % weight, weight + newWidths = oldWidths .* newPixelWidths ./ oldPixelWidths; + elseif oldWidths(1) < 0 && oldWidths(2) >= 0 % weight, pixels + newWidths = [oldWidths(1) * newPixelWidths(1) / ... + oldPixelWidths(1); newPixelWidths(2)]; + elseif oldWidths(1) >= 0 && oldWidths(2) < 0 % pixels, weight + newWidths = [newPixelWidths(1); oldWidths(2) * ... + newPixelWidths(2) / oldPixelWidths(2)]; + else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels + newWidths = newPixelWidths; + end + obj.Widths_(iw:jw) = newWidths; + else + return + end + + % Deactivate divider + obj.FrontDivider.Visible = 'off'; + divider.Visible = 'on'; + + % Reset state at button down + obj.ActiveDivider = 0; + obj.ActiveDividerPosition = [NaN NaN NaN NaN]; + obj.MousePressLocation = [NaN NaN]; + + % Mark as dirty + obj.Dirty = true; + + end % onMouseRelease + + function onMouseMotion( obj, source, eventData ) + %onMouseMotion Handler for WindowMouseMotion events + + loc = obj.ActiveDivider; + if loc == 0 % hovering, update pointer + obj.updateMousePointer( source, eventData ); + else % dragging column divider + root = groot(); + delta = root.PointerLocation(1) - obj.MousePressLocation(1); + iw = loc; + jw = loc + 1; + ic = loc; + jc = loc + 1; + contents = obj.Contents_; + oldPixelWidths = [contents(ic).Position(3); contents(jc).Position(3)]; + minimumWidths = obj.MinimumWidths_(iw:jw,:); + if delta < 0 % limit to minimum distance from left neighbor + delta = max( delta, minimumWidths(1) - oldPixelWidths(1) ); + else % limit to minimum distance from right neighbor + delta = min( delta, oldPixelWidths(2) - minimumWidths(2) ); + end + obj.FrontDivider.Position = ... + obj.ActiveDividerPosition + [delta 0 0 0]; + end + + end % onMouseMotion + + function onBackgroundColorChange( obj, ~, ~ ) + %onBackgroundColorChange Handler for BackgroundColor changes + + backgroundColor = obj.BackgroundColor; + highlightColor = min( [backgroundColor / 0.75; 1 1 1] ); + shadowColor = max( [backgroundColor * 0.75; 0 0 0] ); + columnDividers = obj.ColumnDividers; + for jj = 1:numel( columnDividers ) + columnDivider = columnDividers(jj); + columnDivider.BackgroundColor = backgroundColor; + columnDivider.HighlightColor = highlightColor; + columnDivider.ShadowColor = shadowColor; + end + frontDivider = obj.FrontDivider; + frontDivider.BackgroundColor = shadowColor; + + end % onBackgroundColorChange + + end % event handlers + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw contents + % + % c.redraw() redraws the container c. + + % Call superclass method + redraw@uix.HBox( obj ) + + % Create or destroy column dividers + b = numel( obj.ColumnDividers ); % current number of dividers + c = max( [numel( obj.Widths_ )-1 0] ); % required number of dividers + if b < c % create + for ii = b+1:c + divider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'vertical', ... + 'BackgroundColor', obj.BackgroundColor ); + obj.ColumnDividers(ii,:) = divider; + end + elseif b > c % destroy + % Destroy dividers + delete( obj.ColumnDividers(c+1:b,:) ) + obj.ColumnDividers(c+1:b,:) = []; + % Update pointer + if c == 0 && strcmp( obj.Pointer, 'left' ) + obj.unsetPointer() + end + end + + % Compute container bounds + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + + % Retrieve size properties + widths = obj.Widths_; + minimumWidths = obj.MinimumWidths_; + padding = obj.Padding_; + spacing = obj.Spacing_; + + % Compute column divider positions + xColumnSizes = uix.calcPixelSizes( bounds(3), widths, ... + minimumWidths, padding, spacing ); + xColumnPositions = [cumsum( xColumnSizes(1:c,:) ) + padding + ... + spacing * transpose( 0:c-1 ) + 1, repmat( spacing, [c 1] )]; + yColumnPositions = [padding + 1, max( bounds(4) - 2 * padding, 1 )]; + yColumnPositions = repmat( yColumnPositions, [c 1] ); + columnPositions = [xColumnPositions(:,1), yColumnPositions(:,1), ... + xColumnPositions(:,2), yColumnPositions(:,2)]; + + % Position column dividers + for ii = 1:c + columnDivider = obj.ColumnDividers(ii); + columnDivider.Position = columnPositions(ii,:); + switch obj.DividerMarkings_ + case 'on' + columnDivider.Markings = columnPositions(ii,4)/2; + case 'off' + columnDivider.Markings = zeros( [0 1] ); + end + end + + end % redraw + + function reparent( obj, oldFigure, newFigure ) + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + % Update listeners + if isempty( newFigure ) + mousePressListener = event.listener.empty( [0 0] ); + mouseReleaseListener = event.listener.empty( [0 0] ); + mouseMotionListener = event.listener.empty( [0 0] ); + else + mousePressListener = event.listener( newFigure, ... + 'WindowMousePress', @obj.onMousePress ); + mouseReleaseListener = event.listener( newFigure, ... + 'WindowMouseRelease', @obj.onMouseRelease ); + mouseMotionListener = event.listener( newFigure, ... + 'WindowMouseMotion', @obj.onMouseMotion ); + end + obj.MousePressListener = mousePressListener; + obj.MouseReleaseListener = mouseReleaseListener; + obj.MouseMotionListener = mouseMotionListener; + + % Call superclass method + reparent@uix.HBox( obj, oldFigure, newFigure ) + + % Update pointer + if ~isempty( oldFigure ) && ~strcmp( obj.Pointer, 'unset' ) + obj.unsetPointer() + end + + end % reparent + + end % template methods + + methods( Access = protected ) + + function updateMousePointer ( obj, source, eventData ) + + oldPointer = obj.Pointer; + if any( obj.ColumnDividers.isMouseOver( eventData ) ) + newPointer = 'left'; + else + newPointer = 'unset'; + end + switch newPointer + case oldPointer % no change + % do nothing + case 'unset' % change, unset + obj.unsetPointer() + otherwise % change, set + obj.setPointer( source, newPointer ) + end + + end % updateMousePointer + + end % helpers methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/HButtonBox.m b/Required packages/layout/+uix/HButtonBox.m new file mode 100644 index 0000000..00d20c5 --- /dev/null +++ b/Required packages/layout/+uix/HButtonBox.m @@ -0,0 +1,100 @@ +classdef HButtonBox < uix.ButtonBox + %uix.HButtonBox Horizontal button box + % + % b = uix.HButtonBox(p1,v1,p2,v2,...) constructs a horizontal button + % box and sets parameter p1 to value v1, etc. + % + % A horizontal button box lays out equally sized buttons from left to + % right. + % + % See also: uix.VButtonBox + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + methods + + function obj = HButtonBox( varargin ) + %uix.HButtonBox Horizontal button box constructor + % + % b = uix.HButtonBox() constructs a horizontal button box. + % + % b = uix.HButtonBox(p1,v1,p2,v2,...) sets parameter p1 to + % value v1, etc. + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods( Access = protected ) + + function redraw( obj ) + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + buttonSize = obj.ButtonSize_; + padding = obj.Padding_; + spacing = obj.Spacing_; + c = numel( obj.Contents_ ); + if 2 * padding + (c-1) * spacing + c * buttonSize(1) > bounds(3) + xSizes = uix.calcPixelSizes( bounds(3), -ones( [c 1] ), ... + ones( [c 1] ), padding, spacing ); % shrink to fit + else + xSizes = repmat( buttonSize(1), [c 1] ); + end + switch obj.HorizontalAlignment + case 'left' + xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + ... + padding + spacing * transpose( 0:c-1 ) + 1, xSizes]; + case 'center' + xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + ... + spacing * transpose( 0:c-1 ) + bounds(3) / 2 - ... + sum( xSizes ) / 2 - spacing * (c-1) / 2 + 1, ... + xSizes]; + case 'right' + xPositions = [cumsum( [0; xSizes(1:c-1,:)] ) + ... + spacing * transpose( 0:c-1 ) + bounds(3) - ... + sum( xSizes ) - spacing * (c-1) - padding + 1, ... + xSizes]; + end + if 2 * padding + buttonSize(2) > bounds(4) + ySizes = repmat( uix.calcPixelSizes( bounds(4), -1, 1, ... + padding, spacing ), [c 1] ); % shrink to fit + else + ySizes = repmat( buttonSize(2), [c 1] ); + end + switch obj.VerticalAlignment + case 'top' + yPositions = [bounds(4) - ySizes - padding + 1, ySizes]; + case 'middle' + yPositions = [(bounds(4) - ySizes) / 2 + 1, ySizes]; + case 'bottom' + yPositions = [repmat( padding, [c 1] ) + 1, ySizes]; + end + positions = [xPositions(:,1), yPositions(:,1), ... + xPositions(:,2), yPositions(:,2)]; + + % Set positions + children = obj.Contents_; + for ii = 1:numel( children ) + uix.setPosition( children(ii), positions(ii,:), 'pixels' ) + end + + end % redraw + + end % template methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/Node.m b/Required packages/layout/+uix/Node.m new file mode 100644 index 0000000..642444c --- /dev/null +++ b/Required packages/layout/+uix/Node.m @@ -0,0 +1,94 @@ +classdef ( Hidden ) Node < dynamicprops + %uix.Node Node + % + % n = uix.Node(o) creates a node for the handle o. + % + % Node is a helper class for managing trees of objects and associated + % listeners. + + % Copyright 2009-2015 The MathWorks, Inc. + % $Revision: 1165 $ $Date: 2015-12-06 03:09:17 -0500 (Sun, 06 Dec 2015) $ + + properties( SetAccess = private ) + Object % object + Children = uix.Node.empty( [0 1] ) % children + end + + properties( Access = private ) + ChildListeners = event.listener.empty( [0 1] ) % internal listeners + end + + methods + + function obj = Node( object ) + %uix.Node Node + % + % n = uix.Node(o) creates a node for the handle o. + + % Check + assert( isa( object, 'handle' ) && ... + isequal( size( object ), [1 1] ) && isvalid( object ), ... + 'uix:InvalidArgument', 'Object must be a handle.' ) + + % Set properties + obj.Object = object; + + end % constructor + + end % structors + + methods + + function addChild( obj, child ) + %addChild Add child + % + % n.addChild(c) adds the child node c to the parent node n. + + % Check + assert( isa( child, 'uix.Node' ) && ... + isequal( size( child ), [1 1] ), ... + 'uix:InvalidArgument', 'Invalid node.' ) + + % Add + childListener = event.listener( child, ... + 'ObjectBeingDestroyed', @obj.onChildDeleted ); + obj.Children(end+1,:) = child; + obj.ChildListeners(end+1,:) = childListener; + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % n.removeChild(c) removes the child node c from the parent + % node n. + + % Check + assert( isa( child, 'uix.Node' ) && ... + isequal( size( child ), [1 1] ), ... + 'uix:InvalidArgument', 'Invalid node.' ) + assert( ismember( child, obj.Children ), ... + 'uix:ItemNotFound', 'Node not found.' ) + + % Remove + tf = child == obj.Children; + obj.Children(tf,:) = []; + obj.ChildListeners(tf,:) = []; + + end % removeChild + + end % public methods + + methods( Access = private ) + + function onChildDeleted( obj, source, ~ ) + %onChildDeleted Event handler for deletion of child nodes + + % Remove + obj.removeChild( source ) + + end % onChildDeleted + + end % event handlers + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/Panel.m b/Required packages/layout/+uix/Panel.m new file mode 100644 index 0000000..ebcd202 --- /dev/null +++ b/Required packages/layout/+uix/Panel.m @@ -0,0 +1,63 @@ +classdef Panel < matlab.ui.container.Panel & uix.mixin.Panel + %uix.Panel Standard panel + % + % b = uix.Panel(p1,v1,p2,v2,...) constructs a standard panel and sets + % parameter p1 to value v1, etc. + % + % A card panel is a standard panel (uipanel) that shows one its + % contents and hides the others. + % + % See also: uix.CardPanel, uix.BoxPanel, uipanel + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + methods + + function obj = Panel( varargin ) + %uix.Panel Standard panel constructor + % + % p = uix.Panel() constructs a standard panel. + % + % p = uix.Panel(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods( Access = protected ) + + function redraw( obj ) + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + padding = obj.Padding_; + xSizes = uix.calcPixelSizes( bounds(3), -1, 1, padding, 0 ); + ySizes = uix.calcPixelSizes( bounds(4), -1, 1, padding, 0 ); + position = [padding+1 padding+1 xSizes ySizes]; + + % Redraw contents + selection = obj.Selection_; + if selection ~= 0 + uix.setPosition( obj.Contents_(selection), position, 'pixels' ) + end + + end % redraw + + end % template methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/PointerManager.m b/Required packages/layout/+uix/PointerManager.m new file mode 100644 index 0000000..579ad31 --- /dev/null +++ b/Required packages/layout/+uix/PointerManager.m @@ -0,0 +1,153 @@ +classdef ( Hidden, Sealed ) PointerManager < handle + %uix.PointerManager Pointer manager + + % Copyright 2016 The MathWorks, Inc. + % $Revision: 1435 $ $Date: 2016-11-17 17:50:34 +0000 (Thu, 17 Nov 2016) $ + + properties( SetAccess = private ) + Figure % figure + end + + properties( Access = private ) + Tokens % tokens + Pointers % pointers + NextToken % next token + PointerListener % listener + end + + methods( Access = private ) + + function obj = PointerManager( figure ) + %uix.PointerManager Create pointer manager + % + % m = uix.PointerManager(f) creates a pointer manager for the + % figure f. + + obj.Figure = figure; + obj.Tokens = 0; + obj.Pointers = {figure.Pointer}; + obj.NextToken = 1; + obj.PointerListener = event.proplistener( figure, ... + findprop( figure, 'Pointer' ), 'PostSet', ... + @obj.onPointerChanged ); + + end % constructor + + end % structors + + methods( Access = private ) + + function doSetPointer( obj, token, pointer ) + %doSetPointer Set pointer + % + % m.doSetPointer(t,p) sets the pointer to p with the token t. + + % Remove old entry + tf = obj.Tokens == token; + obj.Tokens(tf) = []; + obj.Pointers(tf) = []; + + % Add new entry + obj.Tokens(end+1) = token; + obj.Pointers{end+1} = pointer; + + % Set pointer + obj.PointerListener.Enabled = false; + obj.Figure.Pointer = pointer; + obj.PointerListener.Enabled = true; + + end % doSetPointer + + function doUnsetPointer( obj, token ) + %doUnsetPointer Unset pointer + % + % m.doUnsetPointer(s) unsets the pointer with the token t. + + % Remove old entry + tf = obj.Tokens == token; + obj.Tokens(tf) = []; + obj.Pointers(tf) = []; + + % Update pointer + obj.PointerListener.Enabled = false; + obj.Figure.Pointer = obj.Pointers{end}; + obj.PointerListener.Enabled = true; + + end % doUnsetPointer + + end % private methods + + methods + + function onPointerChanged( obj, ~, ~ ) + %onPointerChanged Event handler + + % Log as unknown setter + obj.doSetPointer( 0, obj.Figure.Pointer ) + + end % onPointerChanged + + end % event handlers + + methods( Static ) + + function token = setPointer( figure, pointer ) + %setPointer Set pointer + % + % t = uix.PointerManager.setPointer(f,p) sets the pointer of + % the figure f to p. The returned token t can be used + % subsequently to unset the pointer. + + % Get pointer manager + obj = uix.PointerManager.getInstance( figure ); + + % Retrieve token + token = obj.NextToken; + + % Set + obj.doSetPointer( token, pointer ) + + % Increment token + obj.NextToken = token + 1; + + end % setPointer + + function unsetPointer( figure, token ) + %unsetPointer Unset pointer + % + % uix.PointerManager.unsetPointer(f,t) unsets the pointer of + % the figure f using the token t. + + % Check ID + validateattributes( token, {'numeric'}, {'scalar','integer','>',0} ) + + % Get pointer manager + obj = uix.PointerManager.getInstance( figure ); + + % Unset + obj.doUnsetPointer( token ) + + end % unsetPointer + + function obj = getInstance( figure ) + %getInstance Get pointer manager + % + % m = uix.PointerManager.getInstance(f) gets the pointer + % manager for the figure f. + + % Get pointer manager + name = 'UIxPointerManager'; + if isprop( figure, name ) % existing, retrieve + obj = figure.( name ); + else % new, create and store + obj = uix.PointerManager( figure ); + p = addprop( figure, name ); + p.Hidden = true; + figure.( name ) = obj; + end + + end % getInstance + + end % static methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/Resources/tab_NoEdge_NotSelected.png b/Required packages/layout/+uix/Resources/tab_NoEdge_NotSelected.png new file mode 100644 index 0000000..30d4bb4 Binary files /dev/null and b/Required packages/layout/+uix/Resources/tab_NoEdge_NotSelected.png differ diff --git a/Required packages/layout/+uix/Resources/tab_NoEdge_Selected.png b/Required packages/layout/+uix/Resources/tab_NoEdge_Selected.png new file mode 100644 index 0000000..c0c8b56 Binary files /dev/null and b/Required packages/layout/+uix/Resources/tab_NoEdge_Selected.png differ diff --git a/Required packages/layout/+uix/Resources/tab_NotSelected_NoEdge.png b/Required packages/layout/+uix/Resources/tab_NotSelected_NoEdge.png new file mode 100644 index 0000000..30bf1da Binary files /dev/null and b/Required packages/layout/+uix/Resources/tab_NotSelected_NoEdge.png differ diff --git a/Required packages/layout/+uix/Resources/tab_NotSelected_NotSelected.png b/Required packages/layout/+uix/Resources/tab_NotSelected_NotSelected.png new file mode 100644 index 0000000..c6aca7c Binary files /dev/null and b/Required packages/layout/+uix/Resources/tab_NotSelected_NotSelected.png differ diff --git a/Required packages/layout/+uix/Resources/tab_NotSelected_Selected.png b/Required packages/layout/+uix/Resources/tab_NotSelected_Selected.png new file mode 100644 index 0000000..e96782b Binary files /dev/null and b/Required packages/layout/+uix/Resources/tab_NotSelected_Selected.png differ diff --git a/Required packages/layout/+uix/Resources/tab_Selected_NoEdge.png b/Required packages/layout/+uix/Resources/tab_Selected_NoEdge.png new file mode 100644 index 0000000..f23a1b0 Binary files /dev/null and b/Required packages/layout/+uix/Resources/tab_Selected_NoEdge.png differ diff --git a/Required packages/layout/+uix/Resources/tab_Selected_NotSelected.png b/Required packages/layout/+uix/Resources/tab_Selected_NotSelected.png new file mode 100644 index 0000000..4758ca3 Binary files /dev/null and b/Required packages/layout/+uix/Resources/tab_Selected_NotSelected.png differ diff --git a/Required packages/layout/+uix/ScrollingPanel.m b/Required packages/layout/+uix/ScrollingPanel.m new file mode 100644 index 0000000..667434d --- /dev/null +++ b/Required packages/layout/+uix/ScrollingPanel.m @@ -0,0 +1,645 @@ +classdef ScrollingPanel < uix.Container & uix.mixin.Panel + %uix.ScrollingPanel Scrolling panel + % + % p = uix.ScrollingPanel(p1,v1,p2,v2,...) constructs a scrolling panel + % and sets parameter p1 to value v1, etc. + % + % A scrolling panel is a standard container (uicontainer) that shows + % one its contents and hides the others. + % + % See also: uix.Panel, uix.BoxPanel, uix.TabPanel, uicontainer + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1455 $ $Date: 2017-01-26 20:34:18 +0000 (Thu, 26 Jan 2017) $ + + properties( Dependent ) + Heights % heights of contents, in pixels and/or weights + MinimumHeights % minimum heights of contents, in pixels + VerticalOffsets % vertical offsets of contents, in pixels + VerticalSteps % vertical slider steps, in pixels + Widths % widths of contents, in pixels and/or weights + MinimumWidths % minimum widths of contents, in pixels + HorizontalOffsets % horizontal offsets of contents, in pixels + HorizontalSteps % horizontal slider steps, in pixels + MouseWheelEnabled % mouse wheel scrolling enabled [on|off] + end + + properties( Access = protected ) + Heights_ = zeros( [0 1] ) % backing for Heights + MinimumHeights_ = zeros( [0 1] ) % backing for MinimumHeights + Widths_ = zeros( [0 1] ) % backing for Widths + MinimumWidths_ = zeros( [0 1] ) % backing for MinimumWidths + HorizontalSliders = matlab.ui.control.UIControl.empty( [0 1] ) % sliders + VerticalSliders = matlab.ui.control.UIControl.empty( [0 1] ) % sliders + BlankingPlates = matlab.ui.control.UIControl.empty( [0 1] ) % blanking plates + HorizontalSteps_ = zeros( [0 1] ) % steps + VerticalSteps_ = zeros( [0 1] ) % steps + end + + properties( Access = private ) + MouseWheelListener = [] % mouse listener + MouseWheelEnabled_ = 'on' % + SliderListener = [] % slider listener + end + + properties( Constant, Access = protected ) + SliderSize = 20 % slider size, in pixels + SliderStep = 10 % slider step, in pixels + end + + methods + + function obj = ScrollingPanel( varargin ) + %uix.ScrollingPanel Scrolling panel constructor + % + % p = uix.ScrollingPanel() constructs a scrolling panel. + % + % p = uix.ScrollingPanel(p1,v1,p2,v2,...) sets parameter p1 to + % value v1, etc. + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods + + function value = get.Heights( obj ) + + value = obj.Heights_; + + end % get.Heights + + function set.Heights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Heights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Heights'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''Heights'' must match size of contents.' ) + + % Set + obj.Heights_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Heights + + function value = get.MinimumHeights( obj ) + + value = obj.MinimumHeights_; + + end % get.MinimumHeights + + function set.MinimumHeights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumHeights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumHeights'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Heights_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumHeights'' must match size of contents.' ) + + % Set + obj.MinimumHeights_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumHeights + + function value = get.VerticalOffsets( obj ) + + sliders = obj.VerticalSliders; + if isempty( sliders ) + value = zeros( size( sliders ) ); + else + value = -vertcat( sliders.Value ) - 1; + value(value<0) = 0; + end + + end % get.VerticalOffsets + + function set.VerticalOffsets( obj, value ) + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''VerticalOffsets'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''VerticalOffsets'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''VerticalOffsets'' must match size of contents.' ) + + % Set + sliders = obj.VerticalSliders; + heights = obj.Heights_; + for ii = 1:numel( sliders ) + if heights(ii) > 0 + sliders(ii).Value = -value(ii) - 1; + end + end + + % Mark as dirty + obj.Dirty = true; + + end % set.VerticalOffsets + + function value = get.VerticalSteps( obj ) + + value = obj.VerticalSteps_; + + end % get.VerticalSteps + + function set.VerticalSteps( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''VerticalSteps'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ) && all( value > 0 ), ... + 'uix:InvalidPropertyValue', ... + 'Elements of property ''VerticalSteps'' must be real, finite and positive.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''VerticalSteps'' must match size of contents.' ) + + % Set + obj.VerticalSteps_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.VerticalSteps + + function value = get.Widths( obj ) + + value = obj.Widths_; + + end % get.Widths + + function set.Widths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Widths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Widths'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''Widths'' must match size of contents.' ) + + % Set + obj.Widths_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Widths + + function value = get.MinimumWidths( obj ) + + value = obj.MinimumWidths_; + + end % get.MinimumWidths + + function set.MinimumWidths( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumWidths'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumWidths'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Widths_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumWidths'' must match size of contents.' ) + + % Set + obj.MinimumWidths_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumWidths + + function value = get.HorizontalOffsets( obj ) + + sliders = obj.HorizontalSliders; + if isempty( sliders ) + value = zeros( size( sliders ) ); + else + value = vertcat( sliders.Value ); + value(value<0) = 0; + end + + end % get.HorizontalOffsets + + function set.HorizontalOffsets( obj, value ) + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''HorizontalOffsets'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''HorizontalOffsets'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''HorizontalOffsets'' must match size of contents.' ) + + % Set + sliders = obj.HorizontalSliders; + widths = obj.Widths_; + for ii = 1:numel( sliders ) + if widths(ii) > 0 + sliders(ii).Value = value(ii); + end + end + + % Mark as dirty + obj.Dirty = true; + + end % set.HorizontalOffsets + + function value = get.HorizontalSteps( obj ) + + value = obj.HorizontalSteps_; + + end % get.HorizontalSteps + + function set.HorizontalSteps( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''HorizontalSteps'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ) && all( value > 0 ), ... + 'uix:InvalidPropertyValue', ... + 'Elements of property ''HorizontalSteps'' must be real, finite and positive.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''HorizontalSteps'' must match size of contents.' ) + + % Set + obj.HorizontalSteps_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.HorizontalSteps + + function value = get.MouseWheelEnabled( obj ) + + value = obj.MouseWheelEnabled_; + + end % get.MouseWheelEnabled + + function set.MouseWheelEnabled( obj, value ) + + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uix:InvalidArgument', ... + 'Property ''MouseWheelEnabled'' must ''on'' or ''off''.' ) + listener = obj.MouseWheelListener; + if ~isempty( listener ) + listener.Enabled = strcmp( value, 'on' ); + end + obj.MouseWheelEnabled_ = value; + + end % set.MouseWheelEnabled + + end % accessors + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + + % Return if no contents + selection = obj.Selection_; + if selection == 0, return, end + + % Retrieve width and height of selected contents + contentsWidth = obj.Widths_(selection); + minimumWidth = obj.MinimumWidths_(selection); + contentsHeight = obj.Heights_(selection); + minimumHeight = obj.MinimumHeights_(selection); + + % Retrieve selected contents and corresponding decorations + child = obj.Contents_(selection); + vSlider = obj.VerticalSliders(selection); + hSlider = obj.HorizontalSliders(selection); + plate = obj.BlankingPlates(selection); + + % Compute dimensions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + width = bounds(3); + height = bounds(4); + sliderSize = obj.SliderSize; % slider size + vSliderWidth = sliderSize * ... + (contentsHeight > height | ... + minimumHeight > height); % first pass + hSliderHeight = sliderSize * ... + (contentsWidth > width - vSliderWidth | ... + minimumWidth > width - vSliderWidth); + vSliderWidth = sliderSize * ... + (contentsHeight > height - hSliderHeight | ... + minimumHeight > height - hSliderHeight); % second pass + vSliderWidth = min( vSliderWidth, width ); % limit + hSliderHeight = min( hSliderHeight, height ); % limit + vSliderHeight = height - hSliderHeight; + hSliderWidth = width - vSliderWidth; + widths = uix.calcPixelSizes( width, ... + [contentsWidth;vSliderWidth], ... + [minimumWidth;vSliderWidth], 0, 0 ); + contentsWidth = widths(1); % to be offset + heights = uix.calcPixelSizes( height, ... + [contentsHeight;hSliderHeight], ... + [minimumHeight;hSliderHeight], 0, 0 ); + contentsHeight = heights(1); % to be offset + + % Compute positions + contentsPosition = [1 1+hSliderHeight+vSliderHeight-contentsHeight contentsWidth contentsHeight]; + vSliderPosition = [1+hSliderWidth 1+hSliderHeight vSliderWidth vSliderHeight]; + hSliderPosition = [1 1 hSliderWidth hSliderHeight]; + platePosition = [1+hSliderWidth 1 vSliderWidth hSliderHeight]; + + % Compute and set vertical slider properties + if vSliderWidth == 0 || vSliderHeight == 0 || vSliderHeight <= vSliderWidth + % Slider is invisible or incorrectly oriented + set( vSlider, 'Style', 'text', 'Enable', 'inactive', ... + 'Position', vSliderPosition, ... + 'Min', 0, 'Max', 1, 'Value', 1 ) + else + % Compute properties + vSliderMin = 0; + vSliderMax = contentsHeight - vSliderHeight; + vSliderValue = -vSlider.Value; % negative sign convention + vSliderValue = max( vSliderValue, vSliderMin ); % limit + vSliderValue = min( vSliderValue, vSliderMax ); % limit + vStep = obj.VerticalSteps_(selection); + vSliderStep(1) = min( vStep / vSliderMax, 1 ); + vSliderStep(2) = max( vSliderHeight / vSliderMax, vSliderStep(1) ); + contentsPosition(2) = contentsPosition(2) + vSliderValue; + % Set properties + set( vSlider, 'Style', 'slider', 'Enable', 'on', ... + 'Position', vSliderPosition, ... + 'Min', -vSliderMax, 'Max', -vSliderMin, ... + 'Value', -vSliderValue, 'SliderStep', vSliderStep ) + end + + % Compute and set horizontal slider properties + if hSliderHeight == 0 || hSliderWidth == 0 || hSliderWidth <= hSliderHeight + % Slider is invisible or incorrectly oriented + set( hSlider, 'Style', 'text', 'Enable', 'inactive', ... + 'Position', hSliderPosition, ... + 'Min', -1, 'Max', 0, 'Value', -1 ) + else + % Compute properties + hSliderMin = 0; + hSliderMax = contentsWidth - hSliderWidth; + hSliderValue = hSlider.Value; % positive sign convention + hSliderValue = max( hSliderValue, hSliderMin ); % limit + hSliderValue = min( hSliderValue, hSliderMax ); % limit + hStep = obj.HorizontalSteps_(selection); + hSliderStep(1) = min( hStep / hSliderMax, 1 ); + hSliderStep(2) = max( hSliderWidth / hSliderMax, hSliderStep(1) ); + contentsPosition(1) = contentsPosition(1) - hSliderValue; + % Set properties + set( hSlider, 'Style', 'slider', 'Enable', 'on', ... + 'Position', hSliderPosition, ... + 'Min', hSliderMin, 'Max', hSliderMax, ... + 'Value', hSliderValue, 'SliderStep', hSliderStep ) + end + + % Set contents and blanking plate positions + uix.setPosition( child, contentsPosition, 'pixels' ) + set( plate, 'Position', platePosition ) + + end % redraw + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Add to sizes + obj.Widths_(end+1,:) = -1; + obj.MinimumWidths_(end+1,:) = -1; + obj.Heights_(end+1,:) = -1; + obj.MinimumHeights_(end+1,:) = -1; + obj.VerticalSliders(end+1,:) = uicontrol( ... + 'Internal', true, 'Parent', obj, 'Units', 'pixels', ... + 'Style', 'slider' ); + obj.HorizontalSliders(end+1,:) = uicontrol( ... + 'Internal', true, 'Parent', obj, 'Units', 'pixels', ... + 'Style', 'slider' ); + obj.BlankingPlates(end+1,:) = uicontrol( ... + 'Internal', true, 'Parent', obj, 'Units', 'pixels', ... + 'Style', 'text', 'Enable', 'inactive' ); + obj.VerticalSteps_(end+1,:) = obj.SliderStep; + obj.HorizontalSteps_(end+1,:) = obj.SliderStep; + obj.updateSliderListener() + + % Call superclass method + addChild@uix.mixin.Panel( obj, child ) + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Remove from sizes + tf = obj.Contents_ == child; + obj.Widths_(tf,:) = []; + obj.MinimumWidths_(tf,:) = []; + obj.Heights_(tf,:) = []; + obj.MinimumHeights_(tf,:) = []; + obj.VerticalSliders(tf,:) = []; + obj.HorizontalSliders(tf,:) = []; + obj.BlankingPlates(tf,:) = []; + obj.VerticalSteps_(tf,:) = []; + obj.HorizontalSteps_(tf,:) = []; + obj.updateSliderListener() + + % Call superclass method + removeChild@uix.mixin.Panel( obj, child ) + + end % removeChild + + function reparent( obj, ~, newFigure ) + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + if isempty( newFigure ) + obj.MouseWheelListener = []; + else + listener = event.listener( newFigure, ... + 'WindowScrollWheel', @obj.onMouseScrolled ); + listener.Enabled = strcmp( obj.MouseWheelEnabled_, 'on' ); + obj.MouseWheelListener = listener; + end + + end % reparent + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder + obj.Widths_ = obj.Widths_(indices,:); + obj.MinimumWidths_ = obj.MinimumWidths_(indices,:); + obj.Heights_ = obj.Heights_(indices,:); + obj.MinimumHeights_ = obj.MinimumWidths_(indices,:); + obj.VerticalSliders = obj.VerticalSliders(indices,:); + obj.HorizontalSliders = obj.HorizontalSliders(indices,:); + obj.BlankingPlates = obj.BlankingPlates(indices,:); + obj.VerticalSteps_ = obj.VerticalSteps_(indices,:); + obj.HorizontalSteps_ = obj.HorizontalSteps_(indices,:); + + % Call superclass method + reorder@uix.mixin.Panel( obj, indices ) + + end % reorder + + function showSelection( obj ) + %showSelection Show selected child, hide the others + % + % c.showSelection() shows the selected child of the container + % c, and hides the others. + + % Call superclass method + showSelection@uix.mixin.Panel( obj ) + + % Show and hide sliders based on selection + selection = obj.Selection_; + for ii = 1:numel( obj.Contents_ ) + if ii == selection + obj.VerticalSliders(ii).Visible = 'on'; + obj.HorizontalSliders(ii).Visible = 'on'; + obj.BlankingPlates(ii).Visible = 'on'; + else + obj.VerticalSliders(ii).Visible = 'off'; + obj.HorizontalSliders(ii).Visible = 'off'; + obj.BlankingPlates(ii).Visible = 'off'; + end + end + + end % showSelection + + end % template methods + + methods( Access = private ) + + function onSliderValueChanged( obj, ~, ~ ) + %onSliderValueChanged Event handler + + % Mark as dirty + obj.Dirty = true; + + end % onSliderValueChanged + + function onMouseScrolled( obj, ~, eventData ) + %onMouseScrolled Event handler + + sel = obj.Selection_; + if sel == 0 + return + else + % Get pointer position and panel bounds + pp = getpixelposition( obj, true ); + f = ancestor( obj, 'figure' ); + cp = f.CurrentPoint; + % Check that pointer is over panel + if cp(1) < pp(1) || cp(1) > pp(1) + pp(3) || ... + cp(2) < pp(2) || cp(2) > pp(2) + pp(4), return, end + % Compute delta + delta = eventData.VerticalScrollCount * ... + eventData.VerticalScrollAmount * obj.VerticalSteps(sel); + % Scroll + if obj.Heights_(sel) > 0 % scroll vertically + obj.VerticalOffsets(sel) = obj.VerticalOffsets(sel) + delta; + elseif obj.Widths_(sel) > 0 % scroll horizontally + obj.HorizontalOffsets(sel) = obj.HorizontalOffsets(sel) + delta; + end + end + + end % onMouseScrolled + + end % event handlers + + methods( Access = private ) + + function updateSliderListener( obj ) + %updateSliderListener Update listener to slider events + + if isempty( obj.VerticalSliders ) + obj.SliderListener = []; + else + obj.SliderListener = event.listener( ... + [obj.VerticalSliders; obj.HorizontalSliders], ... + 'ContinuousValueChange', @obj.onSliderValueChanged ); + end + + end % updateSliderListener + + end % helpers + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/SelectionData.m b/Required packages/layout/+uix/SelectionData.m new file mode 100644 index 0000000..bf772a6 --- /dev/null +++ b/Required packages/layout/+uix/SelectionData.m @@ -0,0 +1,31 @@ +classdef( Hidden, Sealed ) SelectionData < event.EventData + %uix.SelectionData Event data for selection event + % + % e = uix.SelectionData(o,n) creates event data including the old + % value o and the new value n. + + % Copyright 2009-2015 The MathWorks, Inc. + % $Revision: 1165 $ $Date: 2015-12-06 03:09:17 -0500 (Sun, 06 Dec 2015) $ + + properties( SetAccess = private ) + OldValue % old value + NewValue % newValue + end + + methods + + function obj = SelectionData( oldValue, newValue ) + %uix.SelectionData Event data for selection event + % + % e = uix.SelectionData(o,n) creates event data including the + % old value o and the new value n. + + % Set properties + obj.OldValue = oldValue; + obj.NewValue = newValue; + + end % constructor + + end % structors + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/TabPanel.m b/Required packages/layout/+uix/TabPanel.m new file mode 100644 index 0000000..06a5edc --- /dev/null +++ b/Required packages/layout/+uix/TabPanel.m @@ -0,0 +1,951 @@ +classdef TabPanel < uix.Container & uix.mixin.Panel + %uix.TabPanel Tab panel + % + % p = uix.TabPanel(p1,v1,p2,v2,...) constructs a tab panel and sets + % parameter p1 to value v1, etc. + % + % A tab panel shows one of its contents and hides the others according + % to which tab is selected. + % + % From R2014b, MATLAB provides uitabgroup and uitab as standard + % components. Consider using uitabgroup and uitab for new code if + % these meet your requirements. + % + % See also: uitabgroup, uitab, uix.CardPanel + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + properties( Access = public, Dependent, AbortSet ) + FontAngle % font angle + FontName % font name + FontSize % font size + FontWeight % font weight + FontUnits % font weight + ForegroundColor % tab text color [RGB] + HighlightColor % border highlight color [RGB] + ShadowColor % border shadow color [RGB] + end + + properties + SelectionChangedFcn = '' % selection change callback + end + + properties( Access = public, Dependent, AbortSet ) + TabEnables % tab enable states + TabLocation % tab location [top|bottom] + TabTitles % tab titles + TabContextMenus % tab context menus + TabWidth % tab width + end + + properties( Access = private ) + FontAngle_ = get( 0, 'DefaultUicontrolFontAngle' ) % backing for FontAngle + FontName_ = get( 0, 'DefaultUicontrolFontName' ) % backing for FontName + FontSize_ = get( 0, 'DefaultUicontrolFontSize' ) % backing for FontSize + FontWeight_ = get( 0, 'DefaultUicontrolFontWeight' ) % backing for FontWeight + FontUnits_ = get( 0, 'DefaultUicontrolFontUnits' ) % backing for FontUnits + ForegroundColor_ = get( 0, 'DefaultUicontrolForegroundColor' ) % backing for ForegroundColor + HighlightColor_ = [1 1 1] % backing for HighlightColor + ShadowColor_ = [0.7 0.7 0.7] % backing for ShadowColor + ParentBackgroundColor = get( 0, 'DefaultUicontrolForegroundColor' ) % default parent background color + Tabs = gobjects( [0 1] ) % tabs + TabListeners = event.listener.empty( [0 1] ) % tab listeners + TabLocation_ = 'top' % backing for TabPosition + TabHeight = -1 % cache of tab height (-1 denotes stale cache) + TabWidth_ = 50 % backing for TabWidth + Dividers % tab dividers + BackgroundColorListener % listener + SelectionChangedListener % listener + ParentListener % listener + ParentBackgroundColorListener % listener + end + + properties( Access = private, Constant ) + FontNames = listfonts() % all available font names + DividerMask = uix.TabPanel.getDividerMask() % divider image data + DividerWidth = 8 % divider width + TabMinimumHeight = 9 % tab minimum height + Tint = 0.85 % tint factor for unselected tabs + end + + methods + + function obj = TabPanel( varargin ) + %uix.TabPanel Tab panel constructor + % + % p = uix.TabPanel() constructs a tab panel. + % + % p = uix.TabPanel(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Create dividers + dividers = matlab.ui.control.UIControl( 'Internal', true, ... + 'Parent', obj, 'Units', 'pixels', 'Style', 'checkbox',... + 'Tag', 'TabPanelDividers' ); + + % Create listeners + backgroundColorListener = event.proplistener( obj, ... + findprop( obj, 'BackgroundColor' ), 'PostSet', ... + @obj.onBackgroundColorChange ); + selectionChangedListener = event.listener( obj, ... + 'SelectionChanged', @obj.onSelectionChanged ); + parentListener = event.proplistener( obj, ... + findprop( obj, 'Parent' ), 'PostSet', ... + @obj.onParentChanged ); + + % Store properties + obj.Dividers = dividers; + obj.BackgroundColorListener = backgroundColorListener; + obj.SelectionChangedListener = selectionChangedListener; + obj.ParentListener = parentListener; + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods + + function value = get.FontAngle( obj ) + + value = obj.FontAngle_; + + end % get.FontAngle + + function set.FontAngle( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'normal','italic','oblique'} ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''FontAngle'' must be ''normal'', ''italic'' or ''oblique''.' ) + + % Set + obj.FontAngle_ = value; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.FontAngle = value; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + end % set.FontAngle + + function value = get.FontName( obj ) + + value = obj.FontName_; + + end % get.FontName + + function set.FontName( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, obj.FontNames ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''FontName'' must be a valid font name.' ) + + % Set + obj.FontName_ = value; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.FontName = value; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + end % set.FontName + + function value = get.FontSize( obj ) + + value = obj.FontSize_; + + end % get.FontSize + + function set.FontSize( obj, value ) + + % Check + assert( isa( value, 'double' ) && isscalar( value ) && ... + isreal( value ) && ~isinf( value ) && ... + ~isnan( value ) && value > 0, ... + 'uix:InvalidPropertyValue', ... + 'Property ''FontSize'' must be a positive scalar.' ) + + % Set + obj.FontSize_ = value; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.FontSize = value; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + end % set.FontSize + + function value = get.FontWeight( obj ) + + value = obj.FontWeight_; + + end % get.FontWeight + + function set.FontWeight( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'normal','bold'} ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''FontWeight'' must be ''normal'' or ''bold''.' ) + + % Set + obj.FontWeight_ = value; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.FontWeight = value; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + end % set.FontWeight + + function value = get.FontUnits( obj ) + + value = obj.FontUnits_; + + end % get.FontUnits + + function set.FontUnits( obj, value ) + + % Check + assert( ischar( value ) && ... + any( strcmp( value, {'inches','centimeters','points','pixels'} ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''FontUnits'' must be ''inches'', ''centimeters'', ''points'' or ''pixels''.' ) + + % Compute size in new units + oldUnits = obj.FontUnits_; + oldSize = obj.FontSize_; + newUnits = value; + newSize = oldSize * convert( oldUnits ) / convert( newUnits ); + + % Set size and units + obj.FontSize_ = newSize; + obj.FontUnits_ = newUnits; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.FontUnits = newUnits; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + function factor = convert( units ) + %convert Compute conversion factor to points + % + % f = convert(u) computes the conversion factor from units + % u to points. For example, convert('inches') since 1 + % inch equals 72 points. + + persistent SCREEN_PIXELS_PER_INCH + if isequal( SCREEN_PIXELS_PER_INCH, [] ) % uninitialized + SCREEN_PIXELS_PER_INCH = get( 0, 'ScreenPixelsPerInch' ); + end + + switch units + case 'inches' + factor = 72; + case 'centimeters' + factor = 72 / 2.54; + case 'points' + factor = 1; + case 'pixels' + factor = 72 / SCREEN_PIXELS_PER_INCH; + end + + end % convert + + end % set.FontUnits + + function value = get.ForegroundColor( obj ) + + value = obj.ForegroundColor_; + + end % get.ForegroundColor + + function set.ForegroundColor( obj, value ) + + % Check + assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ... + all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''ForegroundColor'' must be an RGB triple.' ) + + % Set + obj.ForegroundColor_ = value; + + % Update existing tabs + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tab = tabs(ii); + tab.ForegroundColor = value; + end + + end % set.ForegroundColor + + function value = get.HighlightColor( obj ) + + value = obj.HighlightColor_; + + end % get.HighlightColor + + function set.HighlightColor( obj, value ) + + % Check + assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ... + all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''HighlightColor'' must be an RGB triple.' ) + + % Set + obj.HighlightColor_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.HighlightColor + + function set.SelectionChangedFcn( obj, value ) + + % Check + if ischar( value ) % string + % OK + elseif isa( value, 'function_handle' ) && ... + isequal( size( value ), [1 1] ) % function handle + % OK + elseif iscell( value ) && ndims( value ) == 2 && ... + size( value, 1 ) == 1 && size( value, 2 ) > 0 && ... + isa( value{1}, 'function_handle' ) && ... + isequal( size( value{1} ), [1 1] ) %#ok % cell callback + % OK + else + error( 'uix:InvalidPropertyValue', ... + 'Property ''SelectionChangedFcn'' must be a valid callback.' ) + end + + % Set + obj.SelectionChangedFcn = value; + + end % set.SelectionChangedFcn + + function value = get.ShadowColor( obj ) + + value = obj.ShadowColor_; + + end % get.ShadowColor + + function set.ShadowColor( obj, value ) + + % Check + assert( isnumeric( value ) && isequal( size( value ), [1 3] ) && ... + all( isreal( value ) ) && all( value >= 0 ) && all( value <= 1 ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''ShadowColor'' must be an RGB triple.' ) + + % Set + obj.ShadowColor_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.ShadowColor + + function value = get.TabEnables( obj ) + + value = get( obj.Tabs, {'Enable'} ); + value(strcmp( value, 'inactive' )) = {'on'}; + + end % get.TabEnables + + function set.TabEnables( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Retrieve tabs + tabs = obj.Tabs; + tabListeners = obj.TabListeners; + + % Check + assert( iscellstr( value ) && ... + isequal( size( value ), size( tabs ) ) && ... + all( strcmp( value, 'on' ) | strcmp( value, 'off' ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''TabEnables'' should be a cell array of strings ''on'' or ''off'', one per tab.' ) + + % Set + tf = strcmp( value, 'on' ); + value(tf) = {'inactive'}; + for ii = 1:numel( tabs ) + tabs(ii).Enable = value{ii}; + tabListeners(ii).Enabled = tf(ii); + end + + % Show selected child + obj.showSelection() + + % Mark as dirty + obj.Dirty = true; + + end % set.TabEnables + + function value = get.TabLocation( obj ) + + value = obj.TabLocation_; + + end % get.TabLocation + + function set.TabLocation( obj, value ) + + % Check + assert( ischar( value ) && ... + any( strcmp( value, {'top','bottom'} ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''TabLocation'' should be ''top'' or ''bottom''.' ) + + % Set + obj.TabLocation_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.TabLocation + + function value = get.TabTitles( obj ) + + value = get( obj.Tabs, {'String'} ); + + end % get.TabTitles + + function set.TabTitles( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Retrieve tabs + tabs = obj.Tabs; + + % Check + assert( iscellstr( value ) && ... + isequal( size( value ), size( tabs ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''TabTitles'' should be a cell array of strings, one per tab.' ) + + % Set + n = numel( tabs ); + for ii = 1:n + tabs(ii).String = value{ii}; + end + + % Mark as dirty + obj.TabHeight = -1; + obj.Dirty = true; + + end % set.TabTitles + + function value = get.TabContextMenus( obj ) + + tabs = obj.Tabs; + n = numel( tabs ); + value = cell( [n 1] ); + for ii = 1:n + value{ii} = tabs(ii).UIContextMenu; + end + + end % get.TabContextMenus + + function set.TabContextMenus( obj, value ) + + tabs = obj.Tabs; + n = numel( tabs ); + for ii = 1:n + tabs(ii).UIContextMenu = value{ii}; + end + + end % set.TabContextMenus + + function value = get.TabWidth( obj ) + + value = obj.TabWidth_; + + end % get.TabWidth + + function set.TabWidth( obj, value ) + + % Check + assert( isa( value, 'double' ) && isscalar( value ) && ... + isreal( value ) && ~isinf( value ) && ... + ~isnan( value ) && value ~= 0, ... + 'uix:InvalidPropertyValue', ... + 'Property ''TabWidth'' must be a non-zero scalar.' ) + + % Set + obj.TabWidth_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.TabWidth + + end % accessors + + methods( Access = protected ) + + function redraw( obj ) + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + w = ceil( bounds(1) + bounds(3) ) - floor( bounds(1) ); % width + h = ceil( bounds(2) + bounds(4) ) - floor( bounds(2) ); % height + p = obj.Padding_; % padding + tabs = obj.Tabs; + n = numel( tabs ); % number of tabs + tH = obj.TabHeight; % tab height + if tH == -1 % cache stale, refresh + if n > 0 + cTabExtents = get( tabs, {'Extent'} ); + tabExtents = vertcat( cTabExtents{:} ); + tH = max( tabExtents(:,4) ); + end + tH = max( tH, obj.TabMinimumHeight ); % apply minimum + tH = ceil( tH ); % round up + obj.TabHeight = tH; % store + end + cH = max( [h - 2 * p - tH, 1] ); % contents height + switch obj.TabLocation_ + case 'top' + cY = 1 + p; % contents y + tY = cY + cH + p; % tab y + case 'bottom' + tY = 1; % tab y + cY = tY + tH + p; % contents y + end + cX = 1 + p; % contents x + cW = max( [w - 2 * p, 1] ); % contents width + tW = obj.TabWidth_; % tab width + dW = obj.DividerWidth; % tab divider width + if tW < 0 && n > 0 % relative + tW = max( ( w - (n+1) * dW ) / n, 1 ); + end + tW = ceil( tW ); % round up + for ii = 1:n + tabs(ii).Position = [1 + (ii-1) * tW + ii * dW, tY, tW, tH]; + end + obj.Dividers.Position = [0 tY w+1 tH]; + contentsPosition = [cX cY cW cH]; + + % Redraw tabs + obj.redrawTabs() + + % Redraw contents + selection = obj.Selection_; + if selection ~= 0 && strcmp( obj.TabEnables{selection}, 'on' ) + uix.setPosition( obj.Contents_(selection), contentsPosition, 'pixels' ) + end + + end % redraw + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Create new tab + n = numel( obj.Tabs ); + tab = matlab.ui.control.UIControl( 'Internal', true, ... + 'Parent', obj, 'Style', 'text', 'Enable', 'inactive', ... + 'Units', 'pixels', 'FontUnits', obj.FontUnits_, ... + 'FontSize', obj.FontSize_, 'FontName', obj.FontName_, ... + 'FontAngle', obj.FontAngle_, 'FontWeight', obj.FontWeight_, ... + 'ForegroundColor', obj.ForegroundColor_, ... + 'String', sprintf( 'Page %d', n + 1 ) ); + tabListener = event.listener( tab, 'ButtonDown', @obj.onTabClicked ); + obj.Tabs(n+1,:) = tab; + obj.TabListeners(n+1,:) = tabListener; + + % Mark as dirty + obj.TabHeight = -1; + + % Check for bug + if verLessThan( 'MATLAB', '8.5' ) && strcmp( child.Visible, 'off' ) + obj.G1218142 = true; + end + + % Select new content + oldSelection = obj.Selection_; + if numel( obj.Contents_ ) == 0 + newSelection = 1; + obj.Selection_ = newSelection; + else + newSelection = oldSelection; + end + + % Call superclass method + addChild@uix.mixin.Container( obj, child ) + + % Show selected child + obj.showSelection() + + % Notify selection change + if oldSelection ~= newSelection + obj.notify( 'SelectionChanged', ... + uix.SelectionData( oldSelection, newSelection ) ) + end + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Find index of removed child + contents = obj.Contents_; + index = find( contents == child ); + + % Remove tab + delete( obj.Tabs(index) ) + obj.Tabs(index,:) = []; + obj.TabListeners(index,:) = []; + + % Call superclass method + removeChild@uix.mixin.Panel( obj, child ) + + end % removeChild + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder + obj.Tabs = obj.Tabs(indices,:); + obj.TabListeners = obj.TabListeners(indices,:); + + % Call superclass method + reorder@uix.mixin.Panel( obj, indices ) + + end % reorder + + function reparent( obj, oldFigure, newFigure ) + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + if ~isequal( oldFigure, newFigure ) + contextMenus = obj.TabContextMenus; + for ii = 1:numel( contextMenus ) + contextMenu = contextMenus{ii}; + if ~isempty( contextMenu ) + contextMenu.Parent = newFigure; + end + end + end + + % Call superclass method + reparent@uix.mixin.Panel( obj, oldFigure, newFigure ) + + end % reparent + + function showSelection( obj ) + %showSelection Show selected child, hide the others + % + % c.showSelection() shows the selected child of the container + % c, and hides the others. + + % Call superclass method + showSelection@uix.mixin.Panel( obj ) + + % If not enabled, hide selected contents too + selection = obj.Selection_; + if selection ~= 0 && strcmp( obj.TabEnables{selection}, 'off' ) + child = obj.Contents_(selection); + child.Visible = 'off'; + if isa( child, 'matlab.graphics.axis.Axes' ) + child.ContentsVisible = 'off'; + end + % As a remedy for g1100294, move off-screen too + margin = 1000; + if isa( child, 'matlab.graphics.axis.Axes' ) ... + && strcmp(child.ActivePositionProperty, 'outerposition' ) + child.OuterPosition(1) = -child.OuterPosition(3)-margin; + else + child.Position(1) = -child.Position(3)-margin; + end + end + + end % showSelection + + end % template methods + + methods( Access = private ) + + function redrawTabs( obj ) + %redrawTabs Redraw tabs + % + % p.redrawTabs() redraws the tabs. + + % Get relevant properties + selection = obj.Selection_; + tabs = obj.Tabs; + t = numel( tabs ); + dividers = obj.Dividers; + + % Handle no tabs as a special case + if t == 0 + dividers.Visible = 'off'; % hide + return + end + + % Repaint tabs + backgroundColor = obj.BackgroundColor; + for ii = 1:t + tab = tabs(ii); + if ii == selection + tab.BackgroundColor = backgroundColor; + else + tab.BackgroundColor = obj.Tint * backgroundColor; + end + end + + % Repaint dividers + d = t + 1; + dividerNames = repmat( 'F', [d 2] ); % initialize + dividerNames(1,1) = 'E'; % end + dividerNames(end,2) = 'E'; % end + if selection ~= 0 + dividerNames(selection,2) = 'T'; % selected + dividerNames(selection+1,1) = 'T'; % selected + end + tH = obj.TabHeight; + assert( tH >= obj.TabMinimumHeight, 'uix:InvalidState', ... + 'Cannot redraw tabs with invalid TabHeight.' ) + tW = obj.Tabs(1).Position(3); + dW = obj.DividerWidth; + allCData = zeros( [tH 0 3] ); % initialize + map = [obj.ShadowColor; obj.BackgroundColor; ... + obj.Tint * obj.BackgroundColor; obj.HighlightColor;... + obj.ParentBackgroundColor]; + for ii = 1:d + % Select mask + iMask = obj.DividerMask.( dividerNames(ii,:) ); + % Resize + iData = repmat( iMask(5,:), [tH 1] ); + iData(1:4,:) = iMask(1:4,:); + iData(end-3:end,:) = iMask(end-3:end,:); + % Convert to RGB + cData = ind2rgb( iData+1, map ); + % Orient + switch obj.TabLocation_ + case 'bottom' + cData = flipud( cData ); + end + % Insert + allCData(1:tH,(ii-1)*(dW+tW)+(1:dW),:) = cData; % center + if ii > 1 % extend left under transparent uicontrol edge + allCData(1:tH,(ii-1)*(dW+tW),:) = cData(:,1,:); + end + if ii < d % extend right under transparent uicontrol edge + allCData(1:tH,(ii-1)*(dW+tW)+dW+1,:) = cData(:,end,:); + end + end + dividers.CData = allCData; % paint + dividers.BackgroundColor = obj.ParentBackgroundColor; + dividers.Visible = 'on'; % show + + end % redrawTabs + + end % helper methods + + methods( Access = private ) + + function onTabClicked( obj, source, ~ ) + + % Update selection + oldSelection = obj.Selection_; + newSelection = find( source == obj.Tabs ); + if oldSelection == newSelection, return, end % abort set + obj.Selection_ = newSelection; + + % Show selected child + obj.showSelection() + + % Mark as dirty + obj.Dirty = true; + + % Notify selection change + obj.notify( 'SelectionChanged', ... + uix.SelectionData( oldSelection, newSelection ) ) + + end % onTabClicked + + function onBackgroundColorChange( obj, ~, ~ ) + + % Mark as dirty + obj.Dirty = true; + + end % onBackgroundColorChange + + function onSelectionChanged( obj, source, eventData ) + + % Call callback + callback = obj.SelectionChangedFcn; + if ischar( callback ) && isequal( callback, '' ) + % do nothing + elseif ischar( callback ) + feval( callback, source, eventData ) + elseif isa( callback, 'function_handle' ) + callback( source, eventData ) + elseif iscell( callback ) + feval( callback{1}, source, eventData, callback{2:end} ) + end + + end % onSelectionChanged + + function onParentChanged( obj, ~, ~ ) + + % Update ParentBackgroundColor and ParentBackgroundColor + if isprop( obj.Parent, 'BackgroundColor' ) + prop = 'BackgroundColor'; + elseif isprop( obj.Parent, 'Color' ) + prop = 'Color'; + else + prop = []; + end + + if ~isempty( prop ) + obj.ParentBackgroundColorListener = event.proplistener( obj.Parent, ... + findprop( obj.Parent, prop ), 'PostSet', ... + @( src, evt ) obj.updateParentBackgroundColor( prop ) ); + else + obj.ParentBackgroundColorListener = []; + end + + obj.updateParentBackgroundColor( prop ); + + end % onParentChanged + + function updateParentBackgroundColor( obj, prop ) + + if isempty( prop ) + obj.ParentBackgroundColor = obj.BackgroundColor; + else + obj.ParentBackgroundColor = obj.Parent.(prop); + end + + % Mark as dirty + obj.Dirty = true; + + end + + end % event handlers + + methods( Access = private, Static ) + + function mask = getDividerMask() + %getDividerMask Get divider image data + % + % m = uix.TabPanel.getDividerMask() returns the image masks + % for tab panel dividers. Mask entries are 0 (shadow), 1 + % (background), 2 (tint) and 3 (highlight). + + mask.EF = indexColor( uix.loadIcon( 'tab_NoEdge_NotSelected.png' ) ); + mask.ET = indexColor( uix.loadIcon( 'tab_NoEdge_Selected.png' ) ); + mask.FE = indexColor( uix.loadIcon( 'tab_NotSelected_NoEdge.png' ) ); + mask.FF = indexColor( uix.loadIcon( 'tab_NotSelected_NotSelected.png' ) ); + mask.FT = indexColor( uix.loadIcon( 'tab_NotSelected_Selected.png' ) ); + mask.TE = indexColor( uix.loadIcon( 'tab_Selected_NoEdge.png' ) ); + mask.TF = indexColor( uix.loadIcon( 'tab_Selected_NotSelected.png' ) ); + + function mask = indexColor( rgbMap ) + %indexColor Returns a map of index given an RGB map + % + % mask = indexColor( rgbMap ) returns a mask of color + % index based on the supplied rgbMap. + % black : 0 + % red : 1 + % yellow : 2 + % white : 3 + % blue : 4 + mask = nan( size( rgbMap, 1 ),size( rgbMap, 2 ) ); + % Black + colorIndex = isColor( rgbMap, [0 0 0] ); + mask(colorIndex) = 0; + % Red + colorIndex = isColor( rgbMap, [1 0 0] ); + mask(colorIndex) = 1; + % Yellow + colorIndex = isColor( rgbMap, [1 1 0] ); + mask(colorIndex) = 2; + % White + colorIndex = isColor( rgbMap, [1 1 1] ); + mask(colorIndex) = 3; + % Blue + colorIndex = isColor( rgbMap, [0 0 1] ); + mask(colorIndex) = 4; + % Nested + function boolMap = isColor( map, color ) + %isColor Return a map of boolean where map is equal to color + boolMap = all( bsxfun( @eq, map, permute( color, [1 3 2] ) ), 3 ); + end + end + + end % getDividerMask + + end % static helper methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/Text.m b/Required packages/layout/+uix/Text.m new file mode 100644 index 0000000..8a32f94 --- /dev/null +++ b/Required packages/layout/+uix/Text.m @@ -0,0 +1,546 @@ +classdef Text < matlab.mixin.SetGet + %uix.Text Text control + % + % t = uix.Text(p1,v1,p2,v2,...) constructs a text control and sets + % parameter p1 to value v1, etc. + % + % A text control adds functionality to a uicontrol of Style text: + % * Set VerticalAlignment to 'top', 'middle' or 'bottom' + % * Fire a Callback when the user clicks on the text + % + % See also: uicontrol + + % Copyright 2009-2015 The MathWorks, Inc. + % $Revision: 1435 $ $Date: 2016-11-17 17:50:34 +0000 (Thu, 17 Nov 2016) $ + + properties( Dependent ) + BackgroundColor + end + + properties( Dependent, SetAccess = private ) + BeingDeleted + end + + properties( Dependent ) + Callback + DeleteFcn + Enable + end + + properties( Dependent, SetAccess = private ) + Extent + end + + properties( Dependent ) + FontAngle + FontName + FontSize + FontUnits + FontWeight + ForegroundColor + HandleVisibility + HorizontalAlignment + Parent + Position + String + Tag + TooltipString + end + + properties( Dependent, SetAccess = private ) + Type + end + + properties( Dependent ) + UIContextMenu + Units + UserData + VerticalAlignment + Visible + end + + properties( Access = private ) + Container % container + Checkbox % checkbox, used for label + Screen % text, used for covering checkbox + VerticalAlignment_ = 'top' % backing for VerticalAlignment + Dirty = false % flag + FigureObserver % observer + FigureListener % listener + end + + properties( Constant, Access = private ) + Margin = checkBoxLabelOffset() % checkbox size + end + + methods + + function obj = Text( varargin ) + %uix.Text Text control + % + % t = uix.Text(p1,v1,p2,v2,...) constructs a text control and + % sets parameter p1 to value v1, etc. + + % Create graphics + container = uicontainer( 'Parent', [], ... + 'Units', get( 0, 'DefaultUicontrolUnits' ), ... + 'Position', get( 0, 'DefaultUicontrolPosition' ), ... + 'SizeChangedFcn', @obj.onResized ); + checkbox = uicontrol( 'Parent', container, ... + 'HandleVisibility', 'off', ... + 'Style', 'checkbox', 'Units', 'pixels', ... + 'HorizontalAlignment', 'center', ... + 'Enable', 'inactive' ); + screen = uicontrol( 'Parent', container, ... + 'HandleVisibility', 'off', ... + 'Style', 'text', 'Units', 'pixels' ); + + % Create observers and listeners + figureObserver = uix.FigureObserver( container ); + figureListener = event.listener( figureObserver, ... + 'FigureChanged', @obj.onFigureChanged ); + + % Store properties + obj.Container = container; + obj.Checkbox = checkbox; + obj.Screen = screen; + obj.FigureObserver = figureObserver; + obj.FigureListener = figureListener; + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + function delete( obj ) + %delete Destructor + + delete( obj.Container ) + + end % destructor + + end % structors + + methods + + function value = get.BackgroundColor( obj ) + + value = obj.Checkbox.BackgroundColor; + + end % get.BackgroundColor + + function set.BackgroundColor( obj, value ) + + obj.Container.BackgroundColor = value; + obj.Checkbox.BackgroundColor = value; + obj.Screen.BackgroundColor = value; + + end % set.BackgroundColor + + function value = get.BeingDeleted( obj ) + + value = obj.Checkbox.BeingDeleted; + + end % get.BeingDeleted + + function value = get.Callback( obj ) + + value = obj.Checkbox.Callback; + + end % get.Callback + + function set.Callback( obj, value ) + + obj.Checkbox.Callback = value; + + end % set.Callback + + function value = get.DeleteFcn( obj ) + + value = obj.Checkbox.DeleteFcn; + + end % get.DeleteFcn + + function set.DeleteFcn( obj, value ) + + obj.Checkbox.DeleteFcn = value; + + end % set.DeleteFcn + + function value = get.Enable( obj ) + + value = obj.Checkbox.Enable; + + end % get.Enable + + function set.Enable( obj, value ) + + obj.Checkbox.Enable = value; + + end % set.Enable + + function value = get.Extent( obj ) + + value = obj.Checkbox.Extent; + + end % get.Extent + + function value = get.FontAngle( obj ) + + value = obj.Checkbox.FontAngle; + + end % get.FontAngle + + function set.FontAngle( obj, value ) + + % Set + obj.Checkbox.FontAngle = value; + + % Mark as dirty + obj.setDirty() + + end % set.FontAngle + + function value = get.FontName( obj ) + + value = obj.Checkbox.FontName; + + end % get.FontName + + function set.FontName( obj, value ) + + % Set + obj.Checkbox.FontName = value; + + % Mark as dirty + obj.setDirty() + + end % set.FontName + + function value = get.FontSize( obj ) + + value = obj.Checkbox.FontSize; + + end % get.FontSize + + function set.FontSize( obj, value ) + + % Set + obj.Checkbox.FontSize = value; + + % Mark as dirty + obj.setDirty() + + end % set.FontSize + + function value = get.FontUnits( obj ) + + value = obj.Checkbox.FontUnits; + + end % get.FontUnits + + function set.FontUnits( obj, value ) + + obj.Checkbox.FontUnits = value; + + end % set.FontUnits + + function value = get.FontWeight( obj ) + + value = obj.Checkbox.FontWeight; + + end % get.FontWeight + + function set.FontWeight( obj, value ) + + % Set + obj.Checkbox.FontWeight = value; + + % Mark as dirty + obj.setDirty() + + end % set.FontWeight + + function value = get.ForegroundColor( obj ) + + value = obj.Checkbox.ForegroundColor; + + end % get.ForegroundColor + + function set.ForegroundColor( obj, value ) + + obj.Checkbox.ForegroundColor = value; + + end % set.ForegroundColor + + function value = get.HandleVisibility( obj ) + + value = obj.Container.HandleVisibility; + + end % get.HandleVisibility + + function set.HandleVisibility( obj, value ) + + obj.Container.HandleVisibility = value; + + end % set.HandleVisibility + + function value = get.HorizontalAlignment( obj ) + + value = obj.Checkbox.HorizontalAlignment; + + end % get.HorizontalAlignment + + function set.HorizontalAlignment( obj, value ) + + % Set + obj.Checkbox.HorizontalAlignment = value; + + % Mark as dirty + obj.setDirty() + + end % set.HorizontalAlignment + + function value = get.Parent( obj ) + + value = obj.Container.Parent; + + end % get.Parent + + function set.Parent( obj, value ) + + obj.Container.Parent = value; + + end % set.Parent + + function value = get.Position( obj ) + + value = obj.Container.Position; + + end % get.Position + + function set.Position( obj, value ) + + obj.Container.Position = value; + + end % set.Position + + function value = get.String( obj ) + + value = obj.Checkbox.String; + + end % get.String + + function set.String( obj, value ) + + % Set + obj.Checkbox.String = value; + + % Mark as dirty + obj.setDirty() + + end % set.String + + function value = get.Tag( obj ) + + value = obj.Checkbox.Tag; + + end % get.Tag + + function set.Tag( obj, value ) + + obj.Checkbox.Tag = value; + + end % set.Tag + + function value = get.TooltipString( obj ) + + value = obj.Checkbox.TooltipString; + + end % get.TooltipString + + function set.TooltipString( obj, value ) + + obj.Checkbox.TooltipString = value; + + end % set.TooltipString + + function value = get.Type( obj ) + + value = obj.Checkbox.Type; + + end % get.Type + + function value = get.UIContextMenu( obj ) + + value = obj.Checkbox.UIContextMenu; + + end % get.UIContextMenu + + function set.UIContextMenu( obj, value ) + + obj.Checkbox.UIContextMenu = value; + + end % set.UIContextMenu + + function value = get.Units( obj ) + + value = obj.Container.Units; + + end % get.Units + + function set.Units( obj, value ) + + obj.Container.Units = value; + + end % set.Units + + function value = get.UserData( obj ) + + value = obj.Checkbox.UserData; + + end % get.UserData + + function set.UserData( obj, value ) + + obj.Checkbox.UserData = value; + + end % set.UserData + + function value = get.VerticalAlignment( obj ) + + value = obj.VerticalAlignment_; + + end % get.VerticalAlignment + + function set.VerticalAlignment( obj, value ) + + % Check + assert( ischar( value ) && ... + any( strcmp( value, {'top','middle','bottom'} ) ), ... + 'uix:InvalidPropertyValue', ... + 'Property ''VerticalAlignment'' must be ''top'', ''middle'' or ''bottom''.' ) + + % Set + obj.VerticalAlignment_ = value; + + % Mark as dirty + obj.setDirty() + + end % set.VerticalAlignment + + function value = get.Visible( obj ) + + value = obj.Container.Visible; + + end % get.Visible + + function set.Visible( obj, value ) + + obj.Container.Visible = value; + + end % set.Visible + + end % accessors + + methods( Access = private ) + + function onResized( obj, ~, ~ ) + %onResized Event handler + + % Rooted, so redraw + obj.redraw() + + end % onResized + + function onFigureChanged( obj, ~, eventData ) + + % If rooted, redraw + if isempty( eventData.OldFigure ) && ... + ~isempty( eventData.NewFigure ) && obj.Dirty + obj.redraw() + end + + end % onFigureChanged + + end % event handlers + + methods( Access = private ) + + function setDirty( obj ) + %setDirty Mark as dirty + % + % t.setDirty() marks the text control t as dirty. If the text + % control is rooted then it is redrawn immediately. If not + % then the redraw is queued for when it is next rooted. + + if isempty( obj.FigureObserver.Figure ) + obj.Dirty = true; % set flag + else + obj.Dirty = false; % unset flag + obj.redraw() % redraw + end + + end % setDirty + + function redraw( obj ) + %redraw Redraw + % + % t.redraw() redraws the text control t. Note that this + % requires the text control to be rooted. Methods should + % request redraws using setDirty, rather than calling redraw + % directly. + + c = obj.Container; + b = obj.Checkbox; + s = obj.Screen; + bo = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', c ); % bounds + m = obj.Margin; + e = b.Extent; + switch b.HorizontalAlignment + case 'left' + x = 1 - m; + case 'center' + x = 1 + bo(3)/2 - e(3)/2 - m; + case 'right' + x = 1 + bo(3) - e(3) - m; + end + w = e(3) + m; + switch obj.VerticalAlignment_ + case 'top' + y = 1 + bo(4) - e(4); + case 'middle' + y = 1 + bo(4)/2 - e(4)/2; + case 'bottom' + y = 1; + end + h = e(4); + b.Position = [x y w h]; + s.Position = [x y m h]; + + end % redraw + + end % helpers + +end % classdef + +function o = checkBoxLabelOffset() +%checkBoxLabelOffset Horizontal offset to checkbox label + +if verLessThan( 'MATLAB', '8.6' ) % R2015b + o = 18; +else + o = 16; +end + +end % margin \ No newline at end of file diff --git a/Required packages/layout/+uix/VBox.m b/Required packages/layout/+uix/VBox.m new file mode 100644 index 0000000..4237ae7 --- /dev/null +++ b/Required packages/layout/+uix/VBox.m @@ -0,0 +1,194 @@ +classdef VBox < uix.Box + %uix.VBox Vertical box + % + % b = uix.VBox(p1,v1,p2,v2,...) constructs a vertical box and sets + % parameter p1 to value v1, etc. + % + % A vertical box lays out contents from top to bottom. + % + % See also: uix.HBox, uix.Grid, uix.VButtonBox, uix.VBoxFlex + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + properties( Access = public, Dependent, AbortSet ) + Heights % heights of contents, in pixels and/or weights + MinimumHeights % minimum heights of contents, in pixels + end + + properties( Access = protected ) + Heights_ = zeros( [0 1] ) % backing for Heights + MinimumHeights_ = zeros( [0 1] ) % backing for MinimumHeights + end + + methods + + function obj = VBox( varargin ) + %uix.VBox Vertical box constructor + % + % b = uix.VBox() constructs a horizontal box. + % + % b = uix.VBox(p1,v1,p2,v2,...) sets parameter p1 to value v1, + % etc. + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods + + function value = get.Heights( obj ) + + value = obj.Heights_; + + end % get.Heights + + function set.Heights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''Heights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + ~any( isnan( value ) ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''Heights'' must be real and finite.' ) + assert( isequal( size( value ), size( obj.Contents_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''Heights'' must match size of contents.' ) + + % Set + obj.Heights_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.Heights + + function value = get.MinimumHeights( obj ) + + value = obj.MinimumHeights_; + + end % get.MinimumHeights + + function set.MinimumHeights( obj, value ) + + % For those who can't tell a column from a row... + if isrow( value ) + value = transpose( value ); + end + + % Check + assert( isa( value, 'double' ), 'uix:InvalidPropertyValue', ... + 'Property ''MinimumHeights'' must be of type double.' ) + assert( all( isreal( value ) ) && ~any( isinf( value ) ) && ... + all( value >= 0 ), 'uix:InvalidPropertyValue', ... + 'Elements of property ''MinimumHeights'' must be non-negative.' ) + assert( isequal( size( value ), size( obj.Heights_ ) ), ... + 'uix:InvalidPropertyValue', ... + 'Size of property ''MinimumHeights'' must match size of contents.' ) + + % Set + obj.MinimumHeights_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.MinimumHeights + + end % accessors + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw + % + % c.redraw() redraws the container c. + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + heights = obj.Heights_; + minimumHeights = obj.MinimumHeights_; + padding = obj.Padding_; + spacing = obj.Spacing_; + r = numel( heights ); + xPositions = [padding + 1, max( bounds(3) - 2 * padding, 1 )]; + xPositions = repmat( xPositions, [r 1] ); + ySizes = uix.calcPixelSizes( bounds(4), heights, ... + minimumHeights, padding, spacing ); + yPositions = [bounds(4) - cumsum( ySizes ) - padding - ... + spacing * transpose( 0:r-1 ) + 1, ySizes]; + positions = [xPositions(:,1), yPositions(:,1), ... + xPositions(:,2), yPositions(:,2)]; + + % Set positions + children = obj.Contents_; + for ii = 1:numel( children ) + uix.setPosition( children(ii), positions(ii,:), 'pixels' ) + end + + end % redraw + + function addChild( obj, child ) + %addChild Add child + % + % c.addChild(d) adds the child d to the container c. + + % Add to sizes + obj.Heights_(end+1,:) = -1; + obj.MinimumHeights_(end+1,:) = 1; + + % Call superclass method + addChild@uix.Box( obj, child ) + + end % addChild + + function removeChild( obj, child ) + %removeChild Remove child + % + % c.removeChild(d) removes the child d from the container c. + + % Remove from sizes + tf = obj.Contents_ == child; + obj.Heights_(tf,:) = []; + obj.MinimumHeights_(tf,:) = []; + + % Call superclass method + removeChild@uix.Box( obj, child ) + + end % removeChild + + function reorder( obj, indices ) + %reorder Reorder contents + % + % c.reorder(i) reorders the container contents using indices + % i, c.Contents = c.Contents(i). + + % Reorder + obj.Heights_ = obj.Heights_(indices,:); + obj.MinimumHeights_ = obj.MinimumHeights_(indices,:); + + % Call superclass method + reorder@uix.Box( obj, indices ) + + end % reorder + + end % template methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/VBoxFlex.m b/Required packages/layout/+uix/VBoxFlex.m new file mode 100644 index 0000000..9a716d9 --- /dev/null +++ b/Required packages/layout/+uix/VBoxFlex.m @@ -0,0 +1,349 @@ +classdef VBoxFlex < uix.VBox & uix.mixin.Flex + %uix.VBoxFlex Flexible vertical box + % + % b = uix.VBoxFlex(p1,v1,p2,v2,...) constructs a flexible vertical box + % and sets parameter p1 to value v1, etc. + % + % A vertical box lays out contents from top to bottom. Users can + % resize contents by dragging the dividers. + % + % See also: uix.HBoxFlex, uix.GridFlex, uix.VBox, uix.VButtonBox + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + properties( Access = public, Dependent, AbortSet ) + DividerMarkings % divider markings [on|off] + end + + properties( Access = private ) + RowDividers = uix.Divider.empty( [0 1] ) % row dividers + FrontDivider % front divider + DividerMarkings_ = 'on' % backing for DividerMarkings + MousePressListener = event.listener.empty( [0 0] ) % mouse press listener + MouseReleaseListener = event.listener.empty( [0 0] ) % mouse release listener + MouseMotionListener = event.listener.empty( [0 0] ) % mouse motion listener + ActiveDivider = 0 % active divider index + ActiveDividerPosition = [NaN NaN NaN NaN] % active divider position + MousePressLocation = [NaN NaN] % mouse press location + BackgroundColorListener % background color listener + end + + methods + + function obj = VBoxFlex( varargin ) + %uix.VBoxFlex Flexible vertical box constructor + % + % b = uix.VBoxFlex() constructs a flexible vertical box. + % + % b = uix.VBoxFlex(p1,v1,p2,v2,...) sets parameter p1 to value + % v1, etc. + + % Create front divider + frontDivider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'horizontal', ... + 'BackgroundColor', obj.BackgroundColor * 0.75, ... + 'Visible', 'off' ); + + % Create listeners + backgroundColorListener = event.proplistener( obj, ... + findprop( obj, 'BackgroundColor' ), 'PostSet', ... + @obj.onBackgroundColorChange ); + + % Store properties + obj.FrontDivider = frontDivider; + obj.BackgroundColorListener = backgroundColorListener; + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods + + function value = get.DividerMarkings( obj ) + + value = obj.DividerMarkings_; + + end % get.DividerMarkings + + function set.DividerMarkings( obj, value ) + + % Check + assert( ischar( value ) && any( strcmp( value, {'on','off'} ) ), ... + 'uix:InvalidArgument', ... + 'Property ''DividerMarkings'' must be ''on'' or ''off'.' ) + + % Set + obj.DividerMarkings_ = value; + + % Mark as dirty + obj.Dirty = true; + + end % set.DividerMarkings + + end % accessors + + methods( Access = protected ) + + function onMousePress( obj, source, eventData ) + %onMousePress Handler for WindowMousePress events + + % Check whether mouse is over a divider + loc = find( obj.RowDividers.isMouseOver( eventData ) ); + if isempty( loc ), return, end + + % Capture state at button down + divider = obj.RowDividers(loc); + obj.ActiveDivider = loc; + obj.ActiveDividerPosition = divider.Position; + root = groot(); + obj.MousePressLocation = root.PointerLocation; + + % Make sure the pointer is appropriate + obj.updateMousePointer( source, eventData ); + + % Activate divider + frontDivider = obj.FrontDivider; + frontDivider.Position = divider.Position; + divider.Visible = 'off'; + frontDivider.Parent = []; + frontDivider.Parent = obj; + frontDivider.Visible = 'on'; + + end % onMousePress + + function onMouseRelease( obj, ~, ~ ) + %onMousePress Handler for WindowMouseRelease events + + % Compute new positions + loc = obj.ActiveDivider; + if loc > 0 + root = groot(); + delta = root.PointerLocation(2) - obj.MousePressLocation(2); + ih = loc; + jh = loc + 1; + ic = loc; + jc = loc + 1; + divider = obj.RowDividers(loc); + contents = obj.Contents_; + oldPixelHeights = [contents(ic).Position(4); contents(jc).Position(4)]; + minimumHeights = obj.MinimumHeights_(ih:jh,:); + if delta < 0 % limit to minimum distance from lower neighbor + delta = max( delta, minimumHeights(2) - oldPixelHeights(2) ); + else % limit to minimum distance from upper neighbor + delta = min( delta, oldPixelHeights(1) - minimumHeights(1) ); + end + oldHeights = obj.Heights_(loc:loc+1); + newPixelHeights = oldPixelHeights - delta * [1;-1]; + if oldHeights(1) < 0 && oldHeights(2) < 0 % weight, weight + newHeights = oldHeights .* newPixelHeights ./ oldPixelHeights; + elseif oldHeights(1) < 0 && oldHeights(2) >= 0 % weight, pixels + newHeights = [oldHeights(1) * newPixelHeights(1) / ... + oldPixelHeights(1); newPixelHeights(2)]; + elseif oldHeights(1) >= 0 && oldHeights(2) < 0 % pixels, weight + newHeights = [newPixelHeights(1); oldHeights(2) * ... + newPixelHeights(2) / oldPixelHeights(2)]; + else % sizes(1) >= 0 && sizes(2) >= 0 % pixels, pixels + newHeights = newPixelHeights; + end + obj.Heights_(loc:loc+1) = newHeights; + else + return + end + + % Deactivate divider + obj.FrontDivider.Visible = 'off'; + divider.Visible = 'on'; + + % Reset state at button down + obj.ActiveDivider = 0; + obj.ActiveDividerPosition = [NaN NaN NaN NaN]; + obj.MousePressLocation = [NaN NaN]; + + % Mark as dirty + obj.Dirty = true; + + end % onMouseRelease + + function onMouseMotion( obj, source, eventData ) + %onMouseMotion Handler for WindowMouseMotion events + + loc = obj.ActiveDivider; + if loc == 0 % hovering, update pointer + obj.updateMousePointer( source, eventData ); + else % dragging row divider + root = groot(); + delta = root.PointerLocation(2) - obj.MousePressLocation(2); + ih = loc; + jh = loc + 1; + ic = loc; + jc = loc + 1; + contents = obj.Contents_; + oldPixelHeights = [contents(ic).Position(4); contents(jc).Position(4)]; + minimumHeights = obj.MinimumHeights_(ih:jh,:); + if delta < 0 % limit to minimum distance from lower neighbor + delta = max( delta, minimumHeights(2) - oldPixelHeights(2) ); + else % limit to minimum distance from upper neighbor + delta = min( delta, oldPixelHeights(1) - minimumHeights(1) ); + end + obj.FrontDivider.Position = ... + obj.ActiveDividerPosition + [0 delta 0 0]; + end + + end % onMouseMotion + + function onBackgroundColorChange( obj, ~, ~ ) + %onBackgroundColorChange Handler for BackgroundColor changes + + backgroundColor = obj.BackgroundColor; + highlightColor = min( [backgroundColor / 0.75; 1 1 1] ); + shadowColor = max( [backgroundColor * 0.75; 0 0 0] ); + rowDividers = obj.RowDividers; + for ii = 1:numel( rowDividers ) + rowDivider = rowDividers(ii); + rowDivider.BackgroundColor = backgroundColor; + rowDivider.HighlightColor = highlightColor; + rowDivider.ShadowColor = shadowColor; + end + frontDivider = obj.FrontDivider; + frontDivider.BackgroundColor = shadowColor; + + end % onBackgroundColorChange + + end % event handlers + + methods( Access = protected ) + + function redraw( obj ) + %redraw Redraw contents + % + % c.redraw() redraws the container c. + + % Call superclass method + redraw@uix.VBox( obj ) + + % Create or destroy row dividers + q = numel( obj.RowDividers ); % current number of dividers + r = max( [numel( obj.Heights_ )-1 0] ); % required number of dividers + if q < r % create + for ii = q+1:r + divider = uix.Divider( 'Parent', obj, ... + 'Orientation', 'horizontal', ... + 'BackgroundColor', obj.BackgroundColor ); + obj.RowDividers(ii,:) = divider; + end + elseif q > r % destroy + % Destroy dividers + delete( obj.RowDividers(r+1:q,:) ) + obj.RowDividers(r+1:q,:) = []; + % Update pointer + if r == 0 && strcmp( obj.Pointer, 'top' ) + obj.unsetPointer() + end + end + + % Compute container bounds + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + + % Retrieve size properties + heights = obj.Heights_; + minimumHeights = obj.MinimumHeights_; + padding = obj.Padding_; + spacing = obj.Spacing_; + + % Compute row divider positions + xRowPositions = [padding + 1, max( bounds(3) - 2 * padding, 1 )]; + xRowPositions = repmat( xRowPositions, [r 1] ); + yRowSizes = uix.calcPixelSizes( bounds(4), heights, ... + minimumHeights, padding, spacing ); + yRowPositions = [bounds(4) - cumsum( yRowSizes(1:r,:) ) - padding - ... + spacing * transpose( 1:r ) + 1, repmat( spacing, [r 1] )]; + rowPositions = [xRowPositions(:,1), yRowPositions(:,1), ... + xRowPositions(:,2), yRowPositions(:,2)]; + + % Position row dividers + for ii = 1:r + rowDivider = obj.RowDividers(ii); + rowDivider.Position = rowPositions(ii,:); + switch obj.DividerMarkings_ + case 'on' + rowDivider.Markings = rowPositions(ii,3)/2; + case 'off' + rowDivider.Markings = zeros( [0 1] ); + end + end + + end % redraw + + function reparent( obj, oldFigure, newFigure ) + %reparent Reparent container + % + % c.reparent(a,b) reparents the container c from the figure a + % to the figure b. + + % Update listeners + if isempty( newFigure ) + mousePressListener = event.listener.empty( [0 0] ); + mouseReleaseListener = event.listener.empty( [0 0] ); + mouseMotionListener = event.listener.empty( [0 0] ); + else + mousePressListener = event.listener( newFigure, ... + 'WindowMousePress', @obj.onMousePress ); + mouseReleaseListener = event.listener( newFigure, ... + 'WindowMouseRelease', @obj.onMouseRelease ); + mouseMotionListener = event.listener( newFigure, ... + 'WindowMouseMotion', @obj.onMouseMotion ); + end + obj.MousePressListener = mousePressListener; + obj.MouseReleaseListener = mouseReleaseListener; + obj.MouseMotionListener = mouseMotionListener; + + % Call superclass method + reparent@uix.VBox( obj, oldFigure, newFigure ) + + % Update pointer + if ~isempty( oldFigure ) && ~strcmp( obj.Pointer, 'unset' ) + obj.unsetPointer() + end + + end % reparent + + end % template methods + + methods( Access = protected ) + + function updateMousePointer ( obj, source, eventData ) + + oldPointer = obj.Pointer; + if any( obj.RowDividers.isMouseOver( eventData ) ) + newPointer = 'top'; + else + newPointer = 'unset'; + end + switch newPointer + case oldPointer % no change + % do nothing + case 'unset' % change, unset + obj.unsetPointer() + otherwise % change, set + obj.setPointer( source, newPointer ) + end + + end % updateMousePointer + + end % helpers methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/VButtonBox.m b/Required packages/layout/+uix/VButtonBox.m new file mode 100644 index 0000000..83a7f13 --- /dev/null +++ b/Required packages/layout/+uix/VButtonBox.m @@ -0,0 +1,98 @@ +classdef VButtonBox < uix.ButtonBox + %uix.VButtonBox Vertical button box + % + % b = uix.VButtonBox(p1,v1,p2,v2,...) constructs a vertical button box + % and sets parameter p1 to value v1, etc. + % + % A vertical button box lays out equally sized buttons from top to + % bottom. + % + % See also: uix.HButtonBox + + % Copyright 2009-2016 The MathWorks, Inc. + % $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + + methods + + function obj = VButtonBox( varargin ) + %uix.VButtonBox Vertical button box constructor + % + % b = uix.VButtonBox() constructs a vertical button box. + % + % b = uix.VButtonBox(p1,v1,p2,v2,...) sets parameter p1 to + % value v1, etc. + + % Set properties + if nargin > 0 + try + assert( rem( nargin, 2 ) == 0, 'uix:InvalidArgument', ... + 'Parameters and values must be provided in pairs.' ) + set( obj, varargin{:} ) + catch e + delete( obj ) + e.throwAsCaller() + end + end + + end % constructor + + end % structors + + methods( Access = protected ) + + function redraw( obj ) + + % Compute positions + bounds = hgconvertunits( ancestor( obj, 'figure' ), ... + [0 0 1 1], 'normalized', 'pixels', obj ); + buttonSize = obj.ButtonSize_; + padding = obj.Padding_; + spacing = obj.Spacing_; + r = numel( obj.Contents_ ); + if 2 * padding + buttonSize(1) > bounds(3) + xSizes = repmat( uix.calcPixelSizes( bounds(3), -1, 1, ... + padding, spacing ), [r 1] ); % shrink to fit + else + xSizes = repmat( buttonSize(1), [r 1] ); + end + switch obj.HorizontalAlignment + case 'left' + xPositions = [repmat( padding, [r 1] ) + 1, xSizes]; + case 'center' + xPositions = [(bounds(3) - xSizes) / 2 + 1, xSizes]; + case 'right' + xPositions = [bounds(3) - xSizes - padding + 1, xSizes]; + end + if 2 * padding + (r-1) * spacing + r * buttonSize(2) > bounds(4) + ySizes = uix.calcPixelSizes( bounds(4), -ones( [r 1] ), ... + ones( [r 1] ), padding, spacing ); % shrink to fit + else + ySizes = repmat( buttonSize(2), [r 1] ); + end + switch obj.VerticalAlignment + case 'top' + yPositions = [bounds(4) - padding - cumsum( ySizes ) - ... + spacing * transpose( 0:r-1 ) + 1, ySizes]; + case 'middle' + yPositions = [bounds(4) / 2 + sum( ySizes ) / 2 + ... + spacing * (r-1) / 2 - cumsum( ySizes ) - ... + spacing * transpose( 0:r-1 ) + 1, ySizes]; + case 'bottom' + yPositions = [sum( ySizes ) + spacing * (r-1) - ... + cumsum( ySizes ) - spacing * transpose( 0:r-1 ) + ... + padding + 1, ySizes]; + end + positions = [xPositions(:,1), yPositions(:,1), ... + xPositions(:,2), yPositions(:,2)]; + + % Set positions + children = obj.Contents_; + for ii = 1:numel( children ) + uix.setPosition( children(ii), positions(ii,:), 'pixels' ) + end + + end % redraw + + end % template methods + +end % classdef \ No newline at end of file diff --git a/Required packages/layout/+uix/calcPixelSizes.m b/Required packages/layout/+uix/calcPixelSizes.m new file mode 100644 index 0000000..4035147 --- /dev/null +++ b/Required packages/layout/+uix/calcPixelSizes.m @@ -0,0 +1,47 @@ +function pSizes = calcPixelSizes( pTotal, mSizes, pMinima, pPadding, pSpacing ) +%calcPixelSizes Calculate child sizes in pixels +% +% pSizes = uix.calcPixelSizes(total,mSizes,minSizes,padding,spacing) +% computes child sizes (in pixels) given total available size (in pixels), +% child sizes (in pixels and/or relative), minimum child sizes (in +% pixels), padding (in pixels) and spacing (in pixels). +% +% Notes: +% * All children are at least as large as the minimum specified size +% * Relative sizes are respected for children larger than then minimum +% specified size +% * Children may extend beyond the total available size if the minimum +% sizes, padding and spacing are too large + +% Copyright 2009-2015 The MathWorks, Inc. +% $Revision: 1182 $ $Date: 2015-12-07 14:27:30 -0500 (Mon, 07 Dec 2015) $ + +% Initialize +pSizes = NaN( size( mSizes ) ); % output +n = numel( mSizes ); % need this later + +% Apply absolute sizes +a = mSizes >= 0; % absolute +pSizes(a) = max( mSizes(a), pMinima(a) ); + +while true + + u = isnan( pSizes ); % unsolved + pUnsolvedTotal = pTotal - max( (n-1), 0 ) * pSpacing ... + - 2 * sign( n ) * pPadding - sum( pSizes(~u) ); + pUnsolvedSizes = mSizes(u) / sum( mSizes(u) ) * pUnsolvedTotal; + pUnsolvedMinima = pMinima(u); + s = pUnsolvedSizes < pUnsolvedMinima; % small + if any( s ) + pUnsolvedSizes(s) = pUnsolvedMinima(s); + pUnsolvedSizes(~s) = NaN; + pSizes(u) = pUnsolvedSizes; + % repeat + else + pSizes(u) = pUnsolvedSizes; + break % done + end + +end + +end % calcPixelSizes \ No newline at end of file diff --git a/Required packages/layout/+uix/loadIcon.m b/Required packages/layout/+uix/loadIcon.m new file mode 100644 index 0000000..c273942 --- /dev/null +++ b/Required packages/layout/+uix/loadIcon.m @@ -0,0 +1,102 @@ +function cdata = loadIcon( filename, bgcol ) +%loadIcon Load an icon and set the transparent color +% +% cdata = uix.loadIcon(filename) loads the icon from the specified +% filename. For PNG files with transparency, the transparent pixels are +% set to NaN. For other files, pixels that are pure green are set to +% transparent (i.e., "green screen"). The resulting cdata is an RGB +% double array. +% +% cdata = uix.loadIcon(filename,bgcol) tries to merge the color data with +% the specified background colour bgcol. Fully transparent pixels are +% still set to NaN, but partially transparent pixels are merged with the +% background. +% +% See also: imread + +% Copyright 2009-2016 The MathWorks, Inc. +% $Revision: 1436 $ $Date: 2016-11-17 17:53:29 +0000 (Thu, 17 Nov 2016) $ + +% Check inputs +narginchk( 1, 2 ) +if nargin < 2 + bgcol = get( 0, 'DefaultUIControlBackgroundColor' ); +end + +% First try normally +thisDir = fileparts( mfilename( 'fullpath' ) ); +iconDir = fullfile( thisDir, 'Resources' ); +if exist( filename, 'file' ) + [cdata, map, alpha] = imread( filename ); +elseif exist( fullfile( iconDir, filename ), 'file' ) + [cdata, map, alpha] = imread( fullfile( iconDir, filename ) ); +else + error( 'uix:FileNotFound', 'Cannot open file ''%s''.', filename ) +end + +% Convert indexed images to RGB +if ~isempty( map ) + cdata = ind2rgb( cdata, map ); +end + +% Convert to double before applying transparency +cdata = convertToDouble( cdata ); + +% Handle transparency +[rows, cols, ~] = size( cdata ); +if ~isempty( alpha ) + + % Transparency specified + alpha = convertToDouble( alpha ); + f = find( alpha==0 ); + if ~isempty( f ) + cdata(f) = NaN; + cdata(f + rows*cols) = NaN; + cdata(f + 2*rows*cols) = NaN; + end + % Now blend partial alphas + f = find( alpha(:)>0 & alpha(:)<1 ); + if ~isempty(f) + cdata(f) = cdata(f).*alpha(f) + bgcol(1)*(1-alpha(f)); + cdata(f + rows*cols) = cdata(f + rows*cols).*alpha(f) + bgcol(2)*(1-alpha(f)); + cdata(f + 2*rows*cols) = cdata(f + 2*rows*cols).*alpha(f) + bgcol(3)*(1-alpha(f)); + end + +else + + % Do a "green screen", treating anything pure-green as transparent + f = find( cdata(:,:,1)==0 & cdata(:,:,2)==1 & cdata(:,:,3)==0 ); + cdata(f) = NaN; + cdata(f + rows*cols) = NaN; + cdata(f + 2*rows*cols) = NaN; + +end + +end % uix.loadIcon + +% ------------------------------------------------------------------------- + +function cdata = convertToDouble( cdata ) +%convertToDouble Convert image data to double in the range [0,1] +% +% cdata = convertToDouble(cData) + +switch lower( class( cdata ) ) + case 'double' + % do nothing + case 'single' + cdata = double( cdata ); + case 'uint8' + cdata = double( cdata ) / 255; + case 'uint16' + cdata = double( cdata ) / 65535; + case 'int8' + cdata = ( double( cdata ) + 128 ) / 255; + case 'int16' + cdata = ( double( cdata ) + 32768 ) / 65535; + otherwise + error( 'uix:InvalidArgument', ... + 'Image data of type ''%s'' is not supported.', class( cdata ) ) +end + +end % convertToDouble \ No newline at end of file diff --git a/Required packages/layout/+uix/setPosition.m b/Required packages/layout/+uix/setPosition.m new file mode 100644 index 0000000..f658ada --- /dev/null +++ b/Required packages/layout/+uix/setPosition.m @@ -0,0 +1,29 @@ +function setPosition( o, p, u ) +%setPosition Set position of graphics object +% +% setPosition(o,p,u) sets the position of a graphics object o to value p +% with units u. +% +% In contrast to setting the Position property directly, this function +% honors the ActivePositionProperty of axes. + +% Copyright 2009-2016 The MathWorks, Inc. +% $Revision: 1435 $ $Date: 2016-11-17 17:50:34 +0000 (Thu, 17 Nov 2016) $ + +o.Units = u; +if isa( o, 'matlab.graphics.axis.Axes' ) + switch o.ActivePositionProperty + case 'position' + o.Position = p; + case 'outerposition' + o.OuterPosition = p; + otherwise + error( 'uix:InvalidState', ... + 'Unknown value ''%s'' for property ''ActivePositionProperty'' of %s.', ... + o.ActivePositionProperty, class( o ) ) + end +else + o.Position = p; +end + +end % setPosition \ No newline at end of file diff --git a/Required packages/layout/+uix/tracking.m b/Required packages/layout/+uix/tracking.m new file mode 100644 index 0000000..4399ea6 --- /dev/null +++ b/Required packages/layout/+uix/tracking.m @@ -0,0 +1,229 @@ +function varargout = tracking( varargin ) +%tracking Track anonymized usage data +% +% tracking(p,v,id) tracks usage to the property p for the product version +% v and identifier id. No personally identifiable information is tracked. +% +% r = tracking(...) returns the server response r, for debugging purposes. +% +% tracking('on') turns tracking on. tracking('off') turns tracking off. +% tracking('query') returns the tracking state. + +% tracking('spoof') sets the tracking settings -- domain, language, +% client, MATLAB version, operating system version -- to spoof values. +% tracking('reset') sets the tracking settings to normal values. +% +% [t,s] = tracking('query') returns the tracking state t and settings s. + +% Copyright 2016 The MathWorks, Inc. +% $Revision: 1435 $ $Date: 2016-11-17 17:50:34 +0000 (Thu, 17 Nov 2016) $ + +persistent STATE USERNAME DOMAIN LANGUAGE CLIENT MATLAB OS +if isempty( STATE ) + STATE = getpref( 'Tracking', 'State', 'on' ); + if strcmp( STATE, 'snooze' ) % deprecated + setpref( 'Tracking', 'State', 'on' ) + STATE = 'on'; + end + if ispref( 'Tracking', 'Date' ) % deprecated + rmpref( 'Tracking', 'Date' ) + end + USERNAME = getenv( 'USERNAME' ); + reset() +end % initialize + +switch nargin + case 1 + switch varargin{1} + case {'on','off'} + STATE = varargin{1}; + setpref( 'Tracking', 'State', varargin{1} ) % persist + case 'spoof' + spoof() + case 'reset' + reset() + case 'query' + varargout{1} = STATE; + varargout{2} = query(); + otherwise + error( 'tracking:InvalidArgument', ... + 'Valid options are ''on'', ''off'' and ''query''.' ) + end + case 3 + switch nargout + case 0 + if strcmp( STATE, 'off' ), return, end + uri = 'https://www.google-analytics.com/collect'; + track( uri, varargin{:} ); + case 1 + uri = 'https://www.google-analytics.com/debug/collect'; + varargout{1} = track( uri, varargin{:} ); + otherwise + nargoutchk( 0, 1 ) + end + otherwise + narginchk( 3, 3 ) +end % switch + + function reset() + %reset Set normal settings + + DOMAIN = lower( getenv( 'USERDOMAIN' ) ); + LANGUAGE = char( java.util.Locale.getDefault() ); + CLIENT = getpref( 'Tracking', 'Client', uuid() ); + MATLAB = matlab(); + OS = os(); + + end % reset + + function spoof() + %spoof Set spoof settings + + DOMAIN = randomDomain(); + LANGUAGE = randomLanguage(); + CLIENT = randomClient(); + MATLAB = randomMatlab(); + OS = randomOs(); + + end % spoof + + function s = query() + %query Return settings + + s.Username = USERNAME; + s.Domain = DOMAIN; + s.Language = LANGUAGE; + s.Client = CLIENT; + s.Matlab = MATLAB; + s.Os = OS; + + end % query + + function varargout = track( uri, p, v, s ) + %track Do tracking + + a = sprintf( '%s/%s (%s)', MATLAB, v, OS ); + if isdeployed() + ds = 'deployed'; + elseif strcmp( DOMAIN, 'mathworks' ) + ds = DOMAIN; + else + ds = 'unknown'; + end + pv = {'v', '1', 'tid', p, 'ua', escape( a ), 'ul', LANGUAGE, ... + 'cid', CLIENT, 'ht', 'pageview', ... + 'dp', sprintf( '/%s', s ), 'ds', ds}; + [varargout{1:nargout}] = urlread( uri, 'Post', pv ); + + end % track + +end % tracking + +function s = randomDomain() +%randomDomain Random domain string + +switch randi( 4 ) + case 1 + s = 'mathworks'; + otherwise + s = hash( uuid() ); +end + +end % randomDomain + +function s = randomLanguage() +%randomLanguage Random language string + +lo = java.util.Locale.getAvailableLocales(); +s = char( lo(randi( numel( lo ) )) ); + +end % randomLanguage + +function s = randomClient() +%randomClient Random client identifier + +s = uuid(); + +end % randomClient + +function s = matlab() +%matlab MATLAB version string + +v = ver( 'MATLAB' ); +s = v.Release; +s(s=='('|s==')') = []; + +end % matlab + +function s = randomMatlab() +%randomMatlab Random MATLAB version string + +releases = {'R2014b' 'R2015a' 'R2015b' 'R2016a' 'R2016b'}; +s = releases{randi( numel( releases ) )}; + +end % randomMatlab + +function s = os() +%os Operating system string + +if ispc() + s = sprintf( 'Windows NT %s', ... + char( java.lang.System.getProperty( 'os.version' ) ) ); +elseif isunix() + s = 'Linux x86_64'; +elseif ismac() + s = sprintf( 'Macintosh; Intel OS X %s', ... + strrep( char( java.lang.System.getProperty( 'os.version' ) ), ' ', '_' ) ); +else + s = 'unknown'; +end + +end % os + +function s = randomOs() +%randomOs Random operating system string + +switch randi( 3 ) + case 1 + versions = [5.1 5.2 6 6.1 6.2 6.3 10]; + s = sprintf( 'Windows NT %.1f', ... + versions(randi( numel( versions ) )) ); + case 2 + s = 'Linux x86_64'; + case 3 + s = sprintf( 'Macintosh; Intel OS X 10_%d', ... + randi( [10 12] ) ); +end + +end % randomOs + +function s = escape( s ) +%escape Escape string + +s = char( java.net.URLEncoder.encode( s, 'UTF-8' ) ); + +end % escape + +function h = hash( s ) +%hash Hash string +% +% See also: rptgen.hash + +persistent MD5 +if isempty( MD5 ) + MD5 = java.security.MessageDigest.getInstance( 'MD5' ); +end + +MD5.update( uint8( s(:) ) ); +h = typecast( MD5.digest, 'uint8' ); +h = dec2hex( h )'; +h = lower( h(:) )'; + +end % hash + +function s = uuid() +%uuid Unique identifier + +s = char( java.util.UUID.randomUUID() ); + +end % uuid \ No newline at end of file diff --git a/Required packages/layout/Contents.m b/Required packages/layout/Contents.m new file mode 100644 index 0000000..c1dfcc7 --- /dev/null +++ b/Required packages/layout/Contents.m @@ -0,0 +1,29 @@ +% GUI Layout Toolbox +% Version 2.3.1 (R2016b) 24-November-2016 +% +% Panels +% uix.Panel - arrange a single element inside a standard panel +% uix.CardPanel - show one element from a list +% uix.BoxPanel - arrange a single element inside a panel with a boxed title +% uix.TabPanel - arrange elements in a panel with tabs for selecting which is visible +% uix.ScrollingPanel - arrange a single element inside a scrollable panel +% +% Boxes +% uix.HBox - arrange elements horizontally in a single row +% uix.VBox - arrange elements vertically in a single column +% uix.HBoxFlex - arrange elements horizontally with draggable dividers +% uix.VBoxFlex - arrange elements vertically with draggable dividers +% uix.HButtonBox - arrange buttons horizontally in a single row +% uix.VButtonBox - arrange buttons vertically in a single column +% +% Grids +% uix.Grid - arrange elements in a two-dimensional grid +% uix.GridFlex - arrange elements in a two-dimensional grid with draggable dividers +% +% Other +% uix.Empty - create an empty space +% uix.tracking - track anonymized usage data +% uix.Text - create an alignable, clickable text control + +% Copyright 2009-2016 The MathWorks, Inc. +% $Revision: 1434 $ $Date: 2016-11-17 17:44:45 +0000 (Thu, 17 Nov 2016) $ diff --git a/Required packages/layout/layoutRoot.m b/Required packages/layout/layoutRoot.m new file mode 100644 index 0000000..97882fb --- /dev/null +++ b/Required packages/layout/layoutRoot.m @@ -0,0 +1,18 @@ +function folder = layoutRoot() +%layoutRoot Folder containing the GUI Layout Toolbox +% +% folder = layoutRoot() returns the full path to the folder containing +% the GUI Layout Toolbox. +% +% Examples: +% >> folder = layoutRoot() +% folder = 'C:\tools\layouts2\layout' +% +% See also: layoutVersion + +% Copyright 2009-2014 The MathWorks, Inc. +% $Revision: 980 $ $Date: 2014-09-28 14:27:26 -0400 (Sun, 28 Sep 2014) $ + +folder = fileparts( mfilename( 'fullpath' ) ); + +end % layoutRoot \ No newline at end of file diff --git a/Required packages/layoutdoc/AxesExample.html b/Required packages/layoutdoc/AxesExample.html new file mode 100644 index 0000000..41e1f36 --- /dev/null +++ b/Required packages/layoutdoc/AxesExample.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/AxesLegendsColorbars.html b/Required packages/layoutdoc/AxesLegendsColorbars.html new file mode 100644 index 0000000..f5db48d --- /dev/null +++ b/Required packages/layoutdoc/AxesLegendsColorbars.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/BoxPanelFancyStuff.html b/Required packages/layoutdoc/BoxPanelFancyStuff.html new file mode 100644 index 0000000..92d3b34 --- /dev/null +++ b/Required packages/layoutdoc/BoxPanelFancyStuff.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/Compiling.html b/Required packages/layoutdoc/Compiling.html new file mode 100644 index 0000000..b04e081 --- /dev/null +++ b/Required packages/layoutdoc/Compiling.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/ExampleApp.html b/Required packages/layoutdoc/ExampleApp.html new file mode 100644 index 0000000..86fa9ee --- /dev/null +++ b/Required packages/layoutdoc/ExampleApp.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/Examples.html b/Required packages/layoutdoc/Examples.html new file mode 100644 index 0000000..e060671 --- /dev/null +++ b/Required packages/layoutdoc/Examples.html @@ -0,0 +1,88 @@ + + + + + + + + Examples + + + + + + + + + + + +
GUI Layout Toolbox 2.3.1previous pagenext page
+ +

Examples Go back up one level

+ +

The following examples are provided as part of this documentation. Click + the name of any example to go to the corresponding page.

+ +

Basics

+
+
Layout hierarchy
+
Using layouts inside layouts to produce more complex designs
+
+ +

Using axes

+
+
Positioning axes
+
Using the different axes position properties.
+ +
Axes legends and colorbars
+
How to work with axes that may also have legends and/or colorbars.
+
+ +

Using panels

+
+
Context help
+
Adding context-sensitive help using panels.
+ +
Minimize and maximize
+
Creating a user interface with panels that can be minimized and + maximized.
+ +
Dock and undock
+
Creating a user interface with panels that can be undocked into + separate windows.
+
+ +

Visible

+
+
Show and hide
+
Showing and hiding a layout and its contents.
+
+ +

Applications

+
+
Building a complete application
+
Using layouts together to produce a complete application.
+
+ + +
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + diff --git a/Required packages/layoutdoc/Examples/axesexample.m b/Required packages/layoutdoc/Examples/axesexample.m new file mode 100644 index 0000000..6c6b92a --- /dev/null +++ b/Required packages/layoutdoc/Examples/axesexample.m @@ -0,0 +1,41 @@ +%% Axes inside layouts +% This example demonstrates how axes are affected by being placed into +% layouts. The layouts take into account the "ActivePositionProperty" in +% order to determine whether to set the "Position" or "OuterPosition" +% (default) property of the axes. +% +% Copyright 2009-2013 The MathWorks, Inc. + +%% Open the window +% Open a new figure window and remove the toolbar and menus +window = figure( 'Name', 'Axes inside layouts', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'NumberTitle', 'off' ); + +%% Create the layout +% The layout involves two axes side by side. This is done using a +% flexible horizontal box. The left-hand axes is left with the +% ActivePositionProperty set to "outerposition", but the right-hand axes is +% switched to use "Position" +hbox = uix.HBoxFlex('Parent', window, 'Spacing', 3); +axes1 = axes( 'Parent', hbox, ... + 'ActivePositionProperty', 'outerposition' ); +axes2 = axes( 'Parent', hbox, ... + 'ActivePositionProperty', 'Position' ); +set( hbox, 'Widths', [-2 -1] ); + +%% Fill the axes +% Using "OuterPosition" (left-hand axes) is the normal mode and looks good +% for virtually any plot type. Using "Position" is only really useful for +% 2D plots with the axes turned off, such as images +x = membrane( 1, 15 ); +surf( axes1, x ); +lighting( axes1, 'gouraud' ); +shading( axes1, 'interp' ); +l = light( 'Parent', axes1 ); +camlight( l, 'head' ); +axis( axes1, 'tight' ); + +imagesc( x, 'Parent', axes2 ); +set( axes2, 'xticklabel', [], 'yticklabel', [] ); \ No newline at end of file diff --git a/Required packages/layoutdoc/Examples/callbackexample.m b/Required packages/layoutdoc/Examples/callbackexample.m new file mode 100644 index 0000000..0023768 --- /dev/null +++ b/Required packages/layoutdoc/Examples/callbackexample.m @@ -0,0 +1,47 @@ +function callbackexample() + +% Copyright 2009-2013 The MathWorks, Inc. + +% Create application data +colorNames = { + 'Red' + 'Orange' + 'Yellow' + 'Green' + 'Blue' + 'Indigo' + 'Violet' + }; +colorValues = [ + 1.0 0.2 0.2 + 1.0 0.6 0.2 + 1.0 1.0 0.4 + 0.6 1.0 0.6 + 0.2 0.4 1.0 + 0.4 0.1 0.6 + 0.7 0.5 1.0 + ]; + +% Layout the interface +f = figure(); +p = uix.Panel( 'Parent', f, 'Title', 'A Panel', 'TitlePosition', 'CenterTop'); +b = uix.HBoxFlex( 'Parent', p, 'Spacing', 5, 'Padding', 5 ); +hList = uicontrol( 'Style', 'listbox', 'Parent', b, ... + 'String', colorNames, ... + 'Back', 'w' ); +hButton = uicontrol( 'Parent', b, ... + 'Background', colorValues(1,:), ... + 'String', colorNames{1} ); +set( b, 'Widths', [-1 -3] ); + +% Add user interactions +set( hList, 'Callback', @onChangeColor ); + + + function onChangeColor( source, ~ ) + idx = get( source, 'Value' ); + set( hButton, 'Background', colorValues(idx,:), 'String', colorNames{idx} ) + end % onChangeColor + + +end % main \ No newline at end of file diff --git a/Required packages/layoutdoc/Examples/colorbarexample.m b/Required packages/layoutdoc/Examples/colorbarexample.m new file mode 100644 index 0000000..ea6750d --- /dev/null +++ b/Required packages/layoutdoc/Examples/colorbarexample.m @@ -0,0 +1,29 @@ +%% Axes with colorbars inside layouts +% This example demonstrates how to correctly layout axes that have +% associated legends or colorbars by grouping them together using a +% uicontainer. +% +% Copyright 2014 The MathWorks, Inc. + +%% Open the window +% Open a new figure window and remove the toolbar and menus +window = figure( 'Name', 'Axes legend and colorbars', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'NumberTitle', 'off' ); + +%% Create the layout +% The layout involves two axes side by side. Each axes is placed into a +% uicontainer so that the legend and colorbar are "grouped" with the axes. +hbox = uix.VBoxFlex('Parent', window, 'Spacing', 3); +axes1 = axes( 'Parent', uicontainer('Parent', hbox) ); +axes2 = axes( 'Parent', uicontainer('Parent', hbox) ); + +%% Add decorations +% Give the first axes a colorbar and the second axes a legend. +surf( axes1, membrane( 1, 15 ) ); +colorbar( axes1 ); + +theta = 0:360; +plot( axes2, theta, sind(theta), theta, cosd(theta) ); +legend( axes2, 'sin', 'cos', 'Location', 'NorthWestOutside' ); \ No newline at end of file diff --git a/Required packages/layoutdoc/Examples/demoBrowser.m b/Required packages/layoutdoc/Examples/demoBrowser.m new file mode 100644 index 0000000..97ab30b --- /dev/null +++ b/Required packages/layoutdoc/Examples/demoBrowser.m @@ -0,0 +1,209 @@ +function demoBrowser() +%demoBrowser: an example of using layouts to build a user interface +% +% demoBrowser() opens a simple GUI that allows several of MATLAB's +% built-in demos to be viewed. It aims to demonstrate how multiple +% layouts can be used to create a good-looking user interface that +% retains the correct proportions when resized. It also shows how to +% hook-up callbacks to interpret user interaction. +% +% See also: Layouts + +% Copyright 2010-2013 The MathWorks, Inc. + +% Data is shared between all child functions by declaring the variables +% here (they become global to the function). We keep things tidy by putting +% all GUI stuff in one structure and all data stuff in another. As the app +% grows, we might consider making these objects rather than structures. +data = createData(); +gui = createInterface( data.DemoNames ); + +% Now update the GUI with the current data +updateInterface(); +redrawDemo(); + +% Explicitly call the demo display so that it gets included if we deploy +displayEndOfDemoMessage('') + +%-------------------------------------------------------------------------% + function data = createData() + % Create the shared data-structure for this application + demoList = { + 'Complex surface' 'cplxdemo' + 'Cruller' 'cruller' + 'Earth' 'earthmap' + 'Four linked tori' 'tori4' + 'Klein bottle' 'xpklein' + 'Klein bottle (1)' 'klein1' + 'Knot' 'knot' + 'Logo' 'logo' + 'Spherical Surface Harmonic' 'spharm2' + 'Werner Boy''s Surface' 'wernerboy' + }; + selectedDemo = 8; + data = struct( ... + 'DemoNames', {demoList(:,1)'}, ... + 'DemoFunctions', {demoList(:,2)'}, ... + 'SelectedDemo', selectedDemo ); + end % createData + +%-------------------------------------------------------------------------% + function gui = createInterface( demoList ) + % Create the user interface for the application and return a + % structure of handles for global use. + gui = struct(); + % Open a window and add some menus + gui.Window = figure( ... + 'Name', 'Gallery browser', ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'HandleVisibility', 'off' ); + + % + File menu + gui.FileMenu = uimenu( gui.Window, 'Label', 'File' ); + uimenu( gui.FileMenu, 'Label', 'Exit', 'Callback', @onExit ); + + % + View menu + gui.ViewMenu = uimenu( gui.Window, 'Label', 'View' ); + for ii=1:numel( demoList ) + uimenu( gui.ViewMenu, 'Label', demoList{ii}, 'Callback', @onMenuSelection ); + end + + % + Help menu + helpMenu = uimenu( gui.Window, 'Label', 'Help' ); + uimenu( helpMenu, 'Label', 'Documentation', 'Callback', @onHelp ); + + + % Arrange the main interface + mainLayout = uix.HBoxFlex( 'Parent', gui.Window, 'Spacing', 3 ); + + % + Create the panels + controlPanel = uix.BoxPanel( ... + 'Parent', mainLayout, ... + 'Title', 'Select a demo:' ); + gui.ViewPanel = uix.BoxPanel( ... + 'Parent', mainLayout, ... + 'Title', 'Viewing: ???', ... + 'HelpFcn', @onDemoHelp ); + gui.ViewContainer = uicontainer( ... + 'Parent', gui.ViewPanel ); + + % + Adjust the main layout + set( mainLayout, 'Widths', [-1,-2] ); + + + % + Create the controls + controlLayout = uix.VBox( 'Parent', controlPanel, ... + 'Padding', 3, 'Spacing', 3 ); + gui.ListBox = uicontrol( 'Style', 'list', ... + 'BackgroundColor', 'w', ... + 'Parent', controlLayout, ... + 'String', demoList(:), ... + 'Value', 1, ... + 'Callback', @onListSelection); + gui.HelpButton = uicontrol( 'Style', 'PushButton', ... + 'Parent', controlLayout, ... + 'String', 'Help for ', ... + 'Callback', @onDemoHelp ); + set( controlLayout, 'Heights', [-1 28] ); % Make the list fill the space + + % + Create the view + p = gui.ViewContainer; + gui.ViewAxes = axes( 'Parent', p ); + + + end % createInterface + +%-------------------------------------------------------------------------% + function updateInterface() + % Update various parts of the interface in response to the demo + % being changed. + + % Update the list and menu to show the current demo + set( gui.ListBox, 'Value', data.SelectedDemo ); + % Update the help button label + demoName = data.DemoNames{ data.SelectedDemo }; + set( gui.HelpButton, 'String', ['Help for ',demoName] ); + % Update the view panel title + set( gui.ViewPanel, 'Title', sprintf( 'Viewing: %s', demoName ) ); + % Untick all menus + menus = get( gui.ViewMenu, 'Children' ); + set( menus, 'Checked', 'off' ); + % Use the name to work out which menu item should be ticked + whichMenu = strcmpi( demoName, get( menus, 'Label' ) ); + set( menus(whichMenu), 'Checked', 'on' ); + end % updateInterface + +%-------------------------------------------------------------------------% + function redrawDemo() + % Draw a demo into the axes provided + + % We first clear the existing axes ready to build a new one + if ishandle( gui.ViewAxes ) + delete( gui.ViewAxes ); + end + + % Some demos create their own figure. Others don't. + fcnName = data.DemoFunctions{data.SelectedDemo}; + switch upper( fcnName ) + case 'LOGO' + % These demos open their own windows + evalin( 'base', fcnName ); + gui.ViewAxes = gca(); + fig = gcf(); + set( fig, 'Visible', 'off' ); + + otherwise + % These demos need a window opening + fig = figure( 'Visible', 'off' ); + evalin( 'base', fcnName ); + gui.ViewAxes = gca(); + end + % Now copy the axes from the demo into our window and restore its + % state. + cmap = colormap( gui.ViewAxes ); + set( gui.ViewAxes, 'Parent', gui.ViewContainer ); + colormap( gui.ViewAxes, cmap ); + rotate3d( gui.ViewAxes, 'on' ); + % Get rid of the demo figure + close( fig ); + end % redrawDemo + +%-------------------------------------------------------------------------% + function onListSelection( src, ~ ) + % User selected a demo from the list - update "data" and refresh + data.SelectedDemo = get( src, 'Value' ); + updateInterface(); + redrawDemo(); + end % onListSelection + +%-------------------------------------------------------------------------% + function onMenuSelection( src, ~ ) + % User selected a demo from the menu - work out which one + demoName = get( src, 'Label' ); + data.SelectedDemo = find( strcmpi( demoName, data.DemoNames ), 1, 'first' ); + updateInterface(); + redrawDemo(); + end % onMenuSelection + + +%-------------------------------------------------------------------------% + function onHelp( ~, ~ ) + % User has asked for the documentation + doc layout + end % onHelp + +%-------------------------------------------------------------------------% + function onDemoHelp( ~, ~ ) + % User wnats documentation for the current demo + showdemo( data.DemoFunctions{data.SelectedDemo} ); + end % onDemoHelp + +%-------------------------------------------------------------------------% + function onExit( ~, ~ ) + % User wants to quit out of the application + delete( gui.Window ); + end % onExit + +end % EOF \ No newline at end of file diff --git a/Required packages/layoutdoc/Examples/displayEndOfDemoMessage.m b/Required packages/layoutdoc/Examples/displayEndOfDemoMessage.m new file mode 100644 index 0000000..772873f --- /dev/null +++ b/Required packages/layoutdoc/Examples/displayEndOfDemoMessage.m @@ -0,0 +1,4 @@ +function displayEndOfDemoMessage(filename) +% Dummy function - do nothing. +% +% Copyright 2009-2013 The MathWorks, Inc. diff --git a/Required packages/layoutdoc/Examples/dockexample.m b/Required packages/layoutdoc/Examples/dockexample.m new file mode 100644 index 0000000..edeb40f --- /dev/null +++ b/Required packages/layoutdoc/Examples/dockexample.m @@ -0,0 +1,74 @@ +function dockexample() +%DOCKEXAMPLE: An example of using the panelbox dock/undock functionality + +% Copyright 2009-2013 The MathWorks Ltd. + +% Create the window and main layout +fig = figure( 'Name', 'Dockable GUI example', ...' + 'NumberTitle', 'off', ... + 'Toolbar', 'none', ... + 'MenuBar', 'none', ... + 'CloseRequestFcn', @nCloseAll ); +box = uix.HBox( 'Parent', fig ); + +% Add three panels to the box +panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box ); +panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box ); +panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box ); + +% Add some contents +uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} ); +box1 = uix.VBox( 'Parent', panel{3} ); +box2 = uix.HBox( 'Parent', box1 ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', box1 ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 4', 'Parent', box2 ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 5', 'Parent', box2 ); + +% Set the dock/undock callback +set( panel{1}, 'DockFcn', {@nDock, 1} ); +set( panel{2}, 'DockFcn', {@nDock, 2} ); +set( panel{3}, 'DockFcn', {@nDock, 3} ); + +%-------------------------------------------------------------------------% + function nDock( eventSource, eventData, whichpanel ) %#ok + % Set the flag + panel{whichpanel}.Docked = ~panel{whichpanel}.Docked; + if panel{whichpanel}.Docked + % Put it back into the layout + newfig = get( panel{whichpanel}, 'Parent' ); + set( panel{whichpanel}, 'Parent', box ); + delete( newfig ); + else + % Take it out of the layout + pos = getpixelposition( panel{whichpanel} ); + newfig = figure( ... + 'Name', get( panel{whichpanel}, 'Title' ), ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'CloseRequestFcn', {@nDock, whichpanel} ); + figpos = get( newfig, 'Position' ); + set( newfig, 'Position', [figpos(1,1:2), pos(1,3:4)] ); + set( panel{whichpanel}, 'Parent', newfig, ... + 'Units', 'Normalized', ... + 'Position', [0 0 1 1] ); + end + end % nDock + +%-------------------------------------------------------------------------% + function nCloseAll( ~, ~ ) + % User wished to close the application, so we need to tidy up + + % Delete all windows, including undocked ones. We can do this by + % getting the window for each panel in turn and deleting it. + for ii=1:numel( panel ) + if isvalid( panel{ii} ) && ~strcmpi( panel{ii}.BeingDeleted, 'on' ) + figh = ancestor( panel{ii}, 'figure' ); + delete( figh ); + end + end + + end % nCloseAll + +end % Main function diff --git a/Required packages/layoutdoc/Examples/gridflexpositioning.m b/Required packages/layoutdoc/Examples/gridflexpositioning.m new file mode 100644 index 0000000..aea133a --- /dev/null +++ b/Required packages/layoutdoc/Examples/gridflexpositioning.m @@ -0,0 +1,25 @@ +% Copyright 2009-2013 The MathWorks Ltd. + +f = figure(); + +% Box Panel +p = uix.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 ); + +% HBox +b = uix.HBox( 'Parent', p, 'Spacing', 5, 'Padding', 5 ); + +% uicontrol +uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} ); + +% Grid Flex +g = uix.GridFlex( 'Parent', b, 'Spacing', 5 ); +uicontrol( 'Parent', g, 'Background', 'r' ); +uicontrol( 'Parent', g, 'Background', 'b' ); +uicontrol( 'Parent', g, 'Background', 'g' ); +uix.Empty( 'Parent', g ); +uicontrol( 'Parent', g, 'Background', 'c' ); +uicontrol( 'Parent', g, 'Background', 'y' ); +set( g, 'Widths', [-1 100 -2], 'Heights', [-1 -2] ); + +% set HBox elements sizes +set( b, 'Widths', [100 -1] ); diff --git a/Required packages/layoutdoc/Examples/guideApp.fig b/Required packages/layoutdoc/Examples/guideApp.fig new file mode 100644 index 0000000..1f1ceca Binary files /dev/null and b/Required packages/layoutdoc/Examples/guideApp.fig differ diff --git a/Required packages/layoutdoc/Examples/guideApp.m b/Required packages/layoutdoc/Examples/guideApp.m new file mode 100644 index 0000000..bcdda08 --- /dev/null +++ b/Required packages/layoutdoc/Examples/guideApp.m @@ -0,0 +1,106 @@ +function varargout = guideApp(varargin) +% GUIDEAPP MATLAB code for guideApp.fig +% GUIDEAPP, by itself, creates a new GUIDEAPP or raises the existing +% singleton*. +% +% H = GUIDEAPP returns the handle to a new GUIDEAPP or the handle to +% the existing singleton*. +% +% GUIDEAPP('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in GUIDEAPP.M with the given input arguments. +% +% GUIDEAPP('Property','Value',...) creates a new GUIDEAPP or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before guideApp_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to guideApp_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Copyright 2009-2013 The MathWorks Ltd. + +% Edit the above text to modify the response to help guideApp + +% Last Modified by GUIDE v2.5 21-Jul-2010 07:36:25 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @guideApp_OpeningFcn, ... + 'gui_OutputFcn', @guideApp_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before guideApp is made visible. +function guideApp_OpeningFcn(hObject, eventdata, handles, varargin) +% This function has no output args, see OutputFcn. +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% varargin command line arguments to guideApp (see VARARGIN) + +% Choose default command line output for guideApp +handles.output = hObject; + +% Update handles structure +guidata(hObject, handles); + +% Put a layout in the panel +g = uix.GridFlex( 'Parent', handles.uipanel1, ... + 'Units', 'Normalized', 'Position', [0 0 1 1], ... + 'Spacing', 5 ); +uix.BoxPanel( 'Parent', g, 'Title', 'Panel 1' ); +uix.BoxPanel( 'Parent', g, 'Title', 'Panel 2' ); +uix.BoxPanel( 'Parent', g, 'Title', 'Panel 3' ); +uix.BoxPanel( 'Parent', g, 'Title', 'Panel 4' ); +g.Heights = [-1 -1]; + +% UIWAIT makes guideApp wait for user response (see UIRESUME) +% uiwait(handles.figure1); + + +% --- Outputs from this function are returned to the command line. +function varargout = guideApp_OutputFcn(hObject, eventdata, handles) +% varargout cell array for returning output args (see VARARGOUT); +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Get default command line output from handles structure +varargout{1} = handles.output; + + +% --- Executes on button press in pushbutton1. +function pushbutton1_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in pushbutton2. +function pushbutton2_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in pushbutton3. +function pushbutton3_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton3 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) diff --git a/Required packages/layoutdoc/Examples/hierarchyexample.m b/Required packages/layoutdoc/Examples/hierarchyexample.m new file mode 100644 index 0000000..f5c7ff6 --- /dev/null +++ b/Required packages/layoutdoc/Examples/hierarchyexample.m @@ -0,0 +1,33 @@ +%% A Hierarchy of Layouts Example +% This example shows how to use layouts within other layouts to achieve +% more complex user interface designs with the right mix of variable and +% fixed sized components. +% +% Copyright 2009-2014 The MathWorks Ltd. + +%% Open the window +% Open a new figure window and remove the toolbar and menus +window = figure( 'Name', 'A Layout Hierarchy Example', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'NumberTitle', 'off', ... + 'Position', 200*ones(1,4) ); + +%% Create the first layout (vertical box) +% Inside this vertical box we place the axes +vbox = uix.VBox( 'Parent', window ); +axes( 'Parent', vbox ); + +%% Create the second layout (horizontal box) +% Inside this horizontal box we place two buttons +hbox = uix.HButtonBox( 'Parent', vbox, 'Padding', 5 ); +uicontrol( 'Parent', hbox, ... + 'String', 'Button 1' ); +uicontrol( 'Parent', hbox, ... + 'String', 'Button 2' ); + +%% Set the sizes +% We want the axes to grow with the window so set the first size to be -1 +% (which means variable size with wieght 1) and the buttons to stay fixed +% height so set the second size to 35 (fixed height of 35 pixels) +set( vbox, 'Heights', [-1 35] ) diff --git a/Required packages/layoutdoc/Examples/minimizeexample.m b/Required packages/layoutdoc/Examples/minimizeexample.m new file mode 100644 index 0000000..f21180b --- /dev/null +++ b/Required packages/layoutdoc/Examples/minimizeexample.m @@ -0,0 +1,54 @@ +function minimizeexample() +%MINIMIZEEXAMPLE: An example of using the panelbox minimize/maximize + +% Copyright 2010-2013 The MathWorks Ltd. + +width = 200; +pheightmin = 20; +pheightmax = 100; + +% Create the window and main layout +fig = figure( 'Name', 'Collapsable GUI', ...' + 'NumberTitle', 'off', ... + 'Toolbar', 'none', ... + 'MenuBar', 'none' ); +box = uix.VBox( 'Parent', fig ); + +panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box ); +panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box ); +panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box ); +set( box, 'Heights', pheightmax*ones(1,3) ); + +% Add some contents +uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', panel{3} ); + +% Resize the window +pos = get( fig, 'Position' ); +set( fig, 'Position', [pos(1,1:2),width,sum(box.Heights)] ); + +% Hook up the minimize callback +set( panel{1}, 'MinimizeFcn', {@nMinimize, 1} ); +set( panel{2}, 'MinimizeFcn', {@nMinimize, 2} ); +set( panel{3}, 'MinimizeFcn', {@nMinimize, 3} ); + +%-------------------------------------------------------------------------% + function nMinimize( eventSource, eventData, whichpanel ) %#ok + % A panel has been maximized/minimized + s = get( box, 'Heights' ); + pos = get( fig, 'Position' ); + panel{whichpanel}.Minimized = ~panel{whichpanel}.Minimized; + if panel{whichpanel}.Minimized + s(whichpanel) = pheightmin; + else + s(whichpanel) = pheightmax; + end + set( box, 'Heights', s ); + + % Resize the figure, keeping the top stationary + delta_height = pos(1,4) - sum( box.Heights ); + set( fig, 'Position', pos(1,:) + [0 delta_height 0 -delta_height] ); + end % nMinimize + +end % EOF diff --git a/Required packages/layoutdoc/Examples/paneltabexample.m b/Required packages/layoutdoc/Examples/paneltabexample.m new file mode 100644 index 0000000..d2b7e60 --- /dev/null +++ b/Required packages/layoutdoc/Examples/paneltabexample.m @@ -0,0 +1,59 @@ +%% A TabPanel Example +% This example shows how to use tabs within a layout. It also shows how to +% use the TabPanel Callback property to update other GUI elements when the +% visible tab is changed. +% +% Copyright 2009-2013 The MathWorks, Inc. + +%% Open the window +% Open a new figure window and remove the toolbar and menus +window = figure( 'Name', 'A TabPanel example', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'NumberTitle', 'off' ); + +%% Create the layout +% The layout involves two panels side by side. This is done using a +% flexible horizontal box. The left-hand side is filled with a standard +% panel and the right-hand side with some tabs. +hbox = uix.HBoxFlex('Parent', window, 'Spacing', 3); +panel = uix.Panel( ... + 'Parent', hbox, ... + 'Padding', 5, ... + 'Title', 'Left' ); +tabpanel = uix.TabPanel( 'Parent', ... + hbox, ... + 'Padding', 0); + +%% Add a list on the left +% Note that we link the callbacks from the list to the tab selection and +% the tab callback to the list such that they are kept in sync. +panellist = uicontrol( 'Style', 'list', ... + 'Parent', panel, ... + 'String', {'1', '2', '3'}, ... + 'BackgroundColor', 'w', ... + 'Callback', @(a,b) set( tabpanel, 'Selection', get( a, 'Value' ) ) ); +set( tabpanel, 'SelectionChangedFcn', @(a,b) set( panellist, 'Value', b.NewValue ) ); + +%% Create some contents +% Each tab is filled with a list box showing some numbers +htab1 = uix.Panel( 'Parent', tabpanel, 'Padding', 5, 'Title', '1'); +uicontrol( 'Style', 'listbox', 'Parent', htab1, ... + 'String', {'1', '1', '1'}, ... + 'BackgroundColor', 'w' ); + +htab2 = uix.Panel( 'Parent', tabpanel, 'Padding', 5, 'Title', '2'); +uicontrol( 'Style', 'listbox', 'Parent', htab2, ... + 'String', {'2', '2', '2'}, ... + 'BackgroundColor', 'w' ); + +htab3 = uix.Panel( 'Parent', tabpanel, 'Padding', 5, 'Title', '3'); +uicontrol( 'Style', 'listbox', 'Parent', htab3, ... + 'String', {'3', '3', '3'}, ... + 'BackgroundColor', 'w' ); + +%% Update the tab titles +tabpanel.TabTitles = {'1', '2', '3'}; + +%% Show the first tab +tabpanel.Selection = 1; \ No newline at end of file diff --git a/Required packages/layoutdoc/Examples/visibleexample.m b/Required packages/layoutdoc/Examples/visibleexample.m new file mode 100644 index 0000000..12586d1 --- /dev/null +++ b/Required packages/layoutdoc/Examples/visibleexample.m @@ -0,0 +1,30 @@ +%% Showing/hiding a panel +% +% This example opens a simple user-interface with a panel full of +% buttons. We can then show/hide the entire panel in one go. Note +% that the previous state of the buttons is preserved. +% +% Copyright 2009-2013 The MathWorks, Inc. + +%% Open a window and add a panel +fig = figure( 'Name', 'Visible example', ... + 'Position', [100 100 150 250], ... + 'MenuBar', 'none', ... + 'ToolBar', 'none', ... + 'NumberTitle', 'off' ); +panel = uix.BoxPanel( 'Parent', fig, 'Title', 'Panel' ); + +%% Put some buttons inside the panel +box = uix.VButtonBox( 'Parent', panel ); +uicontrol( 'Parent', box, 'String', 'Button 1' ); +uicontrol( 'Parent', box, 'String', 'Button 2' ); +uicontrol( 'Parent', box, 'String', 'Button 3', 'Visible', 'off' ); +uicontrol( 'Parent', box, 'String', 'Button 4' ); +uicontrol( 'Parent', box, 'String', 'Button 5', 'Visible', 'off' ); +uicontrol( 'Parent', box, 'String', 'Button 6' ); + +%% Try disabling the panel +set( panel, 'Visible', 'off' ); + +%% Try enabling the panel +set( panel, 'Visible', 'on' ); \ No newline at end of file diff --git a/Required packages/layoutdoc/Function_reference.html b/Required packages/layoutdoc/Function_reference.html new file mode 100644 index 0000000..0dcbbd7 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference.html @@ -0,0 +1,190 @@ + + + + + + + + Function reference + + + + + + + + + + + +
GUI Layout Toolbox 2.3.1previous pagenext page
+ +

Function reference Go back up one level

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

1: Panels

+ + + + + + + + + + + + + + + + + + +
1.1 uix.PanelArrange a single element inside a standard panel
1.2 uix.CardPanelShow one element (card) from a list
1.3 uix.BoxPanelArrange a single element in a panel with boxed title
1.4 uix.TabPanelArrange elements in a panel with tabs for selecting which is visible
1.5 uix.ScrollingPanelArrange a single element inside a scrollable panel

2: Boxes

+ + + + + + + + + + + + + + + + + + + + +
2.1 uix.HBoxArrange elements horizontally in a single row
2.2 uix.VBoxArrange elements vertically in a single column
2.3 uix.HBoxFlexArrange elements horizontally with draggable dividers
2.4 uix.VBoxFlexArrange elements vertically with draggable dividers
2.5 uix.HButtonBoxArrange buttons horizontally in a single row
2.6 uix.VButtonBoxArrange buttons vertically in a single column

3: Grids

+ + + + + + + +
3.1 uix.GridArrange elements in a two dimensional grid
3.2 uix.GridFlexArrange elements in a two dimensional grid with draggable dividers

4: Other functions

+ + + + + + + +
4.1 uix.EmptyCreate an empty space
4.2 uix.trackingTrack usage
4.3 layoutRootReturn the folder containing the GUI layout toolbox
+
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference1_1.html b/Required packages/layoutdoc/Function_reference1_1.html new file mode 100644 index 0000000..5276a8a --- /dev/null +++ b/Required packages/layoutdoc/Function_reference1_1.html @@ -0,0 +1,83 @@ + + + + + + + uix.Panel + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

1.1: uix.Panel Go back up one level

+ + + +
+

Arrange a single element inside a standard panel

+
+
obj = uix.Panel( )
+
creates a standard uipanel object but with automatic management + of the contained widget or layout. The properties available are largely + the same as the builtin uipanel object. Where more than one child is + added, the currently visible child is determined using the Selection property.
+ +
obj = uix.Panel( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.Panel properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
BorderType none | etchedin | etchedout | beveledin | beveledout | lineType of border around the uipanel area.
BorderWidth positive integerWidth of the panel border.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
FontAngle normal | italic | obliqueTitle font angle.
FontName stringTitle font name (e.g. Arial, Helvetica etc).
FontSize positive integerTitle font size.
FontUnits inches | centimeters | normalized | points | pixelsTitle font units for measuring size.
FontWeight light | normal | demi | boldTitle font weight.
ForegroundColor colorspecTitle font color and/or color of 2-D border line.
HighlightColor colorspec3-D frame highlight color.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Selection positive integer or emptyWhich child is visible.
ShadowColor colorspec3-D frame shadow color.
Tag stringTag to associate with layout.
Title stringTitle string.
TitlePosition lefttop | centertop | righttop | leftbottom | centerbottom | rightbottomLocation of title string in relation to the panel.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+p = uix.Panel( 'Parent', f, 'Title', 'A Panel', 'Padding', 5 );
+uicontrol( 'Parent', p, 'Background', 'r' )
+

+

+

+ +
f = figure();
+p = uix.Panel( 'Parent', f, 'Title', 'A Panel', 'TitlePosition', 'CenterTop');
+b = uix.HBox( 'Parent', p, 'Spacing', 5, 'Padding', 5  );
+uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} );
+uicontrol( 'Parent', b, 'Background', 'b' );
+set( b, 'Widths', [100 -1] );
+

+

+

+ + +
See also: + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference1_2.html b/Required packages/layoutdoc/Function_reference1_2.html new file mode 100644 index 0000000..1472165 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference1_2.html @@ -0,0 +1,77 @@ + + + + + + + uix.CardPanel + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

1.2: uix.CardPanel Go back up one level

+ + + +
+

Show one element (card) from a list

+
+
obj = uix.CardPanel( )
+
creates a new card panel which allows + selection between the different child objects contained, making the + selected child fill the space available and all other children + invisible. This is commonly used for creating wizards or quick + switching between different views of a single data-set.
+ +
obj = uix.CardPanel( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.CardPanel properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Selection positive integer or emptyWhich child is visible.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+p = uix.CardPanel( 'Parent', f, 'Padding', 5 );
+uicontrol( 'Parent', p, 'Background', 'r' );
+uicontrol( 'Parent', p, 'Background', 'b' );
+uicontrol( 'Parent', p, 'Background', 'g' );
+p.Selection = 2;
+

+

+

+ + +
See also: + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference1_3.html b/Required packages/layoutdoc/Function_reference1_3.html new file mode 100644 index 0000000..be81c96 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference1_3.html @@ -0,0 +1,87 @@ + + + + + + + uix.BoxPanel + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

1.3: uix.BoxPanel Go back up one level

+ + + +
+

Arrange a single element in a panel with boxed title

+
+
obj = uix.BoxPanel( )
+
creates a box-styled panel object with + automatic management of the contained widget or layout. The + properties available are largely the same as the builtin UIPANEL + object. Where more than one child is added, the currently visible + child is determined using the Selection property.
+ +
obj = uix.BoxPanel( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.BoxPanel properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
BorderType none | etchedin | etchedout | beveledin | beveledout | lineType of border around the title and content areas.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
CloseRequestFcn function_handleFunction to call when the panel close icon is clicked. Note that if empty, no close button is shown.
DeleteFcn function_handleFunction to call when the layout is being deleted.
DockFcn function handleFunction to call when panel is docked or undocked. Note that if empty, no dock button is shown. See advanced maneuvers with panels for details.
FontAngle normal | italic | obliqueTitle font angle.
FontName stringTitle font name (e.g. Arial, Helvetica etc).
FontSize positive integerTitle font size.
FontUnits inches | centimeters | normalized | points | pixelsTitle font units for measuring size.
FontWeight light | normal | demi | boldTitle font weight.
ForegroundColor colorspecTitle font color and/or color of 2-D border line.
HelpFcn function handleFunction to call when the help icon is clicked. Note that if empty, no help button is shown. See advanced maneuvers with panels for details.
HighlightColor colorspec3-D frame highlight color.
IsDocked logicalIs this panel in a docked state. See advanced maneuvers with panels for details.
Minimized logicalIs this panel in a minimized state. See advanced maneuvers with panels for details.
MinimizeFcn function handleFunction to call when panel is minimized or maximized. Note that if empty, no minimize button is shown. See advanced maneuvers with panels for details.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Selection positive integer or emptyWhich child is visible.
ShadowColor colorspec3-D frame shadow color.
Tag stringTag to associate with layout.
Title stringTitle string.
TitleColor colorspeccolor for the title bar background.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility. See the visible example for more details.
+ +

For example:

+
f = figure();
+p = uix.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 );
+uicontrol( 'Parent', p, 'Background', 'r' )
+

+

+

+ +
f = figure();
+p = uix.BoxPanel( 'Parent', f, 'Title', 'A BoxPanel', 'Padding', 5 );
+b = uix.HBox( 'Parent', p, 'Spacing', 5, 'Padding', 5  );
+uicontrol( 'Style', 'listbox', 'Parent', b, 'String', {'Item 1','Item 2'} );
+uicontrol( 'Parent', b, 'Background', 'b' );
+set( b, 'Widths', [100 -1] );
+p.FontSize = 12;
+p.FontWeight = 'bold';
+p.HelpFcn = @(x,y) disp('Help me!');
+

+

+

+ + +
See also: + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference1_4.html b/Required packages/layoutdoc/Function_reference1_4.html new file mode 100644 index 0000000..910b8f4 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference1_4.html @@ -0,0 +1,75 @@ + + + + + + + uix.TabPanel + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

1.4: uix.TabPanel Go back up one level

+ + + +
+

Arrange elements in a panel with tabs for selecting which is visible

+
+
obj = uix.TabPanel( )
+
creates a panel with tabs along one edge + to allow selection between the different child objects contained.
+ +
obj = uix.TabPanel( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.TabPanel properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
FontAngle normal | italic | obliqueTitle font angle.
FontName stringTitle font name (e.g. Arial, Helvetica etc).
FontSize positive integerTitle font size.
FontUnits inches | centimeters | normalized | points | pixelsTitle font units for measuring size.
FontWeight light | normal | demi | boldTitle font weight.
ForegroundColor colorspecTitle font color and/or color of 2-D border line.
HighlightColor colorspec3-D frame highlight color.
ShadowColor colorspec3-D frame shadow color.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Selection positive integer or emptyWhich child is visible.
SelectionChangedFcn function_handleFunction to call when the selected tab is changed. The event-data supplied has fields OldValue and NewValue giving the previously selected and newly selected tab indices.
TabContextMenus cell array of context menusThe context menu (or []) for each tab.
TabEnables cell array of on | offA list of the enabled state of each tab (default is all 'on').
TabTitles cell array of stringsA list of the names of the tabs with one entry per tab.
TabWidth positive integerWidth of each tab in pixels (default 50).
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+p = uix.TabPanel( 'Parent', f, 'Padding', 5 );
+uicontrol( 'Parent', p, 'Background', 'r' );
+uicontrol( 'Parent', p, 'Background', 'b' );
+uicontrol( 'Parent', p, 'Background', 'g' );
+p.TabTitles = {'Red', 'Blue', 'Green'};
+p.Selection = 2;
+

+

+

+ + +
See also: + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference1_5.html b/Required packages/layoutdoc/Function_reference1_5.html new file mode 100644 index 0000000..5739395 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference1_5.html @@ -0,0 +1,76 @@ + + + + + + + uix.ScrollingPanel + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

1.5: uix.ScrollingPanel Go back up one level

+ + + +
+

Arrange a single element inside a panel and provide scrollbars if the panel is smaller than the element

+
+
obj = uix.ScrollingPanel( )
+
creates a new scrolling panel.
+ +
obj = uix.ScrollingPanel( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.ScrollingPanel properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
Heights double vectorHeight of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
HorizontalOffsets double vectorHorizontal offset of each of the children. Each value is limited to between 0 and the difference between the width of child and the width of the panel. The size of this vector must always match the size of Contents.
HorizontalSteps positive double vectorHorizontal slider step for each of the children. The size of this vector must always match the size of Contents.
MinimumHeights double vectorMinimum height in pixels of each of the children. The size of this vector must match the size of Contents.
MinimumWidths double vectorMinimum width in pixels of each of the children. The size of this vector must match the size of Contents.
MouseWheelEnabled on | offMouse wheel scrolling status (default 'on').
Padding positive integerThis property is not honored by this class.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Selection positive integer or emptyWhich child is visible.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
VerticalOffsets double vectorVertical offset of each of the children. Each value is limited to between 0 and the difference between the height of child and the height of the panel. The size of this vector must always match the size of Contents.
VerticalSteps positive double vectorVertical slider step for each of the children. The size of this vector must always match the size of Contents.
Visible on | offVisibility.
Widths double vectorWidth of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
+ +

For example:

+
f = figure( 'Name', 'uix.ScrollingPanel Help Example' );
+f.Position(3:4) = 400;
+p = uix.ScrollingPanel( 'Parent', f );
+a = axes( 'Parent', p );
+[x, y, z] = peaks();
+surf( a, x, y, z )
+a.ActivePositionProperty = 'position';
+set( p, 'Widths', 600, 'Heights', 600, 'HorizontalOffsets', 100, 'VerticalOffsets', 100 )
+

+

+

+ + +
See also: + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/Function_reference2_1.html b/Required packages/layoutdoc/Function_reference2_1.html new file mode 100644 index 0000000..a3a79e8 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference2_1.html @@ -0,0 +1,88 @@ + + + + + + + uix.HBox + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.1: uix.HBox Go back up one level

+ + + + + + +
+

Arrange elements horizontally in a single row

+
+
obj = uix.HBox( )
+
creates a new horizontal box layout with all properties set to defaults. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.HBox( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.HBox properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
MinimumWidths double vectorMinimum width in pixels of each of the children. The size of this vector must match the size of Contents.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
Widths double vectorWidth of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
+ +

For example:

+
f = figure();
+b = uix.HBox( 'Parent', f );
+uicontrol( 'Parent', b, 'Background', 'r' )
+uicontrol( 'Parent', b, 'Background', 'b' )
+uicontrol( 'Parent', b, 'Background', 'g' )
+set( b, 'Widths', [-1 100 -2], 'Spacing', 5 );
+

+

+

+ +
f = figure();
+b1 = uix.VBox( 'Parent', f );
+uicontrol( 'Parent', b1, 'Background', 'r' )
+b2 = uix.HBox( 'Parent', b1, 'Padding', 5, 'Spacing', 5 );
+uicontrol( 'Parent', b2, 'String', 'Button1' )
+uicontrol( 'Parent', b2, 'String', 'Button2' )
+set( b1, 'Widths', [30 -1] );
+

+

+

+ + +
See also:
  • uix.VBox - for creating a vertical arrangement
  • uix.HBoxFlex - for creating a horizontal arrangement with draggable dividers
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference2_2.html b/Required packages/layoutdoc/Function_reference2_2.html new file mode 100644 index 0000000..95fba30 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference2_2.html @@ -0,0 +1,87 @@ + + + + + + + uix.VBox + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.2: uix.VBox Go back up one level

+ + + + + +
+

Arrange elements vertically in a single column

+
+
obj = uix.VBox( )
+
creates a new vertical box layout with all properties set to defaults. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.VBox( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.VBox properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
Heights double vectorHeight of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
MinimumHeights double vectorMinimum height in pixels of each of the children. The size of this vector must match the size of Contents.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+b = uix.VBox( 'Parent', f );
+uicontrol( 'Parent', b, 'Background', 'r' )
+uicontrol( 'Parent', b, 'Background', 'b' )
+uicontrol( 'Parent', b, 'Background', 'g' )
+set( b, 'Heights', [-1 100 -2], 'Spacing', 5 );
+

+

+

+ +
f = figure();
+b1 = uix.VBox( 'Parent', f );
+uicontrol( 'Parent', b1, 'Background', 'r' )
+b2 = uix.HBox( 'Parent', b1, 'Padding', 5, 'Spacing', 5 );
+uicontrol( 'Parent', b2, 'String', 'Button1' )
+uicontrol( 'Parent', b2, 'String', 'Button2' )
+set( b1, 'Heights', [30 -1] );
+

+

+

+ + +
See also:
  • uix.HBox - for creating a horizontal arrangement
  • uix.VBoxFlex - for creating a vertical arrangement with draggable dividers
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference2_3.html b/Required packages/layoutdoc/Function_reference2_3.html new file mode 100644 index 0000000..9b70851 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference2_3.html @@ -0,0 +1,79 @@ + + + + + + + uix.HBoxFlex + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.3: uix.HBoxFlex Go back up one level

+ + + + + + + +
+

Arrange elements horizontally with draggable dividers

+
+
obj = uix.HBoxFlex( )
+
creates a new horizontal box layout with draggable dividers and with all properties set to defaults. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.HBoxFlex( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.HBoxFlex properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
DividerMarkings on | offShow markings on the draggable dividers (default 'on').
MinimumWidths double vectorMinimum width in pixels of each of the children. The size of this vector must match the size of Contents.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
Widths double vectorWidth of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
+ +

For example:

+
f = figure( 'Name', 'uix.HBoxFlex example' );
+b = uix.HBoxFlex( 'Parent', f );
+uicontrol( 'Parent', b, 'Background', 'r' )
+uicontrol( 'Parent', b, 'Background', 'b' )
+uicontrol( 'Parent', b, 'Background', 'g' )
+uicontrol( 'Parent', b, 'Background', 'y' )
+set( b, 'Widths', [-1 100 -2 -1], 'Spacing', 5 );
+

+

+

+ + +
See also:
  • uix.HBox - for creating a horizontal arrangement
  • uix.VBoxFlex - for creating a vertical arrangement with draggable dividers
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference2_4.html b/Required packages/layoutdoc/Function_reference2_4.html new file mode 100644 index 0000000..d405aac --- /dev/null +++ b/Required packages/layoutdoc/Function_reference2_4.html @@ -0,0 +1,78 @@ + + + + + + + uix.VBoxFlex + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.4: uix.VBoxFlex Go back up one level

+ + + + + + + +
+

Arrange elements vertically with draggable dividers

+
+
obj = uix.VBoxFlex( )
+
creates a new vertical box layout with draggable dividers and with all properties set to defaults. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.VBoxFlex( prop, value, ... )
+
also sets one or more property values from the list below.
+
+ +

uix.VBoxFlex properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
DividerMarkings on | offShow markings on the draggable dividers (default 'on').
Heights double vectorHeight of each of the children. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing. The size of this vector must always match the size of Contents.
MinimumHeights double vectorMinimum height in pixels of each of the children. The size of this vector must match the size of Contents.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ + +

For example:

+
f = figure( 'Name', 'uix.VBoxFlex example' );
+b = uix.VBoxFlex( 'Parent', f );
+uicontrol( 'Parent', b, 'Background', 'r' )
+uicontrol( 'Parent', b, 'Background', 'b' )
+uicontrol( 'Parent', b, 'Background', 'g' )
+uicontrol( 'Parent', b, 'Background', 'y' )
+set( b, 'Heights', [-1 100 -2 -1], 'Spacing', 5 );
+

+

+

+ + +
See also:
  • uix.VBox - for creating a vertical arrangement
  • uix.HBoxFlex - for creating a horizontal arrangement with draggable dividers
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference2_5.html b/Required packages/layoutdoc/Function_reference2_5.html new file mode 100644 index 0000000..51602ac --- /dev/null +++ b/Required packages/layoutdoc/Function_reference2_5.html @@ -0,0 +1,80 @@ + + + + + + + uix.HButtonBox + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.5: uix.HButtonBox Go back up one level

+ + + + + + +
+

Arrange buttons horizontally in a single row

+
+
obj = uix.HButtonBox( )
+
is a type of HBox specialised for + arranging a row of buttons, check-boxes or similar graphical + elements. All buttons are given equal size and by default are + centered in the drawing area. The justification can be changed as + required.
+ +
obj = uix.HButtonBox( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.HButtonBox properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
ButtonSize [w h]The size for the buttons (all are given equal size).
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
HorizontalAlignment left | center | rightThe horizontal position of the buttons.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
VerticalAlignment top | middle | bottomThe vertical position of the buttons.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+b = uix.HButtonBox( 'Parent', f );
+uicontrol( 'Parent', b, 'String', 'One' );
+uicontrol( 'Parent', b, 'String', 'Two' );
+uicontrol( 'Parent', b, 'String', 'Three' );
+set( b, 'ButtonSize', [130 35], 'Spacing', 5 );
+

+

+

+ + +
See also:
  • uix.VButtonBox - for creating a vertical arrangement of buttons
  • uix.HBox - for creating a general horizontal arrangement
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference2_6.html b/Required packages/layoutdoc/Function_reference2_6.html new file mode 100644 index 0000000..544ec25 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference2_6.html @@ -0,0 +1,81 @@ + + + + + + + uix.VButtonBox + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

2.6: uix.VButtonBox Go back up one level

+ + + + + + +
+

Arrange buttons vertically in a single column

+
+
obj = uix.VButtonBox( )
+
is a type of VBox specialised for + arranging a column of buttons, check-boxes or similar graphical + elements. All buttons are given equal size and by default are + centered in the drawing area. The justification can be changed as + required.
+ +
obj = uix.VButtonBox( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.VButtonBox properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
ButtonSize [w h]The size for the buttons (all are given equal size).
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
HorizontalAlignment left | center | rightThe horizontal position of the buttons.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
VerticalAlignment top | middle | bottomThe vertical position of the buttons.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+b = uix.VButtonBox( 'Parent', f );
+uicontrol( 'Parent', b, 'String', 'One' );
+uicontrol( 'Parent', b, 'String', 'Two' );
+uicontrol( 'Parent', b, 'String', 'Three' );
+set( b, 'ButtonSize', [130 35], 'Spacing', 5 );
+

+

+

+ + +
See also:
  • uix.HButtonBox - for creating a horizontal arrangement of buttons
  • uix.VBox - for creating a general vertical arrangement
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/Function_reference3_1.html b/Required packages/layoutdoc/Function_reference3_1.html new file mode 100644 index 0000000..4e91d7c --- /dev/null +++ b/Required packages/layoutdoc/Function_reference3_1.html @@ -0,0 +1,82 @@ + + + + + + + uix.Grid + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

3.1: uix.Grid Go back up one level

+ + + +
+

Arrange elements in a two dimensional grid

+
+
obj = uix.Grid( )
+
creates a new new grid layout with all properties set to defaults. The number of rows and + columns to use is determined from the number of elements in the + Heights and Widths properties respectively. Child elements are + arranged down column one first, then column two etc. If there are insufficient + columns then a new one is added. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.Grid( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.Grid properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
Heights double vectorHeight of each of the rows. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
Widths double vectorWidth of each of the columns. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing.
+ +

For example:

+
f = figure();
+g = uix.Grid( 'Parent', f, 'Spacing', 5 );
+uicontrol( 'Parent', g, 'Background', 'r' )
+uicontrol( 'Parent', g, 'Background', 'b' )
+uicontrol( 'Parent', g, 'Background', 'g' )
+uix.Empty( 'Parent', g )
+uicontrol( 'Parent', g, 'Background', 'c' )
+uicontrol( 'Parent', g, 'Background', 'y' )
+set( g, 'Widths', [-1 100 -2], 'Heights', [-1 100] );
+

+

+

+ + +
See also:
  • uix.GridFlex - for creating a grid arrangement with draggable dividers
+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference3_2.html b/Required packages/layoutdoc/Function_reference3_2.html new file mode 100644 index 0000000..10574b1 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference3_2.html @@ -0,0 +1,84 @@ + + + + + + + uix.GridFlex + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

3.2: uix.GridFlex Go back up one level

+ + + + +
+

Arrange elements in a two dimensional grid with draggable dividers

+
+
obj = uix.GridFlex( )
+
creates a new new grid layout with draggable dividers between elements. The number of rows and + columns to use is determined from the number of elements in the + Heights and Widths properties respectively. Child elements are + arranged down column one first, then column two etc. If there are insufficient + columns then a new one is added. + The output is a new layout object that can be used as the parent for other user-interface components.
+ +
obj = uix.GridFlex( prop, value, ... )
+
also sets one or more property values.
+ +
+ + +

uix.GridFlex properties

+
PropertyValueDescription
BackgroundColor colorspecColor to use for exposed areas of the layout background. This can be an RGB triple (e.g. [0 0 1]) or a colour name (e.g. 'b').
BeingDeleted on | offDeletion status.
Contents empty GraphicsPlaceholder array | array of graphics objectsChildren within this layout, regardless of HandleVisibility. Note that this can only be set to permutations of itself.
DeleteFcn function_handleFunction to call when the layout is being deleted.
DividerMarkings on | offShow markings on the draggable dividers (default 'on').
Heights double vectorHeight of each of the rows. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing.
Padding positive integerNumber of pixels of extra space around the outside of the layout.
Parent empty GraphicsPlaceholder array | figure | containerParent of the layout.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Spacing positive integerNumber of pixels of extra space to leave between elements in the layout.
Tag stringTag to associate with layout.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
Widths double vectorWidth of each of the columns. Positive entries indicate fixed sizes in pixels, negative values indicate relative weights for resizing.
+ +

For example:

+
f = figure();
+g = uix.GridFlex( 'Parent', f, 'Spacing', 5 );
+uicontrol( 'Parent', g, 'Background', 'r' )
+uicontrol( 'Parent', g, 'Background', 'b' )
+uicontrol( 'Parent', g, 'Background', 'g' )
+uix.Empty( 'Parent', g )
+uicontrol( 'Parent', g, 'Background', 'c' )
+uicontrol( 'Parent', g, 'Background', 'y' )
+set( g, 'Widths', [-1 100 -2], 'Heights', [-1 -2] );
+

+

+

+ + +
See also:
  • uix.Grid - for creating a grid arrangement
+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/Function_reference4_1.html b/Required packages/layoutdoc/Function_reference4_1.html new file mode 100644 index 0000000..69f06ee --- /dev/null +++ b/Required packages/layoutdoc/Function_reference4_1.html @@ -0,0 +1,69 @@ + + + + + + + uix.Empty + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

4.1: uix.Empty Go back up one level

+ + +

Create an empty space

+
+
obj = uix.Empty( )
+
creates an empty space object that can be + used in layouts to add gaps between other elements.
+ +
obj = uix.Empty( param, value, ... )
+
also sets one or more property values.
+ +
+ +

uix.Empty properties

+

The empty space is achieved using a container that monitors + its parent's color and changes its own to match.

+
PropertyValueDescription
BeingDeleted on | offDeletion status.
HandleVisibility on | offVisibility of the object.
Parent empty GraphicsPlaceholder array | figure | containerParent of the object.
Position [x y w h]Position (x,y) and size (w,h) within figure or container.
Tag stringTag to associate with object.
Type stringType of graphics object.
Units inches | centimeters | normalized | points | pixels | charactersPosition units.
Visible on | offVisibility.
+ +

For example:

+
f = figure();
+box = uix.HBox( 'Parent', f, 'Spacing', 5 );
+uicontrol( 'Parent', box, 'Background', 'r' )
+uix.Empty( 'Parent', box )
+uicontrol( 'Parent', box, 'Background', 'g' )
+

+ +
See also:
  • uix.HBox - for arranging widgets horizontally
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference4_2.html b/Required packages/layoutdoc/Function_reference4_2.html new file mode 100644 index 0000000..17a5ce7 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference4_2.html @@ -0,0 +1,63 @@ + + + + + + + uix.tracking + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

4.2: uix.tracking Go back up one level

+ + +

tracks anonymized usage data

+
+
uix.tracking( p, v, id )
+
tracks usage to the property p for the version v and identifier id using Google Analytics.
+
uix.tracking( state )
+
turns tracking on or off.
+
state = uix.tracking( 'query' )
+
queries whether tracking is on or off.
+ +
+ +

For example:

+
uix.tracking('UA-45678-9','1.2.3','featurename')
+ +
uix.tracking('on')
+ +
state = uix.tracking('query')
+

state = 'on'

+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Function_reference4_3.html b/Required packages/layoutdoc/Function_reference4_3.html new file mode 100644 index 0000000..6507148 --- /dev/null +++ b/Required packages/layoutdoc/Function_reference4_3.html @@ -0,0 +1,57 @@ + + + + + + + layoutRoot + + + + + + + + + +
Function_referenceprevious pagenext page
+ + +
+ +

4.3: layoutRoot Go back up one level

+ + + + +

returns the folder containing the GUI layout toolbox

+
+
folder = layoutRoot( )
+
returns the full path to the folder containing the GUI Layout Toolbox.
+ +
+ +

For example:

+
folder = layoutRoot()
+

folder = 'C:\tools\glt2'

+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + +> diff --git a/Required packages/layoutdoc/GUI Layout.html b/Required packages/layoutdoc/GUI Layout.html new file mode 100644 index 0000000..1c917fc --- /dev/null +++ b/Required packages/layoutdoc/GUI Layout.html @@ -0,0 +1,5 @@ + + + + + diff --git a/Required packages/layoutdoc/Getting_Started.html b/Required packages/layoutdoc/Getting_Started.html new file mode 100644 index 0000000..f9e5952 --- /dev/null +++ b/Required packages/layoutdoc/Getting_Started.html @@ -0,0 +1,85 @@ + + + + + + + + Getting Started + + + + + + + + + + + +
GUI Layout Toolbox 2.3.1previous pagenext page
+ +

Getting Started Go back up one level

+

+ This chapter gives an overview of this package, including its purpose, +how to install it and any known issues at the time of release. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Contents

+
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/Getting_Started1.html b/Required packages/layoutdoc/Getting_Started1.html new file mode 100644 index 0000000..a409dec --- /dev/null +++ b/Required packages/layoutdoc/Getting_Started1.html @@ -0,0 +1,54 @@ + + + + + + + What is GUI Layout Toolbox? + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

1: What is GUI Layout Toolbox? Go back up one level

+ + +

GUI Layout Toolbox provides a package of MATLAB objects that allow for complex + arrangement of graphical user interface elements within a figure window. The + main capabilities provided are:

+
    +
  • Automatic element arrangement horizontally, vertically or in grids
  • +
  • Ability to specify fixed sizes or resizing weights for each element
  • +
  • Ability to "nest" layouts to produce virtually any element arrangement
  • +
  • Divider bars for user-resizing of elements
  • +
+

These element arrangement capabilities are designed to match those found as + standard in other user-interface toolkits such as Java Swing, GTK, QT etc.

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/Getting_Started2.html b/Required packages/layoutdoc/Getting_Started2.html new file mode 100644 index 0000000..35df2fe --- /dev/null +++ b/Required packages/layoutdoc/Getting_Started2.html @@ -0,0 +1,150 @@ + + + + + + + Compatibility considerations + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

2: Compatibility considerations Go back up one level

+ + + + + + + +

Section contents:

+ + +
    +
+ + +
    +
+

+ +

 2.1: Minimum MATLAB version Go back up one level

+ +

This is version 2 of GUI Layout Toolbox, designed to work with the new + MATLAB graphics system that was introduced in R2014b.

+

Version 1 works with MATLAB releases prior to R2014b that use the old + graphics system.

+

+ +

 2.2: Compatibility with version 1 Go back up one level

+ +

If you are upgrading from version 1, there are a number of compatibility + considerations:

+ +

Package name

+

Version 1 classes were contained in the package "uiextras". Version 2 classes are +contained in the package "uix". In version 2, a package "uiextras" is included +to provide support for legacy code. Classes in "uiextras" extend +corresponding classes in "uix", and contain only compatibility-related +code.

+ +

Contents property

+

The contents of version 1 objects were accessible via the property Children. +The contents of version 2 objects are accessible via the property Contents. +Version 2 objects also provide a property Children, but this controls the +vertical stacking order rather than the layout order. Legacy code that accesses +Children will run without error, but will not achieve the desired change in +layout order, and should be modified to access Contents instead.

+ +

An upcoming release of version 1 will include support for code that references +contents via Contents. That way, code modified to work in version 2 will also +work in version 1.

+ +

The background to this change is as follows. Version 1 objects were wrappers +for built-in graphics objects, and presented contents in layout order via +the property Children. Version 2 objects extend built-in graphics objects, +and as such, inherit properties, methods and events. One such property is +Children which is used to control the top-to-bottom stacking order. +MATLAB stacking rules, e.g. controls are always on top of axes, mean that +some reasonable layout orders may be invalid stacking orders, so a new +property for layout order is required.

+ +

Auto-parenting

+

The new MATLAB graphics system introduces unparented objects, i.e. those with property Parent +empty. The new system also introduces a separation between formal class constructors, e.g. +matlab.ui.container.Panel, and informal construction functions, e.g. uipanel. +Construction functions are auto-parenting, i.e. if Parent is not specified then it is set to +gcf, whereas class constructors return objects with Parent empty unless +explicitly specified. Version 2 presents a formal interface of class constructors which follow this new +convention.

+ +

Classes in "uiextras" are auto-parenting so the behavior of legacy code is +unchanged. However, best practice is to specify parent explicitly during +construction.

+ +

Defaults mechanism

+

Version 1 provided a defaults mechanism (uiextras.get, uiextras.set +and uiextras.unset) that mimicked get and set in the MATLAB +graphics system itself. This feature has been removed from version 2. Users should use an +alternative programming pattern, e.g. factory function, to create objects with standard settings.

+ +

Enable and disable

+

Version 1 provided a mechanism to enable and disable container contents using the property +Enable. This feature has been removed from version 2. Users should enable and disable +controls directly rather than via containers.

+

For more commentary, see this article.

+ +

Other property name changes

+

A number of property names have changed to achieve greater consistency +across the package. For example, RowSizes and ColumnSizes in +uiextras.Grid are now Heights and Widths in uix.Grid. The package +"uiextras" provides support for legacy property names.

+
    +
  • RowSizes in "uiextras" is Heights in "uix"
  • +
  • ColumnSizes in "uiextras" is Widths in "uix"
  • +
  • ShowMarkings in "uiextras" is DividerMarkings in "uix"
  • +
+ +

Property shape changes

+

Version 2 contents companion properties are now of the same size as Contents, +i.e. column vectors. In version 1, these properties were row vectors. The +package "uiextras" provides support for legacy property values.

+ +

Tab selection behavior

+

In version 1, after adding a tab to a tab panel, the new tab is selected.

+

In version 2, the original selection is preserved, except if the tab panel was + empty, in which case the new tab is selected. This is consistent with the + behavior of uitabgroup.

+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/Getting_Started3.html b/Required packages/layoutdoc/Getting_Started3.html new file mode 100644 index 0000000..ef65040 --- /dev/null +++ b/Required packages/layoutdoc/Getting_Started3.html @@ -0,0 +1,179 @@ + + + + + + + Release notes + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

3: Release notes Go back up one level

+ +

+ The GUI Layout Toolbox version numbers take the form major.minor.iter. The + current version you have installed can be checked by typing ver + at the MATLAB command prompt. +

+ + + + + + + + + + + + + + + + + + +

Section contents:

+ + +
    +
+ + +
    +
+

+ +

 3.1: Version 2.3.1 Go back up one level

+ +
    +
  • Released 1 February 2017
  • +
  • Specify minimum width and height of contents in uix.ScrollingPanel
  • +
  • Update contents position while dragging uix.ScrollingPanel scrollbox
  • +
  • Scroll uix.ScrollingPanel using mouse wheel
  • +
  • Updated toolbox logo
  • +
  • Updated documentation
  • +
+

+ +

 3.2: Version 2.3 Go back up one level

+ +
    +
  • Released 24 November 2016
  • +
  • Added scrolling panel
  • +
  • Expand and collapse box panel by clicking on title
  • +
  • Fixed G1493103 "Error on construction behavior is inconstistent with builtin objects"
  • +
  • Updated documentation
  • +
+

+ +

 3.3: Version 2.2.2 Go back up one level

+ +
    +
  • Released 22 August 2016
  • +
  • Fixed G1175938 "Cannot use data cursor mode with GUI Layout Toolbox containers"
  • +
  • Fixed G1367337 "Update flex container pointer on mouse press event"
  • +
  • Fixed G1380756 "Space behind TabPanel tabs should match parent color"
  • +
  • Updated documentation
  • +
  • Added anonymous tracking of version, operating system and usage to help + us prioritize the improvements we should work on
  • +
+

+ +

 3.4: Version 2.2.1 Go back up one level

+ +
    +
  • Released 26 February 2016
  • +
  • Fixed G1346921 "Mouse pointer gets confused when moving between adjacent flex containers"
  • +
  • Fixed G1357340 "BoxPanel property ForegroundColor is initialized incorrectly"
  • +
+

+ +

 3.5: Version 2.2 Go back up one level

+ +
    +
  • Released 18 December 2015
  • +
  • Improved box panel title bar appearance
  • +
  • Changed selection behavior of uix.TabGroup to match that of uitabgroup when the selected tab is removed
  • +
  • Fixed G1253937 "uix.TabPanel/redrawTabs fails" (R2015b)
  • +
  • Fixed G1292238 "uix.BoxPanel/redrawBorders fails" (R2015b)
  • +
  • Fixed G1330841 "mouse-over-divider detection does not work for docked figures" (all)
  • +
  • Fixed G1332109 "uix.Empty background color does not match that of its Parent" (all)
  • +
  • Fixed G1334867 "cannot add axes to container" (R2016a prerelease)
  • +
  • Removed internal helper classes uix.AncestryObserver, uix.LocationObserver, uix.VisibilityObserver
  • +
  • Updated documentation
  • +
+

+ +

 3.6: Version 2.1.2 Go back up one level

+ +
    +
  • Released 29 May 2015
  • +
  • Fixed G1250248 "uix.Empty becomes visible in a panel"
  • +
  • Fixed G1250249 "missing property Selection of uix.BoxPanel"
  • +
  • Fixed G1250808 "uix.TabPanel context menus are orphaned when reparenting to a different figure"
  • +
  • Updated documentation
  • +
+

+ +

 3.7: Version 2.1.1 Go back up one level

+ +
    +
  • Released 15 May 2015
  • +
  • Added context menus on uix.TabPanel tab labels (G1245669)
  • +
  • Fixed G1164656 "cannot set relative tab widths"
  • +
  • Fixed G1019441 "property RowSizes of uiextras.GridFlex sets heights not widths"
  • +
  • Fixed G1165274 "missing properties RowSizes, MinimumRowSizes, ColumnSizes, + MinimumColumnSizes of uiextras.Grid, uiextras.GridFlex"
  • +
  • Fixed G1218142 "contents are lost when reordering via property Children"
  • +
  • Protected against G1136196 "segv when setting child visibility from 'off' to 'on' in response to being reparented"
  • +
  • Updated documentation
  • +
+

+ +

 3.8: Version 2.1 Go back up one level

+ +
    +
  • Released 2 October 2014
  • +
  • Initial version for MATLAB R2014b
  • +
  • Versions 2.0.x were for prerelease testing
  • +
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/Getting_Started4.html b/Required packages/layoutdoc/Getting_Started4.html new file mode 100644 index 0000000..bdbd888 --- /dev/null +++ b/Required packages/layoutdoc/Getting_Started4.html @@ -0,0 +1,51 @@ + + + + + + + Installation + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

4: Installation Go back up one level

+ + +

+ GUI Layout Toolbox is provided as a MATLAB toolbox file (.mltbx). +

+

+ For instructions on installing and uninstalling, see the section on + managing toolboxes + in the MATLAB documentation. +

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/Getting_Started5.html b/Required packages/layoutdoc/Getting_Started5.html new file mode 100644 index 0000000..f10756e --- /dev/null +++ b/Required packages/layoutdoc/Getting_Started5.html @@ -0,0 +1,55 @@ + + + + + + + Support + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

5: Support Go back up one level

+ + +

+ This toolbox is not a MathWorks supported product. However, if you + have problems, suggestions or other comments, please contact the + authors: +

+ +

If you like this toolbox, help others to find it by leaving a rating + and comment on the MATLAB Central File Exchange. +

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/Getting_Started6.html b/Required packages/layoutdoc/Getting_Started6.html new file mode 100644 index 0000000..e3930c3 --- /dev/null +++ b/Required packages/layoutdoc/Getting_Started6.html @@ -0,0 +1,49 @@ + + + + + + + Acknowledgements + + + + + + + + + +
Getting_Startedprevious pagenext page
+ + +

6: Acknowledgements Go back up one level

+ +

The authors wish to acknowledge the earlier contributions of the following MathWorks + consultants to this area:

+
    +
  • Brad Phelan
  • +
  • Malcolm Wood
  • +
  • Richard Lang
  • +
  • Paul Kerr-Delworth
  • +
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + +> diff --git a/Required packages/layoutdoc/HierarchyExample.html b/Required packages/layoutdoc/HierarchyExample.html new file mode 100644 index 0000000..d422948 --- /dev/null +++ b/Required packages/layoutdoc/HierarchyExample.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/Images/Border.png b/Required packages/layoutdoc/Images/Border.png new file mode 100644 index 0000000..0e58e8a Binary files /dev/null and b/Required packages/layoutdoc/Images/Border.png differ diff --git a/Required packages/layoutdoc/Images/BoxInBox.png b/Required packages/layoutdoc/Images/BoxInBox.png new file mode 100644 index 0000000..799d725 Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxInBox.png differ diff --git a/Required packages/layoutdoc/Images/BoxPanel.png b/Required packages/layoutdoc/Images/BoxPanel.png new file mode 100644 index 0000000..e261f75 Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxPanel.png differ diff --git a/Required packages/layoutdoc/Images/BoxPanel2.png b/Required packages/layoutdoc/Images/BoxPanel2.png new file mode 100644 index 0000000..6a0a067 Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxPanel2.png differ diff --git a/Required packages/layoutdoc/Images/BoxPanelDockExample1.png b/Required packages/layoutdoc/Images/BoxPanelDockExample1.png new file mode 100644 index 0000000..5b4334d Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxPanelDockExample1.png differ diff --git a/Required packages/layoutdoc/Images/BoxPanelDockExample2.png b/Required packages/layoutdoc/Images/BoxPanelDockExample2.png new file mode 100644 index 0000000..71710ba Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxPanelDockExample2.png differ diff --git a/Required packages/layoutdoc/Images/BoxPanelDockExample3.png b/Required packages/layoutdoc/Images/BoxPanelDockExample3.png new file mode 100644 index 0000000..684c3b1 Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxPanelDockExample3.png differ diff --git a/Required packages/layoutdoc/Images/BoxPanelDockExample4.png b/Required packages/layoutdoc/Images/BoxPanelDockExample4.png new file mode 100644 index 0000000..ce1e8db Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxPanelDockExample4.png differ diff --git a/Required packages/layoutdoc/Images/BoxPanelHelpExample.png b/Required packages/layoutdoc/Images/BoxPanelHelpExample.png new file mode 100644 index 0000000..2ed2506 Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxPanelHelpExample.png differ diff --git a/Required packages/layoutdoc/Images/BoxPanelMinimizeExample1.png b/Required packages/layoutdoc/Images/BoxPanelMinimizeExample1.png new file mode 100644 index 0000000..739539d Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxPanelMinimizeExample1.png differ diff --git a/Required packages/layoutdoc/Images/BoxPanelMinimizeExample2.png b/Required packages/layoutdoc/Images/BoxPanelMinimizeExample2.png new file mode 100644 index 0000000..38ef843 Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxPanelMinimizeExample2.png differ diff --git a/Required packages/layoutdoc/Images/BoxPanelMinimizeExample3.png b/Required packages/layoutdoc/Images/BoxPanelMinimizeExample3.png new file mode 100644 index 0000000..d0c77cd Binary files /dev/null and b/Required packages/layoutdoc/Images/BoxPanelMinimizeExample3.png differ diff --git a/Required packages/layoutdoc/Images/CardPanel.png b/Required packages/layoutdoc/Images/CardPanel.png new file mode 100644 index 0000000..9d6708d Binary files /dev/null and b/Required packages/layoutdoc/Images/CardPanel.png differ diff --git a/Required packages/layoutdoc/Images/CombineBoxes.png b/Required packages/layoutdoc/Images/CombineBoxes.png new file mode 100644 index 0000000..8156ba3 Binary files /dev/null and b/Required packages/layoutdoc/Images/CombineBoxes.png differ diff --git a/Required packages/layoutdoc/Images/DefaultsFigure.png b/Required packages/layoutdoc/Images/DefaultsFigure.png new file mode 100644 index 0000000..e0446a1 Binary files /dev/null and b/Required packages/layoutdoc/Images/DefaultsFigure.png differ diff --git a/Required packages/layoutdoc/Images/DefaultsSystem1.png b/Required packages/layoutdoc/Images/DefaultsSystem1.png new file mode 100644 index 0000000..2c228e4 Binary files /dev/null and b/Required packages/layoutdoc/Images/DefaultsSystem1.png differ diff --git a/Required packages/layoutdoc/Images/DefaultsSystem2.png b/Required packages/layoutdoc/Images/DefaultsSystem2.png new file mode 100644 index 0000000..1065eac Binary files /dev/null and b/Required packages/layoutdoc/Images/DefaultsSystem2.png differ diff --git a/Required packages/layoutdoc/Images/Empty.png b/Required packages/layoutdoc/Images/Empty.png new file mode 100644 index 0000000..4f47041 Binary files /dev/null and b/Required packages/layoutdoc/Images/Empty.png differ diff --git a/Required packages/layoutdoc/Images/EnableExample1.png b/Required packages/layoutdoc/Images/EnableExample1.png new file mode 100644 index 0000000..0f46c6f Binary files /dev/null and b/Required packages/layoutdoc/Images/EnableExample1.png differ diff --git a/Required packages/layoutdoc/Images/EnableExample2.png b/Required packages/layoutdoc/Images/EnableExample2.png new file mode 100644 index 0000000..3d8be82 Binary files /dev/null and b/Required packages/layoutdoc/Images/EnableExample2.png differ diff --git a/Required packages/layoutdoc/Images/EnableExample3.png b/Required packages/layoutdoc/Images/EnableExample3.png new file mode 100644 index 0000000..b3f62e7 Binary files /dev/null and b/Required packages/layoutdoc/Images/EnableExample3.png differ diff --git a/Required packages/layoutdoc/Images/Grid.png b/Required packages/layoutdoc/Images/Grid.png new file mode 100644 index 0000000..47ab781 Binary files /dev/null and b/Required packages/layoutdoc/Images/Grid.png differ diff --git a/Required packages/layoutdoc/Images/GridFlex.png b/Required packages/layoutdoc/Images/GridFlex.png new file mode 100644 index 0000000..76b64c5 Binary files /dev/null and b/Required packages/layoutdoc/Images/GridFlex.png differ diff --git a/Required packages/layoutdoc/Images/HBox.png b/Required packages/layoutdoc/Images/HBox.png new file mode 100644 index 0000000..943f481 Binary files /dev/null and b/Required packages/layoutdoc/Images/HBox.png differ diff --git a/Required packages/layoutdoc/Images/HBoxFlex.png b/Required packages/layoutdoc/Images/HBoxFlex.png new file mode 100644 index 0000000..884a88e Binary files /dev/null and b/Required packages/layoutdoc/Images/HBoxFlex.png differ diff --git a/Required packages/layoutdoc/Images/HButtonBox.png b/Required packages/layoutdoc/Images/HButtonBox.png new file mode 100644 index 0000000..6f87b71 Binary files /dev/null and b/Required packages/layoutdoc/Images/HButtonBox.png differ diff --git a/Required packages/layoutdoc/Images/Panel.png b/Required packages/layoutdoc/Images/Panel.png new file mode 100644 index 0000000..a50979d Binary files /dev/null and b/Required packages/layoutdoc/Images/Panel.png differ diff --git a/Required packages/layoutdoc/Images/Panel2.png b/Required packages/layoutdoc/Images/Panel2.png new file mode 100644 index 0000000..3b2a564 Binary files /dev/null and b/Required packages/layoutdoc/Images/Panel2.png differ diff --git a/Required packages/layoutdoc/Images/ScrollingPanel.png b/Required packages/layoutdoc/Images/ScrollingPanel.png new file mode 100644 index 0000000..5ea6ecf Binary files /dev/null and b/Required packages/layoutdoc/Images/ScrollingPanel.png differ diff --git a/Required packages/layoutdoc/Images/TabPanel.png b/Required packages/layoutdoc/Images/TabPanel.png new file mode 100644 index 0000000..2b42615 Binary files /dev/null and b/Required packages/layoutdoc/Images/TabPanel.png differ diff --git a/Required packages/layoutdoc/Images/VBox.png b/Required packages/layoutdoc/Images/VBox.png new file mode 100644 index 0000000..eb3ec85 Binary files /dev/null and b/Required packages/layoutdoc/Images/VBox.png differ diff --git a/Required packages/layoutdoc/Images/VBoxFlex.png b/Required packages/layoutdoc/Images/VBoxFlex.png new file mode 100644 index 0000000..31275e3 Binary files /dev/null and b/Required packages/layoutdoc/Images/VBoxFlex.png differ diff --git a/Required packages/layoutdoc/Images/VButtonBox.png b/Required packages/layoutdoc/Images/VButtonBox.png new file mode 100644 index 0000000..f8c57aa Binary files /dev/null and b/Required packages/layoutdoc/Images/VButtonBox.png differ diff --git a/Required packages/layoutdoc/Images/VisibleExample1.png b/Required packages/layoutdoc/Images/VisibleExample1.png new file mode 100644 index 0000000..1948bca Binary files /dev/null and b/Required packages/layoutdoc/Images/VisibleExample1.png differ diff --git a/Required packages/layoutdoc/Images/VisibleExample2.png b/Required packages/layoutdoc/Images/VisibleExample2.png new file mode 100644 index 0000000..7b75ae1 Binary files /dev/null and b/Required packages/layoutdoc/Images/VisibleExample2.png differ diff --git a/Required packages/layoutdoc/Images/VisibleExample3.png b/Required packages/layoutdoc/Images/VisibleExample3.png new file mode 100644 index 0000000..23af1ba Binary files /dev/null and b/Required packages/layoutdoc/Images/VisibleExample3.png differ diff --git a/Required packages/layoutdoc/Images/axes_inner.png b/Required packages/layoutdoc/Images/axes_inner.png new file mode 100644 index 0000000..e6dcf35 Binary files /dev/null and b/Required packages/layoutdoc/Images/axes_inner.png differ diff --git a/Required packages/layoutdoc/Images/axes_layout_example_2.png b/Required packages/layoutdoc/Images/axes_layout_example_2.png new file mode 100644 index 0000000..db9a72c Binary files /dev/null and b/Required packages/layoutdoc/Images/axes_layout_example_2.png differ diff --git a/Required packages/layoutdoc/Images/axes_layout_example_3.png b/Required packages/layoutdoc/Images/axes_layout_example_3.png new file mode 100644 index 0000000..22e90cc Binary files /dev/null and b/Required packages/layoutdoc/Images/axes_layout_example_3.png differ diff --git a/Required packages/layoutdoc/Images/axes_outer.png b/Required packages/layoutdoc/Images/axes_outer.png new file mode 100644 index 0000000..096b7fc Binary files /dev/null and b/Required packages/layoutdoc/Images/axes_outer.png differ diff --git a/Required packages/layoutdoc/Images/basics_example2.png b/Required packages/layoutdoc/Images/basics_example2.png new file mode 100644 index 0000000..92367ba Binary files /dev/null and b/Required packages/layoutdoc/Images/basics_example2.png differ diff --git a/Required packages/layoutdoc/Images/basics_example3.png b/Required packages/layoutdoc/Images/basics_example3.png new file mode 100644 index 0000000..186d1d4 Binary files /dev/null and b/Required packages/layoutdoc/Images/basics_example3.png differ diff --git a/Required packages/layoutdoc/Images/basics_example4.png b/Required packages/layoutdoc/Images/basics_example4.png new file mode 100644 index 0000000..c32320b Binary files /dev/null and b/Required packages/layoutdoc/Images/basics_example4.png differ diff --git a/Required packages/layoutdoc/Images/basics_example5.png b/Required packages/layoutdoc/Images/basics_example5.png new file mode 100644 index 0000000..ad06ede Binary files /dev/null and b/Required packages/layoutdoc/Images/basics_example5.png differ diff --git a/Required packages/layoutdoc/Images/basics_example6.png b/Required packages/layoutdoc/Images/basics_example6.png new file mode 100644 index 0000000..4bbe18b Binary files /dev/null and b/Required packages/layoutdoc/Images/basics_example6.png differ diff --git a/Required packages/layoutdoc/Images/basics_example_tab.png b/Required packages/layoutdoc/Images/basics_example_tab.png new file mode 100644 index 0000000..c5bd41c Binary files /dev/null and b/Required packages/layoutdoc/Images/basics_example_tab.png differ diff --git a/Required packages/layoutdoc/Images/basics_example_vbox.png b/Required packages/layoutdoc/Images/basics_example_vbox.png new file mode 100644 index 0000000..d4a4294 Binary files /dev/null and b/Required packages/layoutdoc/Images/basics_example_vbox.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_BorderLayout.png b/Required packages/layoutdoc/Images/bigicon_BorderLayout.png new file mode 100644 index 0000000..665011d Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_BorderLayout.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_BoxPanel.png b/Required packages/layoutdoc/Images/bigicon_BoxPanel.png new file mode 100644 index 0000000..dc9bb2a Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_BoxPanel.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_CardPanel.png b/Required packages/layoutdoc/Images/bigicon_CardPanel.png new file mode 100644 index 0000000..1d0166a Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_CardPanel.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_Grid.png b/Required packages/layoutdoc/Images/bigicon_Grid.png new file mode 100644 index 0000000..afec6e5 Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_Grid.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_GridFlex.png b/Required packages/layoutdoc/Images/bigicon_GridFlex.png new file mode 100644 index 0000000..69e854f Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_GridFlex.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_HBox.png b/Required packages/layoutdoc/Images/bigicon_HBox.png new file mode 100644 index 0000000..916a497 Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_HBox.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_HBoxFlex.png b/Required packages/layoutdoc/Images/bigicon_HBoxFlex.png new file mode 100644 index 0000000..c161f95 Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_HBoxFlex.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_HButtonBox.png b/Required packages/layoutdoc/Images/bigicon_HButtonBox.png new file mode 100644 index 0000000..3a327a3 Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_HButtonBox.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_Panel.png b/Required packages/layoutdoc/Images/bigicon_Panel.png new file mode 100644 index 0000000..ccfcff5 Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_Panel.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_ScrollingPanel.png b/Required packages/layoutdoc/Images/bigicon_ScrollingPanel.png new file mode 100644 index 0000000..7f1ff08 Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_ScrollingPanel.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_TabPanel.png b/Required packages/layoutdoc/Images/bigicon_TabPanel.png new file mode 100644 index 0000000..412b0de Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_TabPanel.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_VBox.png b/Required packages/layoutdoc/Images/bigicon_VBox.png new file mode 100644 index 0000000..14b5e5b Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_VBox.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_VBoxFlex.png b/Required packages/layoutdoc/Images/bigicon_VBoxFlex.png new file mode 100644 index 0000000..867daf8 Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_VBoxFlex.png differ diff --git a/Required packages/layoutdoc/Images/bigicon_VButtonBox.png b/Required packages/layoutdoc/Images/bigicon_VButtonBox.png new file mode 100644 index 0000000..53bbaaf Binary files /dev/null and b/Required packages/layoutdoc/Images/bigicon_VButtonBox.png differ diff --git a/Required packages/layoutdoc/Images/bookicon.gif b/Required packages/layoutdoc/Images/bookicon.gif new file mode 100644 index 0000000..7f86c41 Binary files /dev/null and b/Required packages/layoutdoc/Images/bookicon.gif differ diff --git a/Required packages/layoutdoc/Images/colorbar_example_2.png b/Required packages/layoutdoc/Images/colorbar_example_2.png new file mode 100644 index 0000000..cf35f19 Binary files /dev/null and b/Required packages/layoutdoc/Images/colorbar_example_2.png differ diff --git a/Required packages/layoutdoc/Images/colorbar_example_3.png b/Required packages/layoutdoc/Images/colorbar_example_3.png new file mode 100644 index 0000000..e80b616 Binary files /dev/null and b/Required packages/layoutdoc/Images/colorbar_example_3.png differ diff --git a/Required packages/layoutdoc/Images/demoBrowser1.png b/Required packages/layoutdoc/Images/demoBrowser1.png new file mode 100644 index 0000000..6186138 Binary files /dev/null and b/Required packages/layoutdoc/Images/demoBrowser1.png differ diff --git a/Required packages/layoutdoc/Images/demoBrowser2.png b/Required packages/layoutdoc/Images/demoBrowser2.png new file mode 100644 index 0000000..88b579a Binary files /dev/null and b/Required packages/layoutdoc/Images/demoBrowser2.png differ diff --git a/Required packages/layoutdoc/Images/demoBrowser3.png b/Required packages/layoutdoc/Images/demoBrowser3.png new file mode 100644 index 0000000..096d9ef Binary files /dev/null and b/Required packages/layoutdoc/Images/demoBrowser3.png differ diff --git a/Required packages/layoutdoc/Images/demoBrowser4.png b/Required packages/layoutdoc/Images/demoBrowser4.png new file mode 100644 index 0000000..5129b57 Binary files /dev/null and b/Required packages/layoutdoc/Images/demoBrowser4.png differ diff --git a/Required packages/layoutdoc/Images/demoicon.gif b/Required packages/layoutdoc/Images/demoicon.gif new file mode 100644 index 0000000..c89e7ac Binary files /dev/null and b/Required packages/layoutdoc/Images/demoicon.gif differ diff --git a/Required packages/layoutdoc/Images/deploy.png b/Required packages/layoutdoc/Images/deploy.png new file mode 100644 index 0000000..eae1f87 Binary files /dev/null and b/Required packages/layoutdoc/Images/deploy.png differ diff --git a/Required packages/layoutdoc/Images/greenarrowicon.gif b/Required packages/layoutdoc/Images/greenarrowicon.gif new file mode 100644 index 0000000..5c5d0e4 Binary files /dev/null and b/Required packages/layoutdoc/Images/greenarrowicon.gif differ diff --git a/Required packages/layoutdoc/Images/guide1.png b/Required packages/layoutdoc/Images/guide1.png new file mode 100644 index 0000000..ce9b11e Binary files /dev/null and b/Required packages/layoutdoc/Images/guide1.png differ diff --git a/Required packages/layoutdoc/Images/guide2.png b/Required packages/layoutdoc/Images/guide2.png new file mode 100644 index 0000000..4e328f4 Binary files /dev/null and b/Required packages/layoutdoc/Images/guide2.png differ diff --git a/Required packages/layoutdoc/Images/header.png b/Required packages/layoutdoc/Images/header.png new file mode 100644 index 0000000..9e38e4e Binary files /dev/null and b/Required packages/layoutdoc/Images/header.png differ diff --git a/Required packages/layoutdoc/Images/headerBG.png b/Required packages/layoutdoc/Images/headerBG.png new file mode 100644 index 0000000..9f01b70 Binary files /dev/null and b/Required packages/layoutdoc/Images/headerBG.png differ diff --git a/Required packages/layoutdoc/Images/help_ex.png b/Required packages/layoutdoc/Images/help_ex.png new file mode 100644 index 0000000..50c5df2 Binary files /dev/null and b/Required packages/layoutdoc/Images/help_ex.png differ diff --git a/Required packages/layoutdoc/Images/help_fx.png b/Required packages/layoutdoc/Images/help_fx.png new file mode 100644 index 0000000..5ac8b7b Binary files /dev/null and b/Required packages/layoutdoc/Images/help_fx.png differ diff --git a/Required packages/layoutdoc/Images/help_gs.png b/Required packages/layoutdoc/Images/help_gs.png new file mode 100644 index 0000000..2ab3896 Binary files /dev/null and b/Required packages/layoutdoc/Images/help_gs.png differ diff --git a/Required packages/layoutdoc/Images/help_rn.png b/Required packages/layoutdoc/Images/help_rn.png new file mode 100644 index 0000000..142c6c0 Binary files /dev/null and b/Required packages/layoutdoc/Images/help_rn.png differ diff --git a/Required packages/layoutdoc/Images/help_ug.png b/Required packages/layoutdoc/Images/help_ug.png new file mode 100644 index 0000000..68381b5 Binary files /dev/null and b/Required packages/layoutdoc/Images/help_ug.png differ diff --git a/Required packages/layoutdoc/Images/leftarrow.png b/Required packages/layoutdoc/Images/leftarrow.png new file mode 100644 index 0000000..b8ffd42 Binary files /dev/null and b/Required packages/layoutdoc/Images/leftarrow.png differ diff --git a/Required packages/layoutdoc/Images/pageicon.gif b/Required packages/layoutdoc/Images/pageicon.gif new file mode 100644 index 0000000..3d35fdb Binary files /dev/null and b/Required packages/layoutdoc/Images/pageicon.gif differ diff --git a/Required packages/layoutdoc/Images/pagesicon.gif b/Required packages/layoutdoc/Images/pagesicon.gif new file mode 100644 index 0000000..9278b1f Binary files /dev/null and b/Required packages/layoutdoc/Images/pagesicon.gif differ diff --git a/Required packages/layoutdoc/Images/reficon.gif b/Required packages/layoutdoc/Images/reficon.gif new file mode 100644 index 0000000..44b0548 Binary files /dev/null and b/Required packages/layoutdoc/Images/reficon.gif differ diff --git a/Required packages/layoutdoc/Images/rightarrow.png b/Required packages/layoutdoc/Images/rightarrow.png new file mode 100644 index 0000000..4bdf3ec Binary files /dev/null and b/Required packages/layoutdoc/Images/rightarrow.png differ diff --git a/Required packages/layoutdoc/Images/titleimage.png b/Required packages/layoutdoc/Images/titleimage.png new file mode 100644 index 0000000..b9cd50b Binary files /dev/null and b/Required packages/layoutdoc/Images/titleimage.png differ diff --git a/Required packages/layoutdoc/Images/uparrow.png b/Required packages/layoutdoc/Images/uparrow.png new file mode 100644 index 0000000..4590b67 Binary files /dev/null and b/Required packages/layoutdoc/Images/uparrow.png differ diff --git a/Required packages/layoutdoc/Images/why_fixed1.png b/Required packages/layoutdoc/Images/why_fixed1.png new file mode 100644 index 0000000..f0f7bed Binary files /dev/null and b/Required packages/layoutdoc/Images/why_fixed1.png differ diff --git a/Required packages/layoutdoc/Images/why_fixed2.png b/Required packages/layoutdoc/Images/why_fixed2.png new file mode 100644 index 0000000..1b05edd Binary files /dev/null and b/Required packages/layoutdoc/Images/why_fixed2.png differ diff --git a/Required packages/layoutdoc/Images/why_layout0_1.png b/Required packages/layoutdoc/Images/why_layout0_1.png new file mode 100644 index 0000000..1b38859 Binary files /dev/null and b/Required packages/layoutdoc/Images/why_layout0_1.png differ diff --git a/Required packages/layoutdoc/Images/why_layout0_2.png b/Required packages/layoutdoc/Images/why_layout0_2.png new file mode 100644 index 0000000..80a686d Binary files /dev/null and b/Required packages/layoutdoc/Images/why_layout0_2.png differ diff --git a/Required packages/layoutdoc/Images/why_layout1.png b/Required packages/layoutdoc/Images/why_layout1.png new file mode 100644 index 0000000..80a686d Binary files /dev/null and b/Required packages/layoutdoc/Images/why_layout1.png differ diff --git a/Required packages/layoutdoc/Images/why_layout2.png b/Required packages/layoutdoc/Images/why_layout2.png new file mode 100644 index 0000000..b6e7fa1 Binary files /dev/null and b/Required packages/layoutdoc/Images/why_layout2.png differ diff --git a/Required packages/layoutdoc/Images/why_layout_anno1.png b/Required packages/layoutdoc/Images/why_layout_anno1.png new file mode 100644 index 0000000..30119a8 Binary files /dev/null and b/Required packages/layoutdoc/Images/why_layout_anno1.png differ diff --git a/Required packages/layoutdoc/Images/why_layout_anno2.png b/Required packages/layoutdoc/Images/why_layout_anno2.png new file mode 100644 index 0000000..dda9012 Binary files /dev/null and b/Required packages/layoutdoc/Images/why_layout_anno2.png differ diff --git a/Required packages/layoutdoc/Images/why_normalized1.png b/Required packages/layoutdoc/Images/why_normalized1.png new file mode 100644 index 0000000..638ccb9 Binary files /dev/null and b/Required packages/layoutdoc/Images/why_normalized1.png differ diff --git a/Required packages/layoutdoc/Images/why_normalized2.png b/Required packages/layoutdoc/Images/why_normalized2.png new file mode 100644 index 0000000..54e91d0 Binary files /dev/null and b/Required packages/layoutdoc/Images/why_normalized2.png differ diff --git a/Required packages/layoutdoc/LayoutsGUIDE.html b/Required packages/layoutdoc/LayoutsGUIDE.html new file mode 100644 index 0000000..a884084 --- /dev/null +++ b/Required packages/layoutdoc/LayoutsGUIDE.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/PanelDock.html b/Required packages/layoutdoc/PanelDock.html new file mode 100644 index 0000000..0a62955 --- /dev/null +++ b/Required packages/layoutdoc/PanelDock.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/PanelHelp.html b/Required packages/layoutdoc/PanelHelp.html new file mode 100644 index 0000000..4653cd5 --- /dev/null +++ b/Required packages/layoutdoc/PanelHelp.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/PanelMinimize.html b/Required packages/layoutdoc/PanelMinimize.html new file mode 100644 index 0000000..22b30ab --- /dev/null +++ b/Required packages/layoutdoc/PanelMinimize.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/User_guide.html b/Required packages/layoutdoc/User_guide.html new file mode 100644 index 0000000..81098f6 --- /dev/null +++ b/Required packages/layoutdoc/User_guide.html @@ -0,0 +1,95 @@ + + + + + + + + User guide + + + + + + + + + + + +
GUI Layout Toolbox 2.3.1previous pagenext page
+ +

User guide Go back up one level

+

+ This chapter describes the purpose and overall design of the layout + tools that the toolbox provides. It also provides some examples of + creating some user interfaces using layouts. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Contents

+
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide1.html b/Required packages/layoutdoc/User_guide1.html new file mode 100644 index 0000000..bf24b35 --- /dev/null +++ b/Required packages/layoutdoc/User_guide1.html @@ -0,0 +1,76 @@ + + + + + + + Understanding layouts + + + + + + + + + +
User_guideprevious pagenext page
+ + +

1: Understanding layouts Go back up one level

+ +

The purpose of a "layout" is to manage the positioning of one + or more user-interface components. This means that instead of + worrying about the exact position of each user interface component + you instead worry about the relative positioning of them; are they + arranged in a vertical list, horizontal list, a grid pattern, etc.

+

The best way to understand what layouts are and why they are a good user-interface + design tool is to see some examples. The sections below go through the + basics of building an interface using layouts and how to build complex + interfaces using them.

+ + + + + + + + + + + +

Section contents:

+
    +
+ +
    +
+ + + + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide1_1.html b/Required packages/layoutdoc/User_guide1_1.html new file mode 100644 index 0000000..e073dde --- /dev/null +++ b/Required packages/layoutdoc/User_guide1_1.html @@ -0,0 +1,88 @@ + + + + + + + Layout basics + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

1.1: Layout basics Go back up one level

+ +

To see how layouts work, let's use the most basic layout, + a horizontal list (or box). We first create a window:

+ +
f = figure();
+
+ +

Now let's create the horizontal layout and add it to the figure. Note + that in common with other MATLAB graphics objects, one object is added to + another by setting the Parent property - this will automatically + adjust the list of Children in the parent object. The job of a + horizontal box layout is to arrange its contents in a horizontal line, + setting the position of each element to best fill the space:

+ +
layout = uix.HBox( 'Parent', f );
+
+

Nothing's changed! That's because the layout is for arranging + other user-interface components - it doesn't draw anything itself. Let's + add some buttons. Note how after creating each button the existing contents + of the box make room for the new addition; we don't need to set the position of + any user-interface component!

+ +
uicontrol( 'String', 'Button 1', 'Parent', layout );
+uicontrol( 'String', 'Button 2', 'Parent', layout );
+uicontrol( 'String', 'Button 3', 'Parent', layout );
+

..

+
+

Other layouts work in exactly the same way, although visually + the end-result is quite different:

+ +
f = figure();
+layout = uix.VBox( 'Parent', f );
+uicontrol( 'String', 'Button 1', 'Parent', layout );
+uicontrol( 'String', 'Button 2', 'Parent', layout );
+uicontrol( 'String', 'Button 3', 'Parent', layout );
+

+
+ +
f = figure();
+layout = uix.TabPanel( 'Parent', f );
+uicontrol( 'String', 'Button 1', 'Parent', layout );
+uicontrol( 'String', 'Button 2', 'Parent', layout );
+uicontrol( 'String', 'Button 3', 'Parent', layout );
+

+
+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide1_2.html b/Required packages/layoutdoc/User_guide1_2.html new file mode 100644 index 0000000..c4ebeab --- /dev/null +++ b/Required packages/layoutdoc/User_guide1_2.html @@ -0,0 +1,65 @@ + + + + + + + Types of layout + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

1.2: Types of layout Go back up one level

+ +

The layouts in this toolbox come in three forms:

+
    +
  1. Panels: show a single child element with some decoration. Other children + of the layout are hidden from view. The visible child can be switched. Available + panels include + Panel, + CardPanel, + BoxPanel, + TabPanel and + ScrollingPanel.
  2. + +
  3. Boxes: arrange children linearly in a single row or column. Available boxes include + HBox, + VBox, + HBoxFlex and + VBoxFlex.
  4. + +
  5. Grids: (also known as tables) arrange children in a two-dimensional grid. Available grids include + Grid and + GridFlex.
  6. + +
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide1_3.html b/Required packages/layoutdoc/User_guide1_3.html new file mode 100644 index 0000000..42fc9b9 --- /dev/null +++ b/Required packages/layoutdoc/User_guide1_3.html @@ -0,0 +1,94 @@ + + + + + + + Sizes and units + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

1.3: Sizes and units Go back up one level

+ +

In the previous section we noted that when using layouts + you never need to set the position or size of a user-interface + component yourself - the layouts take care of it. So how do + you control the sizes of the components?

+

Each layout that arranges multiple items within its drawing area + has a sizing property: for horizontal boxes this is Widths + and for vertical boxes Heights; for grids we have both Widths + and Heights. These all obey the same convention:

+
    +
  1. Positive numbers indicate sizes in pixels (similar to "pixel" units)
  2. +
  3. Negative numbers indicate a weighting for variable sizing (similar to "normalized" units)
  4. +
+

By default all sizes are set to -1 (variable size with unit weighting).

+

Let's take a simple example:

+ +
f = figure();
+layout = uix.HBox( 'Parent', f );
+uicontrol( 'String', 'Button 1', 'Parent', layout );
+uicontrol( 'String', 'Button 2', 'Parent', layout );
+uicontrol( 'String', 'Button 3', 'Parent', layout );
+

+
+

We can set the middle element to be twice as wide as the others + (but still variable width) by setting its weight to -2 with the others at -1:

+ +
layout.Widths = [-1 -2 -1]
+

+
+

Alternatively we might want the first element to have a + fixed width of 100 pixels with the others filling any remaining + space equally:

+ +
layout.Widths = [100 -1 -1]
+

+
+ +

This ability to mix fixed and variable sized elements is + crucial in interface design. It really comes into its own when building + a hierarchy of layouts, described next.

+ + + +

  +  1.3.1: + Minimum sizes Go back up one level

+

Many of the multi-element layouts also provide a MinimumWidths + or MinimumHeights + property to prevent an element becoming too small. This is measured in + pixels and defaults to one pixel. Take care to ensure that the available + space is at least the sum of the minimum sizes, plus any padding and + spacing.

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide1_4.html b/Required packages/layoutdoc/User_guide1_4.html new file mode 100644 index 0000000..0d9620c --- /dev/null +++ b/Required packages/layoutdoc/User_guide1_4.html @@ -0,0 +1,92 @@ + + + + + + + Layout hierarchies + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

1.4: Layout hierarchies Go back up one level

+ +

Consider the following simple interface:

+
+

Instead of thinking of this in terms of three elements that need + positioning, we can break it up into two simple linear ("box") arrangements: + a vertical box with the axes at the top and a control area at the bottom and + a horizontal box containing two buttons:

+
.
+

By placing the second layout (horizontal box) inside the first (vertical box) + we arrive at the complete layout. Since the sizes of the elements in each list + can be set to be fixed or flexible we can achieve a user-interface that is not just + arranged correctly when created, but also behaves well when resized.

+
+

Note that the buttons have stayed fixed height as the window grows and the + axes grow to fill the remaining space.

+ + +

  +  1.4.1: + Code: Go back up one level

+

The example above can be created programmically pretty + much as described in text + (the completed example code is here: + [ view + | edit + | run ] + )

+

1. Open a window

+
f = figure( 'Position', 200*ones(1,4) );
+

2. Create the first layout (vertical box)
Inside this vertical box + we place the axes

+
vbox = uix.VBox( 'Parent', f );
+axes( 'Parent', vbox );
+

+
+

3. Create the second layout (horizontal box)
Inside this horizontal box + we place two buttons

+
hbox = uix.HButtonBox( 'Parent', vbox, 'Padding', 5 );
+uicontrol( 'Parent', hbox, ...
+    'String', 'Button 1' );
+uicontrol( 'Parent', hbox, ...
+    'String', 'Button 2' );
+

+
+

4. Set the sizes
We want the axes to grow with the window so + set the first size to be -1 (which means variable size with wieght 1) and the buttons to stay fixed height so set the +second size to 35 (fixed height of 35 pixels)

+
set( vbox, 'Heights', [-1 35] )
+

+
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide1_5.html b/Required packages/layoutdoc/User_guide1_5.html new file mode 100644 index 0000000..db44733 --- /dev/null +++ b/Required packages/layoutdoc/User_guide1_5.html @@ -0,0 +1,105 @@ + + + + + + + Why use layouts? + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

1.5: Why use layouts? Go back up one level

+ +

MATLAB ships with a GUI design tool called GUIDE. This + doesn't use layouts, but forces users to manually position each element. This approach + is a much faster way to build simple user-interfaces, so why would you want to +use layouts?

+

The over-riding reason for using layouts or layout managers is + to gain control of the resizing behaviour of the interface without + having to write a complex "ResizeFcn". If you simply position user-interface elements + directly (either using GUIDE or programmatically), you + have two choices about what happens when the window resizes: +

+

For example:

+ 1. The user-interface components scale with the window (normalised units)
We didn't really want the buttons to grow but everything resizes in proportion.
+
f = figure( 'Position', 200*ones(1,4) );
+axes( 'Parent', f, ...
+    'Units', 'Normalized', ...
+    'OuterPosition', [0.02 0.2 0.96 0.8] );
+uicontrol( 'Parent', f, ...
+    'Units', 'Normalized', ...
+    'Position', [0.02 0.02 0.46 0.16], ...
+    'String', 'Button 1' );
+uicontrol( 'Parent', f, ...
+    'Units', 'Normalized', ...
+    'Position', [0.52 0.02 0.46 0.16], ...
+    'String', 'Button 2' );
+

.

+ + 2. The user-interface components stay fixed and the window resize creates empty space (pixel units)
Although the buttons don't now grow, neither does the axes, which looks very odd.
+
f = figure( 'Position', 200*ones(1,4) );
+axes( 'Parent', f, ...
+    'Units', 'Pixels', ...
+    'OuterPosition', [10 35 190 175] );
+uicontrol( 'Parent', f, ...
+    'Units', 'Pixels', ...
+    'Position', [5 5 90 25], ...
+    'String', 'Button 1' );
+uicontrol( 'Parent', f, ...
+    'Units', 'Pixels', ...
+    'Position', [105 5 90 25], ...
+    'String', 'Button 2' );
+

.

+ +

Neither of these alternatives is particularly useful for a serious + user-interface. Typically there are user-interface components that should + be fixed size: icons, buttons, selectors etc; and others that should resize + with the window: graphs, images, prose text etc. To achieve this one needs + to be able to specify which interface components should be fixed size and + which variable. Over the last two decades, layouts have been shown to be + the method of choice for achieving this.

+

For example:

+ Using layouts, some user-interface components scale with the window, others stay fixed +
f = figure( 'Position', 200*ones(1,4) );
+vbox = uix.VBox( 'Parent', f );
+axes( 'Parent', vbox );
+hbox = uix.HButtonBox( 'Parent', vbox, 'Padding', 5 );
+uicontrol( 'Parent', hbox, ...
+    'String', 'Button 1' );
+uicontrol( 'Parent', hbox, ...
+    'String', 'Button 2' );
+set( vbox, 'Heights', [-1 35] )
+

.

+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/User_guide2.html b/Required packages/layoutdoc/User_guide2.html new file mode 100644 index 0000000..82cab7c --- /dev/null +++ b/Required packages/layoutdoc/User_guide2.html @@ -0,0 +1,68 @@ + + + + + + + Positioning axes + + + + + + + + + +
User_guideprevious pagenext page
+ + +

2: Positioning axes Go back up one level

+ + +

+ Unlike other MATLAB user interface components, axes + have two position properties: Position and + OuterPosition. This means one has some extra + options as to how the layout will arrange the axes. +

+ + + + + + + +

Section contents:

+
    +
+ +
    +
+ + + + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide2_1.html b/Required packages/layoutdoc/User_guide2_1.html new file mode 100644 index 0000000..8fecb51 --- /dev/null +++ b/Required packages/layoutdoc/User_guide2_1.html @@ -0,0 +1,62 @@ + + + + + + + Position vs OuterPosition + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

2.1: Position vs OuterPosition Go back up one level

+ +

Typically one + would position some axes using their OuterPosition so that the + axis labels, title and other annotations are all contained within the + specified area. Sometimes, particularly if drawing images, one might want + to instead make the axes canvas (the white bit!) fill the specified area. + This is done by setting the Position property instead. +

+ +

For example:

+
figure
+axes( 'Units', 'Normalized', 'OuterPosition', [0 0 1 1] )
+                    
+

+ +
figure
+axes( 'Units', 'Normalized', 'Position', [0 0 1 1] )
+                    
+

+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide2_2.html b/Required packages/layoutdoc/User_guide2_2.html new file mode 100644 index 0000000..ea7fdb7 --- /dev/null +++ b/Required packages/layoutdoc/User_guide2_2.html @@ -0,0 +1,92 @@ + + + + + + + Axes inside layouts + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

2.2: Axes inside layouts Go back up one level

+ +

(The code for this example can be found here: + [ view + | edit + | run ] + )

+

+ When using layouts to position axes, the position property + is set by the layout, not the user. Whether the Position + or OuterPosition property is used is determined by the + ActivePositionProperty property of the axes. + Note that the default setting is "outerposition". +

+

+ The following example illustrates the two usages. +

+ +

Open a window

+

Open a new figure window and remove the toolbar and menus.

+
window = figure( 'Name', 'Axes inside layouts', ...
+            'MenuBar', 'none', ...
+            'Toolbar', 'none', ...
+            'NumberTitle', 'off' );
+
+

Create the layout

+

The layout involves two axes side by side. This is done using a flexible horizontal box. The left-hand axes is left with the ActivePositionProperty set to "outerposition", but the right-hand axes is switched to use Position.

+
hbox = uix.HBoxFlex('Parent', window, 'Spacing', 3);
+axes1 = axes( 'Parent', hbox, ...
+    'ActivePositionProperty', 'outerposition' );
+axes2 = axes( 'Parent', hbox, ...
+    'ActivePositionProperty', 'Position' );
+set( hbox, 'Widths', [-2 -1] );
+

+
+ +

Fill the axes

+

Using OuterPosition (left-hand axes) is the normal mode and looks good for virtually any plot type. Using Position is only really useful for 2D plots with the axes turned off, such as images.

+
x = membrane( 1, 15 );
+surf( axes1, x );
+lighting( axes1, 'gouraud' );
+shading( axes1, 'interp' );
+l = light( 'Parent', axes1 );
+camlight( l, 'head' );
+axis( axes1, 'tight' );
+
+imagesc( x, 'Parent', axes2 );
+set( axes2, 'xticklabel', [], 'yticklabel', [] );
+

+
+

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide2_3.html b/Required packages/layoutdoc/User_guide2_3.html new file mode 100644 index 0000000..5543bd9 --- /dev/null +++ b/Required packages/layoutdoc/User_guide2_3.html @@ -0,0 +1,85 @@ + + + + + + + Colorbars and legends + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

2.3: Colorbars and legends Go back up one level

+ +

(The code for this example can be found here: + [ view + | edit + | run ] + )

+

+ When using layouts to position axes that can also have a + colorbar or legend it is very important to group the axes + with its colorbar and legend by putting them inside a uicontainer. +

+

+ The following example illustrates this. +

+ +

Open a window

+

Open a new figure window and remove the toolbar and menus.

+
window = figure( 'Name', 'Axes legend and colorbars', ...
+            'MenuBar', 'none', ...
+            'Toolbar', 'none', ...
+            'NumberTitle', 'off' );
+
+ +

Create the layout

+

The layout involves two axes side by side. Each axes is placed into a uicontainer so that the legend and colorbar are "grouped" with the axes.

+
hbox = uix.HBoxFlex('Parent', window, 'Spacing', 3);
+axes1 = axes( 'Parent', uicontainer('Parent', hbox) );
+axes2 = axes( 'Parent', uicontainer('Parent', hbox) );
+

+
+ +

Add decorations

+

Give the first axes a colorbar and the second axes a legend.

+
surf( axes1, membrane( 1, 15 ) );
+colorbar( axes1 );
+
+theta = 0:360; +plot( axes2, theta, sind(theta), theta, cosd(theta) ); +legend( axes2, 'sin', 'cos', 'Location', 'NorthWestOutside' );
+

+
+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/User_guide3.html b/Required packages/layoutdoc/User_guide3.html new file mode 100644 index 0000000..b88926c --- /dev/null +++ b/Required packages/layoutdoc/User_guide3.html @@ -0,0 +1,57 @@ + + + + + + + Controlling visibility + + + + + + + + + +
User_guideprevious pagenext page
+ + +

3: Controlling visibility Go back up one level

+ +

The examples in this section show the effect of setting the + Visible property on a layout object.

+ + + +

Section contents:

+
    +
+ +
    +
+ + + + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide3_1.html b/Required packages/layoutdoc/User_guide3_1.html new file mode 100644 index 0000000..4536042 --- /dev/null +++ b/Required packages/layoutdoc/User_guide3_1.html @@ -0,0 +1,84 @@ + + + + + + + Visible example + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

3.1: Visible example Go back up one level

+ +

(The code for this example can be found here: + [ view + | edit + | run ] + )

+

+ This example shows how the Visible property can be + used to hide whole sections of an interface. +

+ + Open a window and add a panel +
fig = figure( 'Name', 'Visible example', ...
+    'Position', [100 100 150 250], ...
+    'MenuBar', 'none', ...
+    'ToolBar', 'none', ...
+    'NumberTitle', 'off' );
+panel = uix.BoxPanel( 'Parent', fig, 'Title', 'Panel' );
+

+
+ + Put some buttons inside the panel +
box = uix.VButtonBox( 'Parent', panel );
+uicontrol( 'Parent', box, 'String', 'Button 1' );
+uicontrol( 'Parent', box, 'String', 'Button 2' );
+uicontrol( 'Parent', box, 'String', 'Button 3', 'Visible', 'off' );
+uicontrol( 'Parent', box, 'String', 'Button 4' );
+uicontrol( 'Parent', box, 'String', 'Button 5', 'Visible', 'off' );
+uicontrol( 'Parent', box, 'String', 'Button 6' );
+

+
+ + Try hiding the panel +
set( panel, 'Visible', 'off' );
+

+
+ + Try showing the panel. Note that the original Visible state of each button is remembered. +
set( panel, 'Visible', 'on' );
+

+
+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/User_guide4.html b/Required packages/layoutdoc/User_guide4.html new file mode 100644 index 0000000..a801d9c --- /dev/null +++ b/Required packages/layoutdoc/User_guide4.html @@ -0,0 +1,71 @@ + + + + + + + Advanced maneuvers with panels + + + + + + + + + +
User_guideprevious pagenext page
+ + +

4: Advanced maneuvers with panels Go back up one level

+ +

+ The uix.BoxPanel provides some extra buttons + and callbacks that can be used to design advanced user-interface + layouts. In particular, the sections below illustrate how to create + interfaces with context help, and panels that can be minimized or undocked. +

+ + + + + + + + + + + +

Section contents:

+
    +
+ +
    +
+ + + + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide4_1.html b/Required packages/layoutdoc/User_guide4_1.html new file mode 100644 index 0000000..0eb56a7 --- /dev/null +++ b/Required packages/layoutdoc/User_guide4_1.html @@ -0,0 +1,62 @@ + + + + + + + Context help + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

4.1: Context help Go back up one level

+ +

+ When a uix.BoxPanel has its HelpFcn + filled in, a help button (?) is shown in the upper-right of the + title-bar. When the user clicks this button the specified function + is called. +

+

For example:

+ Here we hookup the HelpFcn to simply bring up + the MATLAB documentation for each command. Clicking any of the "?" buttons + will cause the MATLAB help browser to open. +
f = figure( 'Name', 'uix.BoxPanel Help Example' );
+b = uix.HBox( 'Parent', f );
+uix.BoxPanel( 'Parent', b, 'Title', 'sin', 'HelpFcn', @(a,b) doc('sin') );
+uix.BoxPanel( 'Parent', b, 'Title', 'cos', 'HelpFcn', @(a,b) doc('cos') );
+uix.BoxPanel( 'Parent', b, 'Title', 'tan', 'HelpFcn', @(a,b) doc('tan') );
+
+

+ + + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide4_2.html b/Required packages/layoutdoc/User_guide4_2.html new file mode 100644 index 0000000..809963f --- /dev/null +++ b/Required packages/layoutdoc/User_guide4_2.html @@ -0,0 +1,140 @@ + + + + + + + Minimize and maximize + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

4.2: Minimize and maximize Go back up one level

+ +

+ When a uix.BoxPanel has its MinimizeFcn + filled in, a minimize/maximize button (â–´/â–¾) is shown in the upper-right of the + title-bar. When the user clicks this button the specified function + is called. Since the behaviour of the parent container is + different in different use-cases, it is up to the user to write + some code to actually resize the panel. Note that minimizing + a panel to its title-bar only really makes sense inside a + uix.VBox or uix.VBoxFlex. +

+

The following simple example shows how to add minimize/maximize + functionality to a box full of panels. Save the code into + a file called "minimizeexample.m" to run it.

+ +

(The code for this example can be found here: + [ view + | edit + | run ] + )

+ + +

Create the layout with three panels

+

Open a new figure window and add three panels.

+
function minimizeexample()
+width = 200;
+pheightmin = 20;
+pheightmax = 100;
+
+% Create the window and main layout
+fig = figure( 'Name', 'Collapsable GUI example', ...
+              'NumberTitle', 'off', ...
+              'Toolbar', 'none', ...
+              'MenuBar', 'none' );
+box = uix.VBox( 'Parent', fig );
+
+panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box );
+panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box );
+panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box );
+set( box, 'Heights', pheightmax*ones(1,3) );
+
+% Add some contents.
+uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} );
+uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} );
+uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', panel{3} );
+
+% Resize the window
+pos = get( fig, 'Position' );
+set( fig, 'Position', [pos(1,1:2),width,sum(box.Heights)] );
+

+
+ +

Add the minimize/maximize callback

+

We set each panel to call the same minimize/maximize function. + This function is nested inside the main function so that it has access + to the main function's variables. A better way to do this is to make the +main function into a class, but this nested-function approach is fine +for simple applications.

+

Note that as soon as we set the "MinimizeFcn" property the minimize/maximize + icon appears in the top-right of each panel. We use a cell-array to pass an + extra argument, the panel number, to the minimize function. This extra argument appears after the usual + eventSource and eventData arguments.

+
% Hook up the minimize callback.
+set( panel{1}, 'MinimizeFcn', {@nMinimize, 1} );
+set( panel{2}, 'MinimizeFcn', {@nMinimize, 2} );
+set( panel{3}, 'MinimizeFcn', {@nMinimize, 3} );
+
+%-------------------------------------------------------------------------%
+ function nMinimize( eventSource, eventData, whichpanel ) + % A panel has been maximized/minimized + s = get( box, 'Heights' ); + pos = get( fig, 'Position' ); + panel{whichpanel}.Minimized = ~panel{whichpanel}.Minimized; + if panel{whichpanel}.Minimized + s(whichpanel) = pheightmin; + else + s(whichpanel) = pheightmax; + end  + set( box, 'Heights', s ); + + % Resize the figure, keeping the top stationary + delta_height = pos(1,4) - sum( box.Heights ); + set( fig, 'Position', pos(1,:) + [0 delta_height 0 -delta_height] ); + end % Minimize  + +end % Main function
+

+
+ + +

Click the minimize buttons

+

Minimizing the middle panel causes it to shrink to just its + title-bar and the window shrinks accordingly. The + "Minimize" icon is replaced by a "Maximise" icon.

+

+

Re-maximizing the panel would + cause it to re-appear in full and the window to grow again.

+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide4_3.html b/Required packages/layoutdoc/User_guide4_3.html new file mode 100644 index 0000000..b32cb4b --- /dev/null +++ b/Required packages/layoutdoc/User_guide4_3.html @@ -0,0 +1,154 @@ + + + + + + + Dock and undock + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

4.3: Dock and undock Go back up one level

+ + +

+ When a uix.BoxPanel has its DockFcn + filled in, a dock/undock button (↘/↗) is shown in the upper-right of the + title-bar. When the user clicks this button the specified function + is called. Since re-docking the panel into its previous parent + depends on the type of parent, it is up to the user to write + some code to actually extract or insert the panel. +

+

The following simple example shows how to add dock/undock + functionality to a box full of panels. Save the code into + a file called "dockexample.m" to run it.

+ +

(The code for this example can be found here: + [ view + | edit + | run ] + )

+ +

Create the layout with three panels

+

Open a new figure window and add three panels.

+
function dockexample()
+% Create the window and main layout
+fig = figure( 'Name', 'Dockable GUI example', ...
+              'NumberTitle', 'off', ...
+              'Toolbar', 'none', ...
+              'MenuBar', 'none', ...
+              'CloseRequestFcn', @nCloseAll );
+box = uix.HBox( 'Parent', fig );
+
+% Add three panels to the box
+panel{1} = uix.BoxPanel( 'Title', 'Panel 1', 'Parent', box );
+panel{2} = uix.BoxPanel( 'Title', 'Panel 2', 'Parent', box );
+panel{3} = uix.BoxPanel( 'Title', 'Panel 3', 'Parent', box );
+
+% Add some contents
+uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} ); +uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', panel{3} );
+

+
+ +

Add the dock/undock callback

+

We set each panel to call the same dock/undock function. + This function is nested inside the main function so that it has access + to the main function's variables. A better way to do this is to make the +main function into a class, but this nested-function approach is fine +for simple applications.

+

Note that as soon as we set the "DockFcn" property the Dock/Undock + icon appears in the top-right of each panel. We use a cell-array to pass an + extra argument, the panel number, to the minimize function. This extra argument appears after the usual + eventSource and eventData arguments.

+
% Set the dock/undock callback
+set( panel{1}, 'DockFcn', {@nDock, 1} ); +set( panel{2}, 'DockFcn', {@nDock, 2} ); +set( panel{3}, 'DockFcn', {@nDock, 3} ); + +%-------------------------------------------------------------------------%
+ function nDock( eventSource, eventData, whichpanel ) + % Set the flag + panel{whichpanel}.IsDocked = ~panel{whichpanel}.IsDocked; + if panel{whichpanel}.IsDocked + % Put it back into the layout + newfig = get( panel{whichpanel}, 'Parent' ); + set( panel{whichpanel}, 'Parent', box ); + delete( newfig ); + else  + % Take it out of the layout + pos = getpixelposition( panel{whichpanel} ); + newfig = figure( ... + 'Name', get( panel{whichpanel}, 'Title' ), ... + 'NumberTitle', 'off', ... + 'MenuBar', 'none', ... + 'Toolbar', 'none', ... + 'CloseRequestFcn', {@nDock, whichpanel} ); + figpos = get( newfig, 'Position' ); + set( newfig, 'Position', [figpos(1,1:2), pos(1,3:4)] ); + set( p{whichpanel}, 'Parent', newfig, ... + 'Units', 'Normalized', ... + 'Position', [0 0 1 1] ); + end  + end % nDock
+ + +

Add the close callback

+

If the user closes the main window we need to also close any + other windows that were created. This can be done by finding + the window that contains each panel and deleting it.

+
%-------------------------------------------------------------------------%
+ function nCloseAll( ~, ~ ) + for ii=1:numel( panel ) + if isvalid( panel{ii} ) && ~strcmpi( panel{ii}.BeingDeleted, 'on' ) + figh = ancestor( panel{ii}, 'figure' ); + delete( figh ); + end  + end  + + end % nCloseAll +end % Main function
+

+
+ +

Click the dock buttons

+

Undocking the middle panel causes the other two to fill the + vacated space. The undocked panel appears in its own window, with the + "Undock" icon replaced by a "Dock" icon.

+

.

+

Re-docking the panel would + cause it to be appended to the right of the list in the original window. Closing the main window + causes all panels, docked or undocked, and their enclosing windows to be closed.

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/User_guide5.html b/Required packages/layoutdoc/User_guide5.html new file mode 100644 index 0000000..e368e38 --- /dev/null +++ b/Required packages/layoutdoc/User_guide5.html @@ -0,0 +1,84 @@ + + + + + + + Using layouts inside GUIDE GUIs + + + + + + + + + +
User_guideprevious pagenext page
+ + +

5: Using layouts inside GUIDE GUIs Go back up one level

+ + +

Whilst the layouts in this toolbox do not integrate into the + MATLAB Graphical User Interface Design Environment (GUIDE), it + is possible to insert layouts into a GUIDE-built GUI as follows:

+

Create the GUIDE GUI

+

Create you GUIDE application as usual, placing a panel where you + want to insert the layout. You can turn the panel border and title + off if you do not want them.

+
+ +

Insert the layout

+

Edit the "OpeningFcn" in the GUIDE-created code and insert your + layout into the panel, making it fill the space. In the example below +four boxpanels are inserted into a grid, which itself is placed inside + uipanel1:

+ +
% --- Executes just before guideApp is made visible. 
+function guideApp_OpeningFcn(hObject, eventdata, handles, varargin)
+
+% Choose default command line output for guideApp 
+handles.output = hObject;
+
+% Update handles structure 
+guidata(hObject, handles);
+
+% Put a layout in the panel 
+g = uix.GridFlex( 'Parent', handles.uipanel1, ...
+    'Units', 'Normalized', 'Position', [0 0 1 1], ...
+    'Spacing', 5 );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 1' );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 2' );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 3' );
+uix.BoxPanel( 'Parent', g, 'Title', 'Panel 4' );
+g.Heights = [-1 -1];
+

+
+

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/User_guide6.html b/Required packages/layoutdoc/User_guide6.html new file mode 100644 index 0000000..cb1f4bb --- /dev/null +++ b/Required packages/layoutdoc/User_guide6.html @@ -0,0 +1,56 @@ + + + + + + + Deploying GUIs using the MATLAB Compiler + + + + + + + + + +
User_guideprevious pagenext page
+ + +

6: Deploying GUIs using the MATLAB Compiler Go back up one level

+ + + +

Applications built using these layout tools can be deployed as standalone + executables using the MATLAB Compiler in + the same way as any other MATLAB application. There is, however, one thing to watch out for:

+
    +
  • You must explicitly include the "Resources" folder within the +uix package
  • +
+

Example

+

Below is a screen-shot of the deploytool setup + used to build the example application. + The "Resources" folder from the toolbox has been explicitly added as a +shared resource so that the mouse-pointers and panel icons continue to work.

+

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + + diff --git a/Required packages/layoutdoc/User_guide7.html b/Required packages/layoutdoc/User_guide7.html new file mode 100644 index 0000000..9a26e56 --- /dev/null +++ b/Required packages/layoutdoc/User_guide7.html @@ -0,0 +1,90 @@ + + + + + + + A complete example + + + + + + + + + +
User_guideprevious pagenext page
+ + +

7: A complete example Go back up one level

+ + + + +

The following example application uses many of the layout features + discussed above in order to create a good-looking user interface that + scales well when resized. It is not designed to showcase all the + layout functionality, but shows how callbacks are added to provide + user interaction. It also exemplifies separating the data from the GUI, + a fundamental part of creating modular and maintainable applications.

+

The full application is available here:

+ + + + + + + + + + + + + + + + + + + +

Section contents:

+
    +
+ +
    +
+ + + + + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide7_1.html b/Required packages/layoutdoc/User_guide7_1.html new file mode 100644 index 0000000..62d544b --- /dev/null +++ b/Required packages/layoutdoc/User_guide7_1.html @@ -0,0 +1,105 @@ + + + + + + + Application structure + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.1: Application structure Go back up one level

+ + +

There are many ways to build graphical applications in MATLAB, but + here we will take a very simple approach. If the application were to become +larger and more complex, this approach would be changed to better mitigate + the complexity. Some notes on this are contained at the end.

+ +

The application is structured as a single function with callbacks and other helper + functions stored as "nested" subfunctions, i.e. functions inside the main function. This has + the advantage that the nested subfunctions can share access to any variables + declared in the main function. This is also a risk as anything we accidentally + declare in the main function becomes "global" within the application. For that reason + all logic is put into subfunctions and we restrict the main + function to just declaring two shared variables:

+
    +
  • data: a structure containing all shared data
  • +
  • gui: a structure containing handles to GUI widgets
  • +
+

+function demoBrowser()
+
+   % Declare shared variables
+   data = createData();
+   gui = createInterface( data.DemoNames );
+
+   % Now update the GUI with the current data
+   updateInterface();
+   redrawDemo();
+   
+   % Helper subfunctions.
+   function data = createData() ... end;
+   function gui = createInterface(names) ... end;
+   function updateInterface() ... end;
+   function redrawDemo() ... end;
+
+   % Callback subfunctions.
+   function onMenuSelection() ... end;
+   function onListSelection() ... end;
+   function onDemoHelp() ... end;
+   function onHelp() ... end;
+   function onExit() ... end;
+
+end  % Main function
+
+ +

Note that all of the work is done in subfunctions. Most subfunctions +are callbacks executed when a button is pressed or a menu selected. The four used +at startup are helper functions:

+
    +
  • createData: build the structure which contains all application data
  • +
  • createInterface: build the user interface
  • +
  • updateInterface: update selectors etc in response to a change in the data
  • +
  • redrawDemo: redraw the plot part of the interface
  • +
+

We will not dig into all the subfunctions and callbacks, but instead + concentrate on the GUI creation (createInterface) + and update (updateInterface).

+ +

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide7_2.html b/Required packages/layoutdoc/User_guide7_2.html new file mode 100644 index 0000000..b6bc4d2 --- /dev/null +++ b/Required packages/layoutdoc/User_guide7_2.html @@ -0,0 +1,105 @@ + + + + + + + createInterface + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.2: createInterface Go back up one level

+ +

The interface creation is handled in the createInterface + subfunction. This has two distinct sections: menu building and widget arrangement. + The menus are built using the standard MATLAB menu building command uimenu, + so let's concentrate on the widget arrangement.

+ +

The top-level layout is a horizontal arrangement, placing the controls +to the left of the main plot. We make the layout draggable by using the +"flex" variant of HBox, and put a panel in each side. Note that setting the +"HelpFcn" for the view panel adds a small "?" icon for bringing up help. See +here for more details.

+

+% Add the contents
+mainLayout = uix.HBoxFlex( 'Parent', gui.Window, 'Spacing', 3 );
+
+% Create the panels
+controlPanel = uix.BoxPanel( ...
+   'Parent', mainLayout, ...
+   'Title', 'Select a demo:' );
+gui.ViewPanel = uix.BoxPanel( ...
+   'Parent', mainLayout, ...
+   'Title', 'Viewing: ???', ...
+   'HelpFcn', @onDemoHelp );
+
+% Adjust the main layout
+set( mainLayout, 'Widths', [-1,-2] ); +
+

+
+

The controls panel is filled with a vertical layout containing the listbox +and a button. Note the callbacks that are specified for both the list and button. These +both call further subfunctions that are able to access the common "data" and "gui" +shared structures.

+

+% Create the controls
+controlLayout = uix.VBox( 'Parent', controlPanel, ...
+   'Padding', 3, 'Spacing', 3 );
+gui.ListBox = uicontrol( 'Style', 'list', ...
+   'BackgroundColor', 'w', ...
+   'Parent', controlLayout, ...
+   'String', demoList(:), ...
+   'Value', 1, ...
+   'Callback', @onListSelection);
+gui.HelpButton = uicontrol( 'Style', 'PushButton', ...
+   'Parent', controlLayout, ...
+   'String', 'Help for <demo>', ...
+   'Callback', @onDemoHelp );
+set( controlLayout, 'Heights', [-1 28] ); % Make the list fill the space
+
+

+
+

Finally, the view itself is simply an axes placed inside the view panel:

+

+% Create the view
+gui.ViewAxes = axes( 'Parent', gui.ViewPanel );
+   
+

+
+

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide7_3.html b/Required packages/layoutdoc/User_guide7_3.html new file mode 100644 index 0000000..ac4a701 --- /dev/null +++ b/Required packages/layoutdoc/User_guide7_3.html @@ -0,0 +1,70 @@ + + + + + + + updateInterface + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.3: updateInterface Go back up one level

+ +

The second subfunction we will look at, updateInterface, uses the + current selections to update the interface. This uses the structure + "data" to update various parts of the interface. For this simple example this just means: +

+

1. Update the selected item in the listbox

+
set( gui.ListBox, 'Value', data.SelectedDemo );
+

2. Update the help button label

+
demoName = data.DemoNames{ data.SelectedDemo };
set( gui.HelpButton, 'String', ['Help for ',demoName] );
+

3. Update the view panel title

+
set( gui.ViewPanel, 'Title', sprintf( 'Viewing: %s', demoName ) );
+

4. Update the ticked menu

+
menus = get( gui.ViewMenu, 'Children' );
+set( menus, 'Checked', 'off' );
+% Use the name to work out which menu item should be ticked
+whichMenu = strcmpi( demoName, get( menus, 'Label' ) );
+set( menus(whichMenu), 'Checked', 'on' );
+
+

+

In general, this update function is called whenever the underlying + shared "data" structure is changed. This happens when the user clicks + a button, selects a list item or a menu. Next we will look at a typical + callback.

+

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide7_4.html b/Required packages/layoutdoc/User_guide7_4.html new file mode 100644 index 0000000..3690840 --- /dev/null +++ b/Required packages/layoutdoc/User_guide7_4.html @@ -0,0 +1,70 @@ + + + + + + + onListSelection + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.4: onListSelection Go back up one level

+ +

Finally, let's have a look at how one of the callbacks works: "onListSelection", the function + that is called when an item is selected in the listbox. The other + callbacks obey the same pattern.

+

The basic rule of thumb is that a callback should not update any part of + the user interface directly - it's job is to respond to user interaction by changing the "data" structure. + In this example, each callback changes the underlying data structure + then asks the interface to refresh. This might mean that things update in the +interface that don't need to, but ensures the callbacks remain simple and that all +interface update logic is in one place. Extending this to more granular interface updates + is straightforward. See Scalability for more details.

+

For the listbox callback, the "src" argument is a handle to the + listbox and we simply need to update the SelectedDemo field of "data" + to reflect the new selection. We then ask the rest of the interface to + update in response to the change. +

+

+                % User selected a demo from the list - update "data" and refresh
+data.SelectedDemo = get( src, 'Value' );
+updateInterface();
+redrawDemo();
+

+
+

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide7_5.html b/Required packages/layoutdoc/User_guide7_5.html new file mode 100644 index 0000000..02585fe --- /dev/null +++ b/Required packages/layoutdoc/User_guide7_5.html @@ -0,0 +1,61 @@ + + + + + + + Running it + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.5: Running it Go back up one level

+ +

When the main function is launched (click + here) + it first creates the data, then the GUI, then updates the GUI using the data. At this point the + function exits and control is returned to the command prompt. Note, however, + that the GUI is still onscreen and will still respond to user interaction.

+

This works because the "shared" variables in the main function are not cleared when the + function exits. They are only cleared once the GUI is closed. This is a slightly + unusual, but very useful, feature of using nested functions for building + applications.

+

For example:

+
>> demoBrowser
+

+ +

(Full source code for this application is available here: + [ view + | edit + | run ] + )

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + + diff --git a/Required packages/layoutdoc/User_guide7_6.html b/Required packages/layoutdoc/User_guide7_6.html new file mode 100644 index 0000000..67e27af --- /dev/null +++ b/Required packages/layoutdoc/User_guide7_6.html @@ -0,0 +1,60 @@ + + + + + + + Scalability + + + + + + + + + +
User_guideprevious pagenext page
+ + +
+ +

7.6: Scalability Go back up one level

+ +

As applications get bigger the code gets more complex. The simple + application structure used here does not scale well to large applications, + however some small adjustments can make life much better:

+
    +
  • Convert the "data" structure into a handle object. This allows + a single "data" object to be shared between mutliple graphical interfaces, and in turn means that the interface + need not be built as a single monolithic entity.
  • +
  • Use the events system to trigger updates + to specific parts of the GUI in response to bits of the data object changing. This removes the need + for a single large "UpdateInterface" function and reduces coupling between parts of the interface. For example, + the "SelectedDemo" property would have an associated event such that when it is changed by a callback (or from the command-line) it + notifies other interface components of the change. Each interface component (or group thereof) can + just listen for the events that affect it.
  • +
+

Advice on how to build large-scale applications is beyond the scope + of this document. If you need help in this area, please contact your MathWorks + account manager who will be able to put you in touch with a technical specialist.

+ + +
+ + + + + + + + + + © 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks + + + +> diff --git a/Required packages/layoutdoc/VisibleExample.html b/Required packages/layoutdoc/VisibleExample.html new file mode 100644 index 0000000..bfdfc18 --- /dev/null +++ b/Required packages/layoutdoc/VisibleExample.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/about.html b/Required packages/layoutdoc/about.html new file mode 100644 index 0000000..98f06e3 --- /dev/null +++ b/Required packages/layoutdoc/about.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/atoz.html b/Required packages/layoutdoc/atoz.html new file mode 100644 index 0000000..38ebbb7 --- /dev/null +++ b/Required packages/layoutdoc/atoz.html @@ -0,0 +1,181 @@ + + + + + GUI Layout Toolbox documentation: Index + + +
+ GUI Layout Toolbox 2.3.1 +
+

Alphabetical index

+
+ A - + B - + C - + D - + E - + F - + G - + H - + I - + J - + K - + L - + M +
+ N - + O - + P - + Q - + R - + S - + T - + U - + V - + W - + X - + Y - + Z +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

A

A complete exampleA complete example (User guide: 7)
AboutWhat is GUI Layout Toolbox? (Getting Started: 1)
AcknowledgementsAcknowledgements (Getting Started: 6)
Advanced maneuvers with panelsAdvanced maneuvers with panels (User guide: 4)
Application designA complete example (User guide: 7)
Application structureApplication structure (User guide: 7.1)
axesPositioning axes (User guide: 2)
Axes inside layoutsAxes inside layouts (User guide: 2.2)

B

Boxuix.HBox (Function reference: 2.1)
 uix.VBox (Function reference: 2.2)
 uix.HBoxFlex (Function reference: 2.3)
 uix.VBoxFlex (Function reference: 2.4)
BoxesBoxes (Function reference: 2)
BoxPaneluix.BoxPanel (Function reference: 1.3)
Button boxuix.HButtonBox (Function reference: 2.5)
 uix.VButtonBox (Function reference: 2.6)

C

CallbacksA complete example (User guide: 7)
CardPaneluix.CardPanel (Function reference: 1.2)
Colorbars and legendsColorbars and legends (User guide: 2.3)
Compatibility considerationsCompatibility considerations (Getting Started: 2)
CompilerDeploying GUIs using the MATLAB Compiler (User guide: 6)
Context helpContext help (User guide: 4.1)
Controlling visibilityControlling visibility (User guide: 3)
createInterfacecreateInterface (User guide: 7.2)

D

Deploying GUIs using the MATLAB CompilerDeploying GUIs using the MATLAB Compiler (User guide: 6)
Dock and undockDock and undock (User guide: 4.3)
Draggable dividersuix.HBoxFlex (Function reference: 2.3)
 uix.VBoxFlex (Function reference: 2.4)
 uix.GridFlex (Function reference: 3.2)

E

Emptyuix.Empty (Function reference: 4.1)
Examples(Examples)

F

Flexible layoutuix.HBoxFlex (Function reference: 2.3)
 uix.VBoxFlex (Function reference: 2.4)
FolderlayoutRoot (Function reference: 4.3)
Function reference(Function reference)

G

Getting Started(Getting Started)
Griduix.Grid (Function reference: 3.1)
GridFlexuix.GridFlex (Function reference: 3.2)
GridsGrids (Function reference: 3)
GUIDEUsing layouts inside GUIDE GUIs (User guide: 5)

H

HBoxuix.HBox (Function reference: 2.1)
HBoxFlexuix.HBoxFlex (Function reference: 2.3)
HButtonBoxuix.HButtonBox (Function reference: 2.5)
HelpSupport (Getting Started: 5)
Horizontal button layoutuix.HButtonBox (Function reference: 2.5)
Horizontal layoutuix.HBox (Function reference: 2.1)
 uix.HBoxFlex (Function reference: 2.3)

I

InstallationInstallation (Getting Started: 4)
Installation folderlayoutRoot (Function reference: 4.3)

L

Layout basicsLayout basics (User guide: 1.1)
Layout hierarchiesLayout hierarchies (User guide: 1.4)
layoutRootlayoutRoot (Function reference: 4.3)

M

MATLAB CompilerDeploying GUIs using the MATLAB Compiler (User guide: 6)
Minimize and maximizeMinimize and maximize (User guide: 4.2)
Minimum sizesSizes and units (User guide: 1.3.1)

O

onListSelectiononListSelection (User guide: 7.4)
Other functionsOther functions (Function reference: 4)

P

Paneluix.Panel (Function reference: 1.1)
PanelsPanels (Function reference: 1)
Position vs OuterPositionPosition vs OuterPosition (User guide: 2.1)
Positioning axesPositioning axes (User guide: 2)

R

Release notesRelease notes (Getting Started: 3)
RootlayoutRoot (Function reference: 4.3)
Running itRunning it (User guide: 7.5)

S

ScalabilityScalability (User guide: 7.6)
ScrollingPaneluix.ScrollingPanel (Function reference: 1.5)
Sizes and unitsSizes and units (User guide: 1.3)
SupportSupport (Getting Started: 5)

T

TabPaneluix.TabPanel (Function reference: 1.4)
Trackinguix.tracking (Function reference: 4.2)
Types of layoutTypes of layout (User guide: 1.2)

U

uix.BoxPaneluix.BoxPanel (Function reference: 1.3)
uix.CardPaneluix.CardPanel (Function reference: 1.2)
uix.Emptyuix.Empty (Function reference: 4.1)
uix.Griduix.Grid (Function reference: 3.1)
uix.GridFlexuix.GridFlex (Function reference: 3.2)
uix.HBoxuix.HBox (Function reference: 2.1)
uix.HBoxFlexuix.HBoxFlex (Function reference: 2.3)
uix.HButtonBoxuix.HButtonBox (Function reference: 2.5)
uix.Paneluix.Panel (Function reference: 1.1)
uix.ScrollingPaneluix.ScrollingPanel (Function reference: 1.5)
uix.TabPaneluix.TabPanel (Function reference: 1.4)
uix.trackinguix.tracking (Function reference: 4.2)
uix.VBoxuix.VBox (Function reference: 2.2)
uix.VBoxFlexuix.VBoxFlex (Function reference: 2.4)
uix.VButtonBoxuix.VButtonBox (Function reference: 2.6)
Understanding layoutsUnderstanding layouts (User guide: 1)
UndockDock and undock (User guide: 4.3)
UninstallInstallation (Getting Started: 4)
updateInterfaceupdateInterface (User guide: 7.3)
User guide(User guide)
Using layouts inside GUIDE GUIsUsing layouts inside GUIDE GUIs (User guide: 5)

V

VBoxuix.VBox (Function reference: 2.2)
VBoxFlexuix.VBoxFlex (Function reference: 2.4)
VButtonBoxuix.VButtonBox (Function reference: 2.6)
Vertical button layoutuix.VButtonBox (Function reference: 2.6)
Vertical layoutuix.VBox (Function reference: 2.2)
 uix.VBoxFlex (Function reference: 2.4)
Visible exampleVisible example (User guide: 3.1)

W

What is GUI Layout Toolbox?What is GUI Layout Toolbox? (Getting Started: 1)
Why use layouts?Why use layouts? (User guide: 1.5)
+
+ + +
+ Back to Top +
+ © 2017 The MathWorks Inc + Terms of Use + Patents + Trademarks + + diff --git a/Required packages/layoutdoc/compatibility.html b/Required packages/layoutdoc/compatibility.html new file mode 100644 index 0000000..0fe0c87 --- /dev/null +++ b/Required packages/layoutdoc/compatibility.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/demoBrowserCreateInterface.html b/Required packages/layoutdoc/demoBrowserCreateInterface.html new file mode 100644 index 0000000..7bc8845 --- /dev/null +++ b/Required packages/layoutdoc/demoBrowserCreateInterface.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/demoBrowserOnListSelection.html b/Required packages/layoutdoc/demoBrowserOnListSelection.html new file mode 100644 index 0000000..e6265e1 --- /dev/null +++ b/Required packages/layoutdoc/demoBrowserOnListSelection.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/demoBrowserRun.html b/Required packages/layoutdoc/demoBrowserRun.html new file mode 100644 index 0000000..e9a4123 --- /dev/null +++ b/Required packages/layoutdoc/demoBrowserRun.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/demoBrowserScalability.html b/Required packages/layoutdoc/demoBrowserScalability.html new file mode 100644 index 0000000..b57635e --- /dev/null +++ b/Required packages/layoutdoc/demoBrowserScalability.html @@ -0,0 +1 @@ + diff --git a/Required packages/layoutdoc/demoBrowserStructure.html b/Required packages/layoutdoc/demoBrowserStructure.html new file mode 100644 index 0000000..68795c1 --- /dev/null +++ b/Required packages/layoutdoc/demoBrowserStructure.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/demoBrowserUpdateInterface.html b/Required packages/layoutdoc/demoBrowserUpdateInterface.html new file mode 100644 index 0000000..6352d0b --- /dev/null +++ b/Required packages/layoutdoc/demoBrowserUpdateInterface.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/doc.css b/Required packages/layoutdoc/doc.css new file mode 100644 index 0000000..517d48c --- /dev/null +++ b/Required packages/layoutdoc/doc.css @@ -0,0 +1,95 @@ + H4 { color: rgb(153,0,0); + font-family: Arial,Helvetica,sans-serif; + font-weight: bold; + font-size: smallnormal; + } + + H3 { color: rgb(153,0,0); + font-family: Arial,Helvetica,sans-serif; + font-weight: bold; + font-size: large; + } + + H2 { color: rgb(153,0,0); + font-weight: bold; + font-size: x-large; + font-family: Arial,Helvetica,sans-serif; + } + + H1 { color: rgb(10,0,0); + font-weight: bold; + font-size: xx-large; + font-family: Arial,Helvetica,sans-serif; + } + + P { font-weight: normal; + font-style: normal; + color: rgb(0, 0, 32); + font-family: Arial,Helvetica,sans-serif; + text-decoration: none; + } + + LI { font-weight: normal; + font-style: normal; + color: rgb(0, 0, 32); + font-family: Arial,Helvetica,sans-serif; + text-decoration: none; + } + + A { font-weight: normal; + font-style: normal; + color: rgb(0,0,180, 0, 0); + font-family: Arial,Helvetica,sans-serif; + text-decoration: none; + } + + CODE { font-family: Courier New,Courier,monospace; + color: #000044; + font-size: -1; + } +CODE.FUNCTION { + color: #0000EE; + font-weight: bold; +} +CODE.INARG { + color: #008800; + font-weight: bold; +} +CODE.OUTARG { + color: #880000; + font-weight: bold; + } +CODE.COMMENT { + color: #008800; +} +CODE.STRING { + color: #DD00FF; +} + +TABLE.PROPERTYTABLE { + border-width: 3; + border-style: inset; + border-color: #777777; + cellpadding: 4; + cellspacing: 0; +} +TH.PROPERTYTABLE { + font-weight: bold; + color: #000000; + border-width: 2; + border-style: inset; + background-color: #b2b2b2; +} +TD.PROPERTYTABLE { + font-weight: normal; + color: #000000; + border-width: 2; + border-style: inset; + background-color: #f2f2f2; +} + +PRE { font-family: Courier New,Courier,monospace; + color: #000044; + font-size: -1; +} + diff --git a/Required packages/layoutdoc/frames.html b/Required packages/layoutdoc/frames.html new file mode 100644 index 0000000..29b1510 --- /dev/null +++ b/Required packages/layoutdoc/frames.html @@ -0,0 +1,12 @@ + + + + GUI Layout Documentation + + + + + + + + diff --git a/Required packages/layoutdoc/helpindex.xml b/Required packages/layoutdoc/helpindex.xml new file mode 100644 index 0000000..bb73df0 --- /dev/null +++ b/Required packages/layoutdoc/helpindex.xml @@ -0,0 +1,118 @@ + + + + +A complete example +About +Acknowledgements +Advanced maneuvers with panels +Application design +Application structure +axes +Axes inside layouts +Box + uix.HBox (Function reference: 2.1) + uix.VBox (Function reference: 2.2) + uix.HBoxFlex (Function reference: 2.3) + uix.VBoxFlex (Function reference: 2.4) + +Boxes +BoxPanel +Button box + uix.HButtonBox (Function reference: 2.5) + uix.VButtonBox (Function reference: 2.6) + +Callbacks +CardPanel +Colorbars and legends +Compatibility considerations +Compiler +Context help +Controlling visibility +createInterface +Deploying GUIs using the MATLAB Compiler +Dock and undock +Draggable dividers + uix.HBoxFlex (Function reference: 2.3) + uix.VBoxFlex (Function reference: 2.4) + uix.GridFlex (Function reference: 3.2) + +Empty +Examples +Flexible layout + uix.HBoxFlex (Function reference: 2.3) + uix.VBoxFlex (Function reference: 2.4) + +Folder +Function reference +Getting Started +Grid +GridFlex +Grids +GUIDE +HBox +HBoxFlex +HButtonBox +Help +Horizontal button layout +Horizontal layout + uix.HBox (Function reference: 2.1) + uix.HBoxFlex (Function reference: 2.3) + +Installation +Installation folder +Layout basics +Layout hierarchies +layoutRoot +MATLAB Compiler +Minimize and maximize +Minimum sizes +onListSelection +Other functions +Panel +Panels +Position vs OuterPosition +Positioning axes +Release notes +Root +Running it +Scalability +ScrollingPanel +Sizes and units +Support +TabPanel +Tracking +Types of layout +uix.BoxPanel +uix.CardPanel +uix.Empty +uix.Grid +uix.GridFlex +uix.HBox +uix.HBoxFlex +uix.HButtonBox +uix.Panel +uix.ScrollingPanel +uix.TabPanel +uix.tracking +uix.VBox +uix.VBoxFlex +uix.VButtonBox +Understanding layouts +Undock +Uninstall +updateInterface +User guide +Using layouts inside GUIDE GUIs +VBox +VBoxFlex +VButtonBox +Vertical button layout +Vertical layout + uix.VBox (Function reference: 2.2) + uix.VBoxFlex (Function reference: 2.4) + +Visible example +What is GUI Layout Toolbox? +Why use layouts? + diff --git a/Required packages/layoutdoc/helpsearch-v3/_0.cfe b/Required packages/layoutdoc/helpsearch-v3/_0.cfe new file mode 100644 index 0000000..b0d78a1 Binary files /dev/null and b/Required packages/layoutdoc/helpsearch-v3/_0.cfe differ diff --git a/Required packages/layoutdoc/helpsearch-v3/_0.cfs b/Required packages/layoutdoc/helpsearch-v3/_0.cfs new file mode 100644 index 0000000..9c7c92d Binary files /dev/null and b/Required packages/layoutdoc/helpsearch-v3/_0.cfs differ diff --git a/Required packages/layoutdoc/helpsearch-v3/_0.si b/Required packages/layoutdoc/helpsearch-v3/_0.si new file mode 100644 index 0000000..ada183a Binary files /dev/null and b/Required packages/layoutdoc/helpsearch-v3/_0.si differ diff --git a/Required packages/layoutdoc/helpsearch-v3/segments.gen b/Required packages/layoutdoc/helpsearch-v3/segments.gen new file mode 100644 index 0000000..63a7ec9 Binary files /dev/null and b/Required packages/layoutdoc/helpsearch-v3/segments.gen differ diff --git a/Required packages/layoutdoc/helpsearch-v3/segments_1 b/Required packages/layoutdoc/helpsearch-v3/segments_1 new file mode 100644 index 0000000..da81286 Binary files /dev/null and b/Required packages/layoutdoc/helpsearch-v3/segments_1 differ diff --git a/Required packages/layoutdoc/helptoc.html b/Required packages/layoutdoc/helptoc.html new file mode 100644 index 0000000..09c44f4 --- /dev/null +++ b/Required packages/layoutdoc/helptoc.html @@ -0,0 +1,37 @@ + + + + Table of Contents + + + + +  GUI Layout

+ +  
 Getting Started
+      1. What is GUI Layout Toolbox?
+      2. Compatibility considerations
+      3. Release notes
+      4. Installation
+      5. Support
+      6. Acknowledgements
+
+ +   Examples
+
+ +   User guide
+      1. Understanding layouts
+      2. Positioning axes
+      3. Controlling visibility
+      4. Advanced maneuvers with panels
+      5. Using layouts inside GUIDE GUIs
+      6. Deploying GUIs using the MATLAB Compiler
+      7. A complete example
+
+ +   Function reference
+
+   Index + + diff --git a/Required packages/layoutdoc/helptoc.xml b/Required packages/layoutdoc/helptoc.xml new file mode 100644 index 0000000..09e8009 --- /dev/null +++ b/Required packages/layoutdoc/helptoc.xml @@ -0,0 +1,12 @@ + + + + + GUI Layout + Getting Started1. What is GUI Layout Toolbox?2. Compatibility considerations3. Release notes4. Installation5. Support6. Acknowledgements + Examples + User guide1. Understanding layouts1.1. Layout basics1.2. Types of layout1.3. Sizes and units1.4. Layout hierarchies1.5. Why use layouts?2. Positioning axes2.1. Position vs OuterPosition2.2. Axes inside layouts2.3. Colorbars and legends3. Controlling visibility3.1. Visible example4. Advanced maneuvers with panels4.1. Context help4.2. Minimize and maximize4.3. Dock and undock5. Using layouts inside GUIDE GUIs6. Deploying GUIs using the MATLAB Compiler7. A complete example7.1. Application structure7.2. createInterface7.3. updateInterface7.4. onListSelection7.5. Running it7.6. Scalability + Function reference1. Panels1.1. uix.Panel1.2. uix.CardPanel1.3. uix.BoxPanel1.4. uix.TabPanel1.5. uix.ScrollingPanel2. Boxes2.1. uix.HBox2.2. uix.VBox2.3. uix.HBoxFlex2.4. uix.VBoxFlex2.5. uix.HButtonBox2.6. uix.VButtonBox3. Grids3.1. uix.Grid3.2. uix.GridFlex4. Other functions4.1. uix.Empty4.2. uix.tracking4.3. layoutRoot + Index + + diff --git a/Required packages/layoutdoc/index.html b/Required packages/layoutdoc/index.html new file mode 100644 index 0000000..a2d5f6b --- /dev/null +++ b/Required packages/layoutdoc/index.html @@ -0,0 +1,59 @@ + + + + GUI Layout Toolbox documentation + + + + + + + +
+ GUI Layout Toolbox Documentation +
+
+

GUI Layout Toolbox documentation

+ Version: 2.3.1 +

+ GUI Layout Toolbox is a layout manager for creating MATLAB graphical user + interfaces that resize gracefully. The classes supplied can be used in + combination to produce virtually any user interface layout. +

+ +
    +
  • Arrange MATLAB user interface components horizontally, vertically or in grids
  • +
  • Mix fixed- and variable-size components
  • +
  • Resize components interactively by dragging dividers
  • +
  • Show and hide components using tabs and panels
  • +
  • Show part of a large component in a scrollable panel
  • +
+ +

+ This toolbox was developed by + David Sampson and + Ben Tordoff from the + Consulting Services group + at MathWorks. +

+

+
+

Contents:

+ + + + + + + +
Getting Started: Introductory notes and installation instructions
Examples: A list of the examples that are provided in the documentation
User guide: Describes how to use these tools
Function reference: A list of the available functions
IndexAlphabetical index of sections, functions and concepts
+
+
+ +
+

© 2017 The MathWorks Ltd + Terms of Use + Patents + Trademarks

+ + diff --git a/Required packages/layoutdoc/info.xml b/Required packages/layoutdoc/info.xml new file mode 100644 index 0000000..ef78de7 --- /dev/null +++ b/Required packages/layoutdoc/info.xml @@ -0,0 +1,11 @@ + + + + +14 +GUI Layout +toolbox +$toolbox/matlab/icons/bookicon.gif +../layoutdoc + + diff --git a/Required packages/layoutdoc/layoutDocRoot.m b/Required packages/layoutdoc/layoutDocRoot.m new file mode 100644 index 0000000..3783077 --- /dev/null +++ b/Required packages/layoutdoc/layoutDocRoot.m @@ -0,0 +1,12 @@ +function folder = layoutDocRoot() +%layoutDocRoot Return the location of the GUI Layout Toolbox documentation. +% +% folder = layoutDocRoot() +% +% See also: layoutRoot + +% Copyright 2014 The MathWorks, Inc. + +folder = fileparts( mfilename( 'fullpath' ) ); + +end % layoutDocRoot \ No newline at end of file diff --git a/Required packages/layoutdoc/layoutRoot.html b/Required packages/layoutdoc/layoutRoot.html new file mode 100644 index 0000000..3b3d363 --- /dev/null +++ b/Required packages/layoutdoc/layoutRoot.html @@ -0,0 +1 @@ + diff --git a/Required packages/layoutdoc/releasenotes.html b/Required packages/layoutdoc/releasenotes.html new file mode 100644 index 0000000..80d6140 --- /dev/null +++ b/Required packages/layoutdoc/releasenotes.html @@ -0,0 +1 @@ + diff --git a/Required packages/layoutdoc/termsOfUse.m b/Required packages/layoutdoc/termsOfUse.m new file mode 100644 index 0000000..820982c --- /dev/null +++ b/Required packages/layoutdoc/termsOfUse.m @@ -0,0 +1,8 @@ +function termsOfUse + if verLessThan('matlab','8.5') + helpview([matlabroot,'/license.txt']) + else + helpview([matlabroot,'/license_agreement.txt']) + end +end + diff --git a/Required packages/layoutdoc/uix.BoxPanel.html b/Required packages/layoutdoc/uix.BoxPanel.html new file mode 100644 index 0000000..a39930d --- /dev/null +++ b/Required packages/layoutdoc/uix.BoxPanel.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.CardPanel.html b/Required packages/layoutdoc/uix.CardPanel.html new file mode 100644 index 0000000..9c80a84 --- /dev/null +++ b/Required packages/layoutdoc/uix.CardPanel.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.Empty.html b/Required packages/layoutdoc/uix.Empty.html new file mode 100644 index 0000000..92d90de --- /dev/null +++ b/Required packages/layoutdoc/uix.Empty.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.Grid.html b/Required packages/layoutdoc/uix.Grid.html new file mode 100644 index 0000000..42132a0 --- /dev/null +++ b/Required packages/layoutdoc/uix.Grid.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.GridFlex.html b/Required packages/layoutdoc/uix.GridFlex.html new file mode 100644 index 0000000..1a9fd48 --- /dev/null +++ b/Required packages/layoutdoc/uix.GridFlex.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.HBox.html b/Required packages/layoutdoc/uix.HBox.html new file mode 100644 index 0000000..85a41d2 --- /dev/null +++ b/Required packages/layoutdoc/uix.HBox.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.HBoxFlex.html b/Required packages/layoutdoc/uix.HBoxFlex.html new file mode 100644 index 0000000..acb94b2 --- /dev/null +++ b/Required packages/layoutdoc/uix.HBoxFlex.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.HButtonBox.html b/Required packages/layoutdoc/uix.HButtonBox.html new file mode 100644 index 0000000..289886a --- /dev/null +++ b/Required packages/layoutdoc/uix.HButtonBox.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.Panel.html b/Required packages/layoutdoc/uix.Panel.html new file mode 100644 index 0000000..0d6630f --- /dev/null +++ b/Required packages/layoutdoc/uix.Panel.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.ScrollingPanel.html b/Required packages/layoutdoc/uix.ScrollingPanel.html new file mode 100644 index 0000000..749d952 --- /dev/null +++ b/Required packages/layoutdoc/uix.ScrollingPanel.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.TabPanel.html b/Required packages/layoutdoc/uix.TabPanel.html new file mode 100644 index 0000000..877e037 --- /dev/null +++ b/Required packages/layoutdoc/uix.TabPanel.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.VBox.html b/Required packages/layoutdoc/uix.VBox.html new file mode 100644 index 0000000..94453eb --- /dev/null +++ b/Required packages/layoutdoc/uix.VBox.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.VBoxFlex.html b/Required packages/layoutdoc/uix.VBoxFlex.html new file mode 100644 index 0000000..e0cd4fa --- /dev/null +++ b/Required packages/layoutdoc/uix.VBoxFlex.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.VButtonBox.html b/Required packages/layoutdoc/uix.VButtonBox.html new file mode 100644 index 0000000..35baa00 --- /dev/null +++ b/Required packages/layoutdoc/uix.VButtonBox.html @@ -0,0 +1 @@ + > diff --git a/Required packages/layoutdoc/uix.tracking.html b/Required packages/layoutdoc/uix.tracking.html new file mode 100644 index 0000000..9321b2f --- /dev/null +++ b/Required packages/layoutdoc/uix.tracking.html @@ -0,0 +1 @@ + > diff --git a/Required packages/license.txt b/Required packages/license.txt new file mode 100644 index 0000000..4e88af6 --- /dev/null +++ b/Required packages/license.txt @@ -0,0 +1,27 @@ +Copyright (c) 2017, The MathWorks, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * In all cases, the software is, and all modifications and derivatives + of the software shall be, licensed to you solely for use in conjunction + with MathWorks products and service offerings. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE.