[Master Index] [Index for Toolbox]

bst_layout

(Toolbox/bst_layout.m in BrainStorm 2.0 (Alpha))


Function Synopsis

bst_layout(varargin);

Help Text

BST_LAYOUT - Manage all BST windows in a standard layout
 function bst_layout(varargin);
function bst_layout(action,h,trow,tcol,tnum);
 bst_layout with no arguments will "snap" all windows to the proper alignment.
  Field tiles will be shaped to the nearest obvious size.

 bst_layout('align',h) will snap only the given window
 bst_layout('align',h,row,col,num) will snap field tiles in h to
  the desired row and col format, in the num position, using the matlab
  convention established in subplot, for sizes 1x1, 1x2, 2x1, and 2x2.
  If h is empty, then all tile windows will be snapped into that shape.
 Examples:
 bst_layout or bst_layout('align')% clean up all windows in display
 bst_layout('align',figh); % set specific tile or Dynamic Toolbar into place
 bst_layout('align',[],2,2,4); % set all tiles into the lower right position

 OTHER Actions:
 bst_layout('close') closes all field tiles but not other windows
 bst_layout('quit') closes all field tiles and message windows, ending BST
 bst_layout('margins') interactively sets the margins of the BST screen
 bst_layout('full') sets the margins to nearly full screen

 Explanation
  BrainStorm has four "tile" types. 
  The first is the Message Tile, found in the upper right corner.

  Next is the StaticToolbar tile, found in the upper left.
  The Message and StaticToolbar tiles are always present.

  The third tile type is the DynamicToolbar in the lower left,
  which is overlaid with various toolbars as driven by the actions.

  The final tile type are the "field tiles" or just "tiles" that fill
  most of the screen. The field tiles can be arranged 
  as 1x1, 2x1, 1x2, or 2x2.

 The TileType must be written into the figure's appdata using name 'TileType'.
  Valid types are 'Message','Static','Dynamic','Tile' (only first letter
  counts, case sensitive).

Cross-Reference Information

This function is called by

Listing of function C:\BrainStorm_2001\Toolbox\bst_layout.m

function bst_layout(varargin);
%BST_LAYOUT - Manage all BST windows in a standard layout
% function bst_layout(varargin);
%function bst_layout(action,h,trow,tcol,tnum);
% bst_layout with no arguments will "snap" all windows to the proper alignment.
%  Field tiles will be shaped to the nearest obvious size.
%
% bst_layout('align',h) will snap only the given window
% bst_layout('align',h,row,col,num) will snap field tiles in h to
%  the desired row and col format, in the num position, using the matlab
%  convention established in subplot, for sizes 1x1, 1x2, 2x1, and 2x2.
%  If h is empty, then all tile windows will be snapped into that shape.
% Examples:
% bst_layout or bst_layout('align')% clean up all windows in display
% bst_layout('align',figh); % set specific tile or Dynamic Toolbar into place
% bst_layout('align',[],2,2,4); % set all tiles into the lower right position
%
% OTHER Actions:
% bst_layout('close') closes all field tiles but not other windows
% bst_layout('quit') closes all field tiles and message windows, ending BST
% bst_layout('margins') interactively sets the margins of the BST screen
% bst_layout('full') sets the margins to nearly full screen
%
% Explanation
%  BrainStorm has four "tile" types. 
%  The first is the Message Tile, found in the upper right corner.
%
%  Next is the StaticToolbar tile, found in the upper left.
%  The Message and StaticToolbar tiles are always present.
%
%  The third tile type is the DynamicToolbar in the lower left,
%  which is overlaid with various toolbars as driven by the actions.
%
%  The final tile type are the "field tiles" or just "tiles" that fill
%  most of the screen. The field tiles can be arranged 
%  as 1x1, 2x1, 1x2, or 2x2.
%
% The TileType must be written into the figure's appdata using name 'TileType'.
%  Valid types are 'Message','Static','Dynamic','Tile' (only first letter
%  counts, case sensitive).

%<autobegin> ---------------------- 12-Oct-2004 01:11:00 -----------------------
% --------- Automatically Generated Comments Block Using AUTO_COMMENTS ---------
%
% CATEGORY: GUI and Related
%
% Alphabetical list of external functions (non-Matlab):
%   toolbox\bst_layout.m  NOTE: Routine calls itself explicitly
%
% Subfunctions in this file, in order of occurrence in file:
%   ScreenSize = get_screensize;
%   align(hf,trow,tcol,tnum);
%   [winpos,tilepos,allpos] = make_positions(STYLE);
%
% Group : Preference data and their calls in this file:
%   'BrainStorm' : 'Layout'
%   
%   setpref('BrainStorm','Layout',L);
%   setpref('BrainStorm','Layout',Layout);
%   
%   L = getpref('BrainStorm','Layout');
%
% Application data and their calls in this file:
%   'TileType'
%   
%   setappdata(hf(i),'TileType',TileType);
%   
%   TileType = getappdata(hf(i),'TileType');
%
% At Check-in: $Author: Mosher $  $Revision: 24 $  $Date: 10/11/04 11:32p $
%
% This software is part of BrainStorm Toolbox Version 2.0 (Alpha) 23-Sep-2004
% 
% Principal Investigators and Developers:
% ** Richard M. Leahy, PhD, Signal & Image Processing Institute,
%    University of Southern California, Los Angeles, CA
% ** John C. Mosher, PhD, Biophysics Group,
%    Los Alamos National Laboratory, Los Alamos, NM
% ** Sylvain Baillet, PhD, Cognitive Neuroscience & Brain Imaging Laboratory,
%    CNRS, Hopital de la Salpetriere, Paris, France
% 
% See BrainStorm website at http://neuroimage.usc.edu for further information.
% 
% Copyright (c) 2004 BrainStorm by the University of Southern California
% This software distributed  under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPL
% license can be found at http://www.gnu.org/copyleft/gpl.html .
% 
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%<autoend> ------------------------ 12-Oct-2004 01:11:00 -----------------------

% History
% ------------------------------------------------------------
% 13-May-2003 JCM  First build of new layout criterion for BST V2
% 14-May-2003 JCM  Second build moving static and message to the bottom of the window
% 15-May-2003 JCM  Making layout more versatile with its own structure
% 6-Aug-2003  JCM  If the computer screen size changes, the default is reinstated. Added
%                  new field "ScreenSize" to the layout structure
% 11-Nov-2003 JCM  Added new style for static in the upper left
% 29-Sep-2004 EK   Added a new style 'd' for lower left - half size of the dynamic style 
% ------------------------------------------------------------

% look at 'defaults' section for hardwiring

global STYLE_BOTTOM STYLE_TOP

STYLE_BOTTOM = 1; % Our Summer 2003 version, with static on bottom right
STYLE_TOP = 2; % New Fall 2003 version, with static in upper left


STYLE = STYLE_TOP; % hardwire the style version

if(nargin == 0),
    varargin{1} = 'align'; % default action
end

switch varargin{1}
    
case {'default','full'} % same thing
    % set the margins to the full desktop

    % ------------ Hardwiring -------------------

    % ----- define the BrainStorm screen area in the user's desktop --------
    LEFT = .05;
    BOTTOM = .1;
    WIDTH = .94;
    HEIGHT = .89;
    
    % all units are relative to the BrainStorm screen area
    % Message is along left bottom, Static is along right bottom, Dynamic up the right
    MessageWidth = .35; % fraction of screen width
    MessageHeight = .15; % fraction of screen height
        
    DynamicWidth = .2; % fraction of screen margin width;
    DynamicHeight = 1 - MessageHeight; % all available height

    % static is same height, rest of screen across bottom
    StaticHeight = MessageHeight;
    StaticWidth = 1 - MessageWidth;
    
    
    % --------- Hardwire for figure margins --------------
    NameMargin = .032; % adds to the height of a figure
    SideMargin = .0075; % adds to the width
    MenuMargin = .025; % additional height if used
    % see also make_positions below for any possible final tinkering with these values
    

    % -------- end of hardwire, should be automatic below ----------
    
    ScreenSize = get_screensize;

    Layout = struct('ScreenSize',[],... % the 4 param screen size (e.g. [1 1 1024 768]
    'ScreenPosition',[],... % the 4 param location of BST
        'MessageHeight',[],'MessageWidth',[],... % the message window in lower left
        'DynamicHeight',[],'DynamicWidth',[],... % the changing toolbar in upper right
        'StaticHeight',[],'StaticWidth',[],... % lower right
        'SideMargin',[],... % allowance for additional right side space needed
        'NameMargin',[],... % allowance for the Name region at top of windows
        'MenuMargin',[],... % allowance for a file menu at top of window
        'winpos',[],... % calculated by make_positions, true positions
        'tilepos',[],... % calculated by make_positions
        'allpos',[]... % calculated by make_positions
        ); 
    
    Layout.ScreenSize = ScreenSize;
    Layout.ScreenPosition = [LEFT BOTTOM WIDTH HEIGHT];
    Layout.MessageWidth = MessageWidth;
    Layout.MessageHeight = MessageHeight;
    Layout.DynamicWidth = DynamicWidth;
    Layout.DynamicHeight = DynamicHeight;
    Layout.StaticHeight = StaticHeight;
    Layout.StaticWidth = StaticWidth;
    Layout.SideMargin = SideMargin;
    Layout.NameMargin = NameMargin;
    Layout.MenuMargin = MenuMargin;
    
    setpref('BrainStorm','Layout',Layout);
    make_positions(STYLE); % generate new positions from above information, update Layout
    
    bst_layout('align')
    
    
 case {'close','quit','close all'}
    set(0,'ShowHidden','on');
    hf = findobj(0,'type','figure'); % all of the figure handles
    
    for i = 1:length(hf),
       TileType = getappdata(hf(i),'TileType');
       if(~isempty(TileType)),
          TileType = TileType(1); % only care about first letter
          switch TileType
          case 'T' % tiles
             delete(hf(i));
          case {'D'}
             if strcmp(varargin{1},'close all'),
                % closing all dynamic toolbars
                delete(hf(i))
             end
          case {'M','S'}               
             if strcmp(varargin{1},'quit'),
                % closing everything in full shutdown
                delete(hf(i))
             end
          end % switch case
       end % if a BST TileType
    end % for all figures
    
case 'margins'
    % set new margins based on current window setting
    ScreenSize = get_screensize;
    
    if(~ispref('BrainStorm','Layout')),
        bst_layout('default');
    end
    L = getpref('BrainStorm','Layout');
    
    % find the dynamic window
    DynamicPos = get(gcbf,'Position'); % position of calling figure
    
    % find the message window
    set(0,'showhidden','on');
    hm = findobj(0,'Name','Messages');
    MessagePos = get(hm,'position');

    MessageWidth = MessagePos(3) + L.SideMargin;
    MessageHeight = MessagePos(4) + L.NameMargin;
    
    DynamicWidth = DynamicPos(3) + L.SideMargin;
    DynamicHeight = DynamicPos(4) + L.NameMargin;
 
    switch STYLE
    case STYLE_BOTTOM
       
       LEFT = MessagePos(1); % the lower corner of the message window
       BOTTOM = MessagePos(2);
       
       % now use upper right edge of dynamic window for other measurement
       WIDTH = (DynamicPos(1) + DynamicWidth) - LEFT; % the right edge of the dynamic window
       HEIGHT = (DynamicPos(2) + DynamicHeight) - BOTTOM;
       
    case STYLE_TOP
       
       LEFT = DynamicPos(1); % the lower corner of the dynamic window
       BOTTOM = DynamicPos(2);
       
       % use the upper right of the message window
       WIDTH = (MessagePos(1) + MessageWidth) - LEFT; % the right edge of the message window
       HEIGHT = (MessagePos(2) + MessageHeight) - BOTTOM;
       
    end
    
    L.ScreenSize = ScreenSize; % present screen size
    L.ScreenPosition = [LEFT BOTTOM WIDTH HEIGHT];
    
    % now set the size of the message and dynamic windows based on current relative settings
    L.MessageWidth = MessageWidth/WIDTH; % relative width
    L.MessageHeight = MessageHeight/HEIGHT;
    L.StaticHeight = L.MessageHeight; % stays same
    L.StaticWidth = 1 - L.MessageWidth; % rest of space
 
    % dynamic height cannot overlap the static toolbar
    L.DynamicHeight = DynamicHeight/HEIGHT;
    switch STYLE
    case STYLE_BOTTOM
       L.DynamicHeight = min(L.DynamicHeight,(1-L.MessageHeight));
    case STYLE_TOP
       L.DynamicHeight = min(L.DynamicHeight,(1-L.MessageHeight));
    end
    L.DynamicWidth = DynamicWidth/WIDTH;
    
    setpref('BrainStorm','Layout',L);
    make_positions(STYLE); % calculate new positions
    
    bst_layout('align'); % align everything to them
    
    
case {'align','snap'} % same thing
    varargin{1} = 'align'; % same thing either way
    feval(varargin{:});
end





% ------------ screensize in pixels
function ScreenSize = get_screensize;
ScreenUnits = get(0,'units'); % what are the current units
set(0,'units','pixels'); % set to pixels
ScreenSize = get(0,'ScreenSize'); % what is the existing screen size (1x4 vec)
set(0,'units',ScreenUnits); % return to original units




% ----------- align (snap) ------------------
function align(hf,trow,tcol,tnum);

if(~ispref('BrainStorm','Layout')),
    bst_layout('default'); % make it
end

L = getpref('BrainStorm','Layout');

ScreenSize = get_screensize;

% double check that L.ScreenSize exists
if(~isfield(L,'ScreenSize')), % it's missing
    bst_layout('default'); % make new structure
end

if(~all(ScreenSize == L.ScreenSize)), % new screen size
    bst_layout('default'); % make a default
    L = getpref('BrainStorm','Layout'); % new values
end


winpos = L.winpos;
tilepos = L.tilepos;
allpos = L.allpos;

% Retrieve sizes of tiles
FullHeight = tilepos{1,1}(1,4); % full height
HalfHeight = tilepos{2,1}(1,4);
FullWidth = tilepos{1,1}(1,3);
HalfWidth = tilepos{1,2}(1,3);


if (~exist('hf','var')),
    hf = []; % set missing to default
end
if(isempty(hf)),
    % user did not give, so get all of them
    set(0,'ShowHidden','on');
    hf = findobj(0,'type','figure'); % all of the figure handles
end

if(~exist('tnum','var')),
    tnum = []; % set missing to default
end    

for i = 1:length(hf),
    TileType = getappdata(hf(i),'TileType');
    if(~isempty(TileType)),
        % one of the tile windows
        set(hf(i),'units','normalized'); % just in case
        if length(TileType) > 1
           TileType = TileType(1); % only want a single letter
           setappdata(hf(i),'TileType',TileType); % correct it
        end        
        
        switch TileType
        case 'M'
            set(hf(i),'position',winpos(1,:));
        case 'S'
            set(hf(i),'position',winpos(2,:));
        case 'D'
            set(hf(i),'position',winpos(3,:));
        case 'd'
            newType = winpos(3,:);
            newType(4) = newType(4)/1.5;;
            set(hf(i),'position',newType);
            case 'T'
            if(~isempty(tnum)),
                % user requested specific setting
                set(hf(i),'position',tilepos{trow,tcol}(tnum,:));
            else
                % snap the tile into the nearest corner and apparent size
                tpos = get(hf(i),'position');
                % distance to each corner
                tdist = sum((allpos(:,1:2) - repmat(tpos(1:2),9,1)).^2,2);
                [ignore,ipos] = min(tdist); % which is the nearest corner
                
                % is it tall or wide?
                isTall = abs(tpos(4) - FullHeight) < abs(tpos(4) - HalfHeight);
                isWide = abs(tpos(3) - FullWidth) < abs(tpos(3) - HalfWidth);
                
                switch ipos % using matlab subplot convention
                    % set the size dependent on where it is and *maybe*
                    %  on what its Tall and Wide was. Some positions
                    %  must be made shorter or narrower.
                case {1,3,4,8} % all same lower left, same as [223]
                    if isTall & isWide
                        set(hf(i),'position',tilepos{1,1}(1,:));
                    elseif isTall & ~isWide
                        set(hf(i),'position',tilepos{1,2}(1,:));
                    elseif ~isTall & isWide
                        set(hf(i),'position',tilepos{2,1}(2,:));
                    else
                        set(hf(i),'position',tilepos{2,2}(3,:));
                    end
                case {2,6} % same as [221]
                    if isWide,
                        set(hf(i),'position',tilepos{2,1}(1,:));
                    else
                        set(hf(i),'position',tilepos{2,2}(1,:));
                    end
                case 7 % same as [222]
                    % must be made not wide and not tall
                    set(hf(i),'position',tilepos{2,2}(2,:));
                case {5,9} % same as [224]
                    if isTall
                        set(hf(i),'position',tilepos{1,2}(2,:));
                    else
                        set(hf(i),'position',tilepos{2,2}(4,:));
                    end
                end % setting the final position and shape
                
                
            end % if snapping or setting the position
        end % for the case of Tiles
        
        % if the menu bar is on, then subtract a little from the height
        MENUBAR = 0; % default is to assume no menubar
        if(strcmp(get(hf(i),'menubar'),'figure')),
            MENUBAR = 1;
        end
        if(~isempty(findobj(get(hf(i),'children'),'flat','type','uimenu'))),
            % one or more children is a uimenu, assume a menubar in place
            MENUBAR = 1;
        end
        if(MENUBAR), % if there is a menubar, allow for space
            final_pos = get(hf(i),'position'); % the final position of this window
            set(hf(i),'position',[final_pos(1:3) ...
                    final_pos(4)-L.MenuMargin]);
        end
        
    end % if it is one of our BrainStorm tiles in the workspace
end % for each of the figure windows

set(0,'ShowHidden','off'); % hide them again



% ---------------- Function to make position information ---------
function [winpos,tilepos,allpos] = make_positions(STYLE);
% Given Layout information, generate the actual positions of the windows and tiles
% winpos is the window position of the message, static, and dynamic windows
% tilepos is the positions for the different types of window sizes
% allpos is concatenation of all of them for convenience

global STYLE_BOTTOM STYLE_TOP % set in the above function

% index numbers for types of windows, for readability
Message = 1; 
Static = 2;
Dynamic = 3;

% Matlab's set('pos') function is set to normalized units. On a 1024 x 768
%  screen size, the name region and menu region each add .025 to the size,
%  i.e. set('pos') only takes into account the region below this.
% similarly the width is slightly wider

if(~ispref('BrainStorm','Layout')),
    bst_layout('Default')
end

L = getpref('BrainStorm','Layout');

ScreenSize = get_screensize;

% double check that L.ScreenSize exists
if(~isfield(L,'ScreenSize')), % it's missing
    bst_layout('default'); % make new structure
end


if(~all(ScreenSize == L.ScreenSize)), % new screen size
    bst_layout('default'); % make a default
    L = getpref('BrainStorm','Layout'); % new values
end


% Let each type be possibly unique for final manipulations
topmargin_tile = L.NameMargin; % total top margin to allow for each tile's height
sidemargin_tile = L.SideMargin; % additional right side for each tile's width

topmargin_toolbar = L.NameMargin; % for active and static toolbars
sidemargin_toolbar = L.SideMargin;

topmargin_message = L.NameMargin; % for message window
sidemargin_message = L.SideMargin;


% define the full BrainStorm area on the screen
BSTx = L.ScreenPosition(1); % lower corner
BSTy = L.ScreenPosition(2);
BSTwidth = L.ScreenPosition(3); % usuable width
BSTheight = L.ScreenPosition(4); % usuable height

% now scale requests into the usuable area
MessageWidth = L.MessageWidth*BSTwidth; % actual width
MessageHeight = L.MessageHeight*BSTheight; % actual height
DynamicWidth = L.DynamicWidth*BSTwidth;
DynamicHeight = L.DynamicHeight*BSTheight;
StaticWidth = L.StaticWidth*BSTwidth;
StaticHeight = L.StaticHeight*BSTheight;

winpos = zeros(3,4); % lower x, lower y, width, height, all normalized
% Tile Positions in the Field
tilepos = cell(2); % 2 x 2 cell array

switch STYLE
case STYLE_BOTTOM
   
   % Message window across the bottom, to the Dynamic Toolbar
   winpos(Message,:) = [BSTx, BSTy, ...
         MessageWidth - sidemargin_message, MessageHeight - topmargin_message];
   
   % Static Toolbar to right of Message
   winpos(Static,:) = [BSTx + MessageWidth, BSTy,...
         StaticWidth-sidemargin_toolbar,... % remaining width
         StaticHeight-topmargin_toolbar]; % height
   
   % Dynamic ToolBar up the right side above Dynamic, at top of field
   winpos(Dynamic,:) = [BSTx + BSTwidth - DynamicWidth,...
         BSTy + BSTheight - DynamicHeight,...
         DynamicWidth-sidemargin_toolbar,DynamicHeight-topmargin_toolbar];
   
   % the available full tile field
   fieldx = BSTx;
   fieldy = BSTy + max(MessageHeight,StaticHeight); % just above Message or Static
   
case STYLE_TOP
    
   % Message window across the Top upper right
   winpos(Message,:) = [BSTx + StaticWidth, ...
         BSTy + BSTheight - MessageHeight, MessageWidth - sidemargin_message, MessageHeight - topmargin_message];
   
   % Static Toolbar in upper left
   winpos(Static,:) = [BSTx, BSTy + BSTheight - StaticHeight,...
         StaticWidth-sidemargin_toolbar,... % remaining width
         StaticHeight-topmargin_toolbar]; % height
   
   % Dynamic ToolBar up the right side above Dynamic, at top of field
   winpos(Dynamic,:) = [BSTx,...
         BSTy,...
         DynamicWidth-sidemargin_toolbar,DynamicHeight-topmargin_toolbar];
   
   % the available full tile field
   fieldx = BSTx + DynamicWidth;
   fieldy = BSTy; % just above Message or Static
   
end
  
fieldwidth = BSTwidth - DynamicWidth; % as wide as Message
fieldheight = BSTheight - max(MessageHeight,StaticHeight); % full remaining space above Message
% not including margins, this is just the field

% a single large tile
tilewidth = fieldwidth - sidemargin_tile;
tileheight = fieldheight - topmargin_tile;
tilepos{1,1} = [fieldx,fieldy,tilewidth,tileheight];

% two wide tiles, i.e. 2 rows by 1 col
% first window, second window
tilewidth = fieldwidth - sidemargin_tile;
tileheight = fieldheight/2 - topmargin_tile;

tilepos{2,1} = zeros(2,4);
tilepos{2,1} = [fieldx,fieldy + fieldheight/2,tilewidth,tileheight;...
        fieldx,fieldy,tilewidth,tileheight];

% two tall tiles, 1,2
tilewidth = fieldwidth/2 - sidemargin_tile;
tileheight = fieldheight - topmargin_tile;
tilepos{1,2} = zeros(2,4);
tilepos{1,2} = [fieldx,fieldy,tilewidth,tileheight;...
        fieldx + fieldwidth/2,fieldy,tilewidth,tileheight];

% four tiles, 2,2
tilewidth = fieldwidth/2 - sidemargin_tile;
tileheight = fieldheight/2 - topmargin_tile;
tilepos{2,2} = zeros(4,4);
tilepos{2,2} = [fieldx,fieldy + fieldheight/2,tilewidth,tileheight;...
        fieldx + fieldwidth/2,fieldy + fieldheight/2,tilewidth,tileheight;...
        fieldx, fieldy, tilewidth, tileheight;...
        fieldx + fieldwidth/2,fieldy, tilewidth, tileheight];

% ------- End of creating winpos and tilepos matrices

% allpos is a handy matrix for the positions of all field tiles
allpos = zeros(9,4);
allpos(1,:) = tilepos{1};
allpos(2:3,:) = tilepos{2,1};
allpos(4:5,:) = tilepos{1,2};
allpos(6:9,:) = tilepos{2,2};

L.winpos = winpos;
L.tilepos = tilepos;
L.allpos = allpos;

setpref('BrainStorm','Layout',L); % write back into structure

Produced by color_mat2html, a customized BrainStorm 2.0 (Alpha) version of mat2html on Tue Oct 12 12:05:14 2004
Cross-Directory links are: ON