% 1. This layout manager is based on MATLAB Central File Exchange entry "Resizable
% MATLAB figures" by Malcolm Wood.
%
% 2. All properties can be accesed either directly like obj.Prop=x or using
% get/set which is set(obj, 'Prop', x).
%
% 3. All resizable objects except RE_Layout are derived from RE_Box. Therefore
% all RE_Box properties are avalable in the derived classes.
%
% 4. On win classic/xp popup height is 21 pixels. Therefore it makes sense to
% set edit fields to this height. Further it makes sense to set buttons to 23
% pixels so that when all elements are displayed in a row they are optically
% alligned. But uicontrol text elements set to this height appear some 4 pixels
% too high. Therefore there exists a RE_Box property HPopup which is set by
% default to 21. When a row box is defined and has a height of HPopup then all
% its uicontrols are perfectly alligned (on windows) with buttons being set to 23
% pixels and uicontrol:text string being alligned to uicontrol:edifield string
%
% 5. The most important property of RE_Box is 'Element'. It is either cell
% matrix or double matrix (of handles). In most cases it is just a vector. If of
% type cell it can contain either:
% i. other RE_Box objects
% ii. empty array - just a spacer
% iii. uicontrol handle
% iv. javax.swing element (!)
%
%++++
% Resizable figure object is the main object and must be called first, all other
% objects are created with its factory methods. To get figure handle query
% Handle property
%
% layoutFigObj = RE_Layout( varargin )
%
% varargin : matlab's figure properties
%++++
% Box object (RE_Box) containing matrix of sub-boxes given by property Element.
% Length of properties Width and Height must match the size of Element. Negative
% Width/Height means that all available space in will be filled
%
% boxObj = layoutFigObj.box( Element, varargin )
%
% Element : (cell)array of handles/resizable elements (also see varargin)
% varargin : properties (with default value)
% Position = []; % box position
% Handle = []; % double array of handles, subset of Element (next property)
% Element = {[]}; % elements matrix HxW (Height x Width)
% Width = -1; % vector Wx1 (or 1xW)
% Height = -1; % vector Hx1 (or 1xH)
% Padding = [0, 0, 0, 0]; % relative to border [left bottom right top]
% Spacing = [0, 0]; % between elements [horizontal, vertical]
% Extent = [-1, -1]; % like uicontrol extent property [horizontal, vertical]
% Children = []; % double array of all handles of box and its subboxes
% HPopup = 21; % popup height on win classic/xp, internally used to allign text labels
%++++
% Shorthand for box object containing elements in a single row/column, other
% dimension is set to -1 (fill all avalable space) by default
%
% boxObj = layoutFigObj.hbox( Element, Width, varargin )
% boxObj = layoutFigObj.vbox( Element, Height, varargin )
%
%++++
% Panel similar to uipanel but with blue bold title (not possible with uipanel),
% derived from RE_Box
%
% panelObj = layoutFigObj.panel( Pane, varargin )
%
% Pane : see varargin
% varargin : properties (with default value)
% Title = ''; % panel title
% Pane = []; % box contained in the panel
%++++
% Tabbed pane. Use method add() to set layout boxes and tab names, derived from
% RE_Box
%
% tabpaneObj = layoutFigObj.tabpane( varargin )
% tabpaneObj.add( 'name1', boxObj1, 'name2', boxObj2, ... );
%
% varargin : properties (with default value)
% Value = 1; % displayed tab
% TabpaneFcn = []; % callback tab is being switched
%++++
% Separator with blue bold title, derived from RE_Box
%
% separatorObj = layoutFigObj.separator( varargin )
%
% varargin : properties (with default value)
% Title = ''; % separator title
%++++
% Resizable Axis. Use Handle property to get its matlab axes ui object
%
% axisObj = layoutFigObj.axis( varargin )
%
% varargin : properties, see RE_Box
%
%++++
% Radio/Checkboxes group, derived from RE_Box. For radiobutton the selection is
% exclusive, i.e. only one element can be selected each time
%
% groupObj = layoutFigObj.radio( varargin )
% groupObj = layoutFigObj.check( varargin )
%
% varargin : properties (with default value)
% ValueFcn = []; % callback
% Value = 1; % selected element
% String = {'<default>'}; % displayed names
%
function resize_example
% figure
ly = RE_Layout('Name', 'Layout Manager');
% uicontrols
h0 = uicontrol('style', 'check', 'string', 'Select file:', 'hori', 'left');
h1 = uicontrol('style', 'edit', 'back', 'white', 'string', 'None', 'hori', 'left');
h2 = uicontrol('string', 'Browse ...');
h3 = uicontrol('style', 'text', 'string', 'Project Name:', 'hori', 'left');
h4 = uicontrol('style', 'popup', 'back', 'white', 'string', 'None');
h6 = uicontrol('style', 'list', 'back', 'white');
h7 = uicontrol('string', 'Apply');
h8 = uicontrol('string', 'OK');
h9 = uicontrol('string', 'Cancel');
% complex elements
ax1 = ly.axis('Padding', 20);
rd1 = ly.radio('String', {'radio1', 'radio2', 'radio3', 'radio4'}, 'Value', 4, 'ValueFcn', @ValueFcn);
ck1 = ly.check('String', {'check1', 'check2', 'check3'}, 'Value', [1,2], 'ValueFcn', @ValueFcn);
sp1 = ly.separator('Title', 'Data', 'Padding', [-10, 0, 0, 0]);
% top panels
bx1 = ly.hbox({h0, h1, h2}, [70, -1, 75], 'Spacing', 6);
bx2 = ly.hbox({h3, h4}, [70, -1], 'Spacing', 6);
% uipanel
bx12 = ly.vbox({bx1, bx2}, [21, 21], 'Spacing', 6, 'Padding', 20);
pn1 = ly.panel(bx12, 'Title', 'Elements');
% radio+check
bx3 = ly.hbox({rd1, ck1}, [-1, -1], 'Height', rd1.Extent(2));
% radio+list
bx4 = ly.vbox({bx3, h6}, [bx3.Extent(2), -1], 'Spacing', 15, 'Padding', 15);
% radio+list+axis
tp1 = ly.tabpane( 'TabpaneFcn', @ValueFcn, 'Padding', 10, 'Value', 2 );
tp1.add('Tab1', ax1, 'Tab2', bx4);
% footer buttons
bx8 = ly.hbox({h7, [], h8, h9}, [70, -1, 75, 75], 'Spacing', 6);
% figure root
ly.vbox({pn1, sp1, tp1, bx8}, [pn1.Extent(2), 16, -1, 21], 'Spacing', 8, 'Padding', [20, 10, 10, 20]);
ly.show([800, 600]);
function ValueFcn(hObj, evt)
disp(evt);