classdef Panel < uiextras.CardPanel & uiextras.DecoratedPanel %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-2010 The MathWorks, Inc. % $Revision: 373 $ % $Date: 2011-07-14 13:24:10 +0100 (Thu, 14 Jul 2011) $ properties( Dependent = true ) BorderType % Type of border around the uipanel area [none|etchedin|etchedout|beveledin|beveledout|line] BorderWidth % Width of the panel border Title % Title string TitlePosition % Location of title string in relation to the panel [lefttop|centertop|righttop|leftbottom|centerbottom|rightbottom] end % dependent properties methods function obj = Panel( varargin ) %PANEL constructor % First step is to create the parent class. We pass the % arguments (if any) just incase the parent needs setting obj = obj@uiextras.CardPanel( varargin{:} ); obj = obj@uiextras.DecoratedPanel( varargin{:} ); set( obj.UIContainer, 'Title', '' ); % Override base settings obj.BorderType = 'etchedin'; obj.BorderWidth = 1; obj.TitlePosition = 'lefttop'; % See if the user has set any defaults obj.setPropertyFromDefault( 'BorderType' ); obj.setPropertyFromDefault( 'BorderWidth' ); obj.setPropertyFromDefault( 'TitlePosition' ); % Set user-supplied property values if nargin > 0 set( obj, varargin{:} ); end end % Panel end % public methods methods function value = get.BorderType( obj ) value = get( obj.UIContainer, 'BorderType' ); end % get.BorderType function set.BorderType( obj, value ) set( obj.UIContainer, 'BorderType', value ); end % set.BorderType function value = get.BorderWidth( obj ) value = get( obj.UIContainer, 'BorderWidth' ); end % get.BorderWidth function set.BorderWidth( obj, value ) set( obj.UIContainer, 'BorderWidth', value ); obj.redraw(); end % set.BorderWidth function value = get.Title( obj ) value = get( obj.UIContainer, 'Title' ); end % get.Title function set.Title( obj, value ) % Only need to redraw if changing to/from empty oldValue = get( obj.UIContainer, 'Title' ); % Unfortunately setting the title creates a uicontrol that % isn't tagged, so we have to set a flag so that we know to % ignore it for resize purposes setappdata( obj.UIContainer, 'PanelTitleCreate', true ); set( obj.UIContainer, 'Title', value ); rmappdata( obj.UIContainer, 'PanelTitleCreate' ); if isempty( value ) && ~isempty( oldValue ) obj.redraw(); elseif isempty( oldValue ) && ~isempty( value ) obj.redraw(); end end % set.Title function value = get.TitlePosition( obj ) value = get( obj.UIContainer, 'TitlePosition' ); end % get.TitlePosition function set.TitlePosition( obj, value ) set( obj.UIContainer, 'TitlePosition', value ); obj.redraw(); end % set.TitlePosition end % accessor methods methods( Access = protected ) function redraw( obj ) %redraw Redraw the layout, positioning the children if isempty( obj.UIContainer ) || ~ishandle( obj.UIContainer ) return end % The selected one inherits the visibility of the layout and % fills the available space oldUnits = obj.Units; obj.Units = 'Pixels'; pos = getpixelposition( obj ); border = obj.BorderWidth+1+obj.Padding; x0 = border; y0 = border; w = pos(3) - 2*border; h = pos(4) - 2*border; if ~isempty( obj.Title ) % Work out how much extra space to leave for the title oldFontUnits = get( obj.UIContainer, 'FontUnits' ); set( obj.UIContainer, 'FontUnits', 'Pixels' ); % Get the height of the title (in pixels) titleSize = get( obj.UIContainer, 'FontSize' ); % Put the old units back set( obj.UIContainer, 'FontUnits', oldFontUnits ); % Whether to move top or bottom depends on title % position if isempty( strfind( get( obj.UIContainer, 'TitlePosition' ), 'top' ) ) % Title at the bottom h = h - titleSize; y0 = y0 + titleSize; else % Title at the top h = h - titleSize; end end % Use the CardLayout function to put the right child onscreen obj.showSelectedChild( [x0 y0 w h] ); obj.Units = oldUnits; end % redraw function onChildAdded( obj, source, eventData ) %#ok %onChildAdded: Callback that fires when a child is added to a container. % Select the new addition obj.SelectedChild = numel( obj.Children ); end % onChildAdded function onChildRemoved( obj, source, eventData ) %#ok %onChildAdded: Callback that fires when a container child is destroyed or reparented. % If the missing child is the selected one, select something else if eventData.ChildIndex == obj.SelectedChild if isempty( obj.Children ) obj.SelectedChild = []; else obj.SelectedChild = max( 1, obj.SelectedChild - 1 ); end end end % onChildRemoved function onEnable( obj, source, eventData ) %#ok %onEnable Callback that fires when the enable state is changed t = findall( obj.UIContainer, ... 'Type', 'uicontrol', ... 'HandleVisibility', 'off', ... 'Parent', obj.UIContainer ); set( t, 'Enable', obj.Enable ); end % onChildRemoved function onBackgroundColorChanged( obj, source, eventData ) %#ok %onBackgroundColorChanged Callback that fires when the container background color is changed % % We need to make the panel match the container background set( obj.UIContainer, 'BackgroundColor', eventData ); end % onChildRemoved function onPanelColorChanged( obj, source, eventData ) %#ok % Colors have changed. This shouldn't require a redraw. set( obj.UIContainer, eventData.Property, eventData.Value ); end % onPanelColorChanged function onPanelFontChanged( obj, source, eventData ) %#ok % Font has changed. Since the font size and shape affects the % space available for the contents, we need to redraw. set( obj.UIContainer, eventData.Property, eventData.Value ); obj.redraw(); end % onPanelFontChanged end % protected methods end % classdef