No BSD License  

Highlights from
Yet Another Layout Manager

  • resize_example 1. This layout manager is based on MATLAB Central File Exchange entry "Resizable
  • RE_Axis custom axis
  • RE_Box elementary layout building block, positions matrix of elements
  • RE_Button checkboxes/radiobuttons/togglebuttons column
  • RE_Layout Class which defines figure and has many factory methods for ui components
  • RE_Panel custom axis
  • RE_Separator separator with or without label
  • RE_Tabpane tab pane implementation using java element
  • View all files
image thumbnail
from Yet Another Layout Manager by amilcar chaudhary
Easily align gui elements and quickly build resizable gui

RE_Box
%% elementary layout building block, positions matrix of elements
classdef RE_Box < hgsetget

    properties
        Position = [];          % box position
        Handle = [];            % array of handles
        Element = {[]};         % elements matrix HxW
        Width = -1;             % vector Wx1
        Height = -1;            % vector Hx1
        Padding = [0, 0, 0, 0]; % [left bottom right top]
        Spacing = [0, 0];       % [horizontal, vertical]
        HPopup = 21;            % popup height on win classic/xp
    end
    
    properties (Dependent = true)
        Children;
        Extent;
    end

    methods

        % CONSTRUCTOR
        function obj = RE_Box(element)
            if ~nargin, element = []; end
            set(obj, 'Element', element);
        end

        function obj = set.Element(obj, element)
            
            if iscell(element)
                ind = cellfun(@(x) isnumeric(x) && ~isempty(x), element(:));
                hcell = element(ind);
                harray = [hcell{:}];
            elseif isnumeric(element)
                harray = element;
            end
            
            obj.Handle = harray(:);
            obj.Element = element;            
        end

        function obj = set.Padding(obj, padding)
            N = length(padding);
            if N == 1, padding = padding(ones(1,4));
            elseif N == 2, padding = padding([1,2,1,2]); end
            obj.Padding = padding;
        end

        function obj = set.Spacing(obj, spacing)
            if length(spacing) == 1, spacing = spacing([1,1]); end
            obj.Spacing = spacing;
        end

        function obj = set.Position(obj, position)
            obj.Position = position;
            setPosition(obj);
        end

        function extent = get.Extent(obj)
            extent = getExtent(obj);
        end
        
       function children = get.Children(obj)
         	children = getChildren(obj);
        end        
    end % methods
    
    methods (Access = protected)
        
        %% calculate object extent
        function extent = getExtent(obj)
            extent = [-1, -1];

            if all(obj.Width > 0)
                extent(1) = sum(obj.Width) + sum(obj.Padding([1,3])) + ...
                    obj.Spacing(1)*(length(obj.Width) - 1);
            end

            if all(obj.Height > 0)
                extent(2) = sum(obj.Height) + sum(obj.Padding([2,4])) + ...
                    obj.Spacing(2)*(length(obj.Height) - 1);
            end
        end

        %% recursively get handles off all children controls
        function children = getChildren(obj)

            children = obj.Handle;
            if ~iscell(obj.Element), return; end;

            ind = cellfun(@(x) ~isnumeric(x) && ~isempty(x), obj.Element(:));
            if ~any(ind), return; end

            elements = obj.Element(ind);

            for i = elements(:)'
                children = [children; i{1}.Children];
            end
        end
        
        %% set box position
        function setPosition(obj)

            position = obj.Position;
            
            sw = position(3) - obj.Padding(1) - obj.Padding(3);
            sh = position(4) - obj.Padding(2) - obj.Padding(4);
            rh = position(2) + position(4) - obj.Padding(4);

            s2 = length(obj.Width);
            s1 = length(obj.Height);

            if s2 == 1 && obj.Width > 0, sw = obj.Width; end
            if s1 == 1 && obj.Height > 0, sh = obj.Height; end

            if s2 > 1, sw = local_size(obj.Width, sw - (s2-1)*obj.Spacing(1)); end
            if s1 > 1, sh = local_size(obj.Height, sh - (s1-1)*obj.Spacing(2)); end

            for ih = 1:s1

                rh = rh - sh(ih);
                rw = position(1) + obj.Padding(1);

                for iw = 1:s2

                    if iscell(obj.Element)
                        iElement = obj.Element{ih, iw};
                    else
                        iElement = obj.Element(ih, iw);
                    end

                    if ~isempty(iElement)

                        pos = [rw, rh, sw(iw), sh(ih)];

                        % hack to allign text + editfield + button
                        if isnumeric(iElement) && sh(ih) == obj.HPopup && s2 > 1 && strcmp('uicontrol', get(iElement,'type'))
                            style = get(iElement, 'style');
                            switch style
                                case 'text'
                                    pos(2) = pos(2) - 4;
                                case {'togglebutton', 'pushbutton'}
                                    pos(2) = pos(2) - 1;
                                    pos(4) = pos(4) + 2;
                            end
                        end

                        set(iElement, 'Position', pos);
                    end

                    rw = rw + sw(iw) + obj.Spacing(1);
                end

                rh = rh - obj.Spacing(2);
            end
        end
    end % methods
end % classdef



%% calculate size of box elements
function sz = local_size(given, available)

sz = given;                     % sizes
ip = sz > 0;                    % indices of fixed sizes
fs = sum(sz(ip));               % sum of fixed sizes
rs = max(available - fs, 1);	% rest sizes (sum of dynamic sizes)
ns = sz(~ip);                   % negative (dynamic) sizes
sz(~ip) = ns * (rs/sum(ns));    % re-assign negative sizes (turned positive)

if sum(sz) < available + 3, return; end

sz = sz*available/sum(sz);      % normalize sizes
sz = max(1,abs(sz));            % make sure size is always positive
end

Contact us at files@mathworks.com