/* * DockableLayout.java -- a more flexible BorderLayout * :tabSize=4:indentSize=4:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 2000, 2005 Slava Pestov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.gjt.sp.jedit.gui; //{{{ Imports import java.awt.*; //}}} /** A more flexible BorderLayout with dockables. */ public class DockableLayout implements LayoutManager2 { // for backwards compatibility with plugins that fiddle with // jEdit's UI layout static final String CENTER = BorderLayout.CENTER; static final String TOP_BUTTONS = "top-buttons"; static final String LEFT_BUTTONS = "left-buttons"; static final String BOTTOM_BUTTONS = "bottom-buttons"; static final String RIGHT_BUTTONS = "right-buttons"; private boolean alternateLayout; private Component center; /* No good */ private DockablePanel top; private DockablePanel left; private DockablePanel bottom; private DockablePanel right; private Component topButtons, leftButtons, bottomButtons, rightButtons; //{{{ isAlternateLayout() method /** * jEdit View option: wide horizontal docking areas versus tall vertical docking areas * @return true if using the "alternate layout" */ public boolean isAlternateLayout() { return alternateLayout; } //}}} //{{{ setAlternateLayout() method public void setAlternateLayout(boolean alternateLayout) { this.alternateLayout = alternateLayout; } //}}} //{{{ addLayoutComponent() method public void addLayoutComponent(String name, Component comp) { addLayoutComponent(comp, name); } //}}} //{{{ addLayoutComponent() method public void addLayoutComponent(Component comp, Object cons) { if(cons == null || CENTER.equals(cons)) center = comp; else if(DockableWindowManager.TOP.equals(cons)) top = (DockablePanel)comp; else if(DockableWindowManager.LEFT.equals(cons)) left = (DockablePanel)comp; else if(DockableWindowManager.BOTTOM.equals(cons)) bottom = (DockablePanel)comp; else if(DockableWindowManager.RIGHT.equals(cons)) right = (DockablePanel)comp; else if(TOP_BUTTONS.equals(cons)) topButtons = comp; else if(LEFT_BUTTONS.equals(cons)) leftButtons = comp; else if(BOTTOM_BUTTONS.equals(cons)) bottomButtons = comp; else if(RIGHT_BUTTONS.equals(cons)) rightButtons = comp; } //}}} //{{{ removeLayoutComponent() method public void removeLayoutComponent(Component comp) { if(center == comp) center = null; else if(comp == top) top = null; else if(comp == left) left = null; else if(comp == bottom) bottom = null; else if(comp == right) right = null; } //}}} //{{{ preferredLayoutSize() method public Dimension preferredLayoutSize(Container parent) { Dimension prefSize = new Dimension(0,0); Dimension _top = top.getPreferredSize(); Dimension _left = left.getPreferredSize(); Dimension _bottom = bottom.getPreferredSize(); Dimension _right = right.getPreferredSize(); Dimension _topButtons = topButtons.getPreferredSize(); Dimension _leftButtons = leftButtons.getPreferredSize(); Dimension _bottomButtons = bottomButtons.getPreferredSize(); Dimension _rightButtons = rightButtons.getPreferredSize(); Dimension _center = (center == null ? new Dimension(0,0) : center.getPreferredSize()); Dimension _topToolbars = new Dimension(0,0); Dimension _bottomToolbars = new Dimension(0,0); prefSize.height = _top.height + _bottom.height + _center.height + _topButtons.height + _bottomButtons.height + _topToolbars.height + _bottomToolbars.height; prefSize.width = _left.width + _right.width + Math.max(_center.width, Math.max(_topToolbars.width,_bottomToolbars.width)) + _leftButtons.width + _rightButtons.width; return prefSize; } //}}} //{{{ minimumLayoutSize() method public Dimension minimumLayoutSize(Container parent) { // I'm lazy return preferredLayoutSize(parent); } //}}} //{{{ maximumLayoutSize() method public Dimension maximumLayoutSize(Container parent) { return new Dimension(Integer.MAX_VALUE,Integer.MAX_VALUE); } //}}} //{{{ layoutContainer() method public void layoutContainer(Container parent) { Dimension size = parent.getSize(); Dimension _topToolbars = new Dimension(0,0); Dimension _bottomToolbars = new Dimension(0,0); int topButtonHeight = -1; int bottomButtonHeight = -1; int leftButtonWidth = -1; int rightButtonWidth = -1; Dimension _top = top.getPreferredSize(); Dimension _left = left.getPreferredSize(); Dimension _bottom = bottom.getPreferredSize(); Dimension _right = right.getPreferredSize(); int topHeight = _top.height; int bottomHeight = _bottom.height; int leftWidth = _left.width; int rightWidth = _right.width; boolean topEmpty = ((Container)topButtons) .getComponentCount() <= 2; boolean leftEmpty = ((Container)leftButtons) .getComponentCount() <= 2; boolean bottomEmpty = ((Container)bottomButtons) .getComponentCount() <= 2; boolean rightEmpty = ((Container)rightButtons) .getComponentCount() <= 2; Dimension closeBoxSize; if(((Container)topButtons).getComponentCount() == 0) closeBoxSize = new Dimension(0,0); else { closeBoxSize = ((Container)topButtons) .getComponent(0).getPreferredSize(); } int closeBoxWidth = Math.max(closeBoxSize.width, closeBoxSize.height) + 1; if(alternateLayout) { //{{{ Lay out independent buttons int _width = size.width; int padding = (leftEmpty&&rightEmpty) ? 0 : closeBoxWidth; topButtonHeight = top.getWindowContainer() .getWrappedDimension(_width - closeBoxWidth * 2); topButtons.setBounds( padding, 0, size.width - padding * 2, topButtonHeight); bottomButtonHeight = bottom.getWindowContainer() .getWrappedDimension(_width); bottomButtons.setBounds( padding, size.height - bottomButtonHeight, size.width - padding * 2, bottomButtonHeight); int _height = size.height - topButtonHeight - bottomButtonHeight; //}}} //{{{ Lay out dependent buttons leftButtonWidth = left.getWindowContainer() .getWrappedDimension(_height); leftButtons.setBounds( 0, topHeight + topButtonHeight, leftButtonWidth, _height - topHeight - bottomHeight); rightButtonWidth = right.getWindowContainer() .getWrappedDimension(_height); rightButtons.setBounds( size.width - rightButtonWidth, topHeight + topButtonHeight, rightButtonWidth, _height - topHeight - bottomHeight); //}}} int[] dimensions = adjustDockingAreasToFit( size, topHeight, leftWidth, bottomHeight, rightWidth, topButtonHeight, leftButtonWidth, bottomButtonHeight, rightButtonWidth, _topToolbars, _bottomToolbars); topHeight = dimensions[0]; leftWidth = dimensions[1]; bottomHeight = dimensions[2]; rightWidth = dimensions[3]; //{{{ Lay out docking areas top.setBounds( 0, topButtonHeight, size.width, topHeight); bottom.setBounds( 0, size.height - bottomHeight - bottomButtonHeight, size.width, bottomHeight); left.setBounds( leftButtonWidth, topButtonHeight + topHeight, leftWidth, _height - topHeight - bottomHeight); right.setBounds( _width - rightButtonWidth - rightWidth, topButtonHeight + topHeight, rightWidth, _height - topHeight - bottomHeight); //}}} } else { //{{{ Lay out independent buttons int _height = size.height; int padding = (topEmpty && bottomEmpty ? 0 : closeBoxWidth); leftButtonWidth = left.getWindowContainer() .getWrappedDimension(_height - closeBoxWidth * 2); leftButtons.setBounds( 0, padding, leftButtonWidth, _height - padding * 2); rightButtonWidth = right.getWindowContainer() .getWrappedDimension(_height); rightButtons.setBounds( size.width - rightButtonWidth, padding, rightButtonWidth, _height - padding * 2); int _width = size.width - leftButtonWidth - rightButtonWidth; //}}} //{{{ Lay out dependent buttons topButtonHeight = top.getWindowContainer() .getWrappedDimension(_width); topButtons.setBounds( leftButtonWidth + leftWidth, 0, _width - leftWidth - rightWidth, topButtonHeight); bottomButtonHeight = bottom.getWindowContainer() .getWrappedDimension(_width); bottomButtons.setBounds( leftButtonWidth + leftWidth, _height - bottomButtonHeight, _width - leftWidth - rightWidth, bottomButtonHeight); //}}} int[] dimensions = adjustDockingAreasToFit( size, topHeight, leftWidth, bottomHeight, rightWidth, topButtonHeight, leftButtonWidth, bottomButtonHeight, rightButtonWidth, _topToolbars, _bottomToolbars); topHeight = dimensions[0]; leftWidth = dimensions[1]; bottomHeight = dimensions[2]; rightWidth = dimensions[3]; //{{{ Lay out docking areas top.setBounds( leftButtonWidth + leftWidth, topButtonHeight, _width - leftWidth - rightWidth, topHeight); bottom.setBounds( leftButtonWidth + leftWidth, size.height - bottomHeight - bottomButtonHeight, _width - leftWidth - rightWidth, bottomHeight); left.setBounds( leftButtonWidth, 0, leftWidth, _height); right.setBounds( size.width - rightWidth - rightButtonWidth, 0, rightWidth, _height); //}}} } //{{{ Position center (edit pane, or split pane) if(center != null) { center.setBounds( leftButtonWidth + leftWidth, topButtonHeight + topHeight + _topToolbars.height, size.width - leftWidth - rightWidth - leftButtonWidth - rightButtonWidth, size.height - topHeight - topButtonHeight - bottomHeight - bottomButtonHeight - _topToolbars.height - _bottomToolbars.height); } //}}} } //}}} //{{{ adjustDockingAreasToFit() method private int[] adjustDockingAreasToFit( Dimension size, int topHeight, int leftWidth, int bottomHeight, int rightWidth, int topButtonHeight, int leftButtonWidth, int bottomButtonHeight, int rightButtonWidth, Dimension _topToolbars, Dimension _bottomToolbars) { int maxTopHeight = size.height - bottomHeight - topButtonHeight - bottomButtonHeight - _topToolbars.height - _bottomToolbars.height; topHeight = Math.min(Math.max(0,maxTopHeight), topHeight); leftWidth = Math.min(Math.max(0, size.width - leftButtonWidth - rightButtonWidth - rightWidth),leftWidth); int maxBottomHeight = size.height - topHeight - topButtonHeight - bottomButtonHeight - _topToolbars.height - _bottomToolbars.height; bottomHeight = Math.min(Math.max(0,maxBottomHeight), bottomHeight); rightWidth = Math.min(Math.max(0, size.width - leftButtonWidth - rightButtonWidth - leftWidth),rightWidth); top.getWindowContainer().setDimension(topHeight); left.getWindowContainer().setDimension(leftWidth); bottom.getWindowContainer().setDimension(bottomHeight); right.getWindowContainer().setDimension(rightWidth); return new int[] { topHeight, leftWidth, bottomHeight, rightWidth }; } //}}} //{{{ getLayoutAlignmentX() method public float getLayoutAlignmentX(Container target) { return 0.5f; } //}}} //{{{ getLayoutAlignmentY() method public float getLayoutAlignmentY(Container target) { return 0.5f; } //}}} //{{{ invalidateLayout() method public void invalidateLayout(Container target) {} //}}} }