001: /*
002: * DockableLayout.java -- a more flexible BorderLayout
003: * :tabSize=8:indentSize=8:noTabs=false:
004: * :folding=explicit:collapseFolds=1:
005: *
006: * Copyright (C) 2000, 2005 Slava Pestov
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License
010: * as published by the Free Software Foundation; either version 2
011: * of the License, or any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
021: */
022:
023: package org.gjt.sp.jedit.gui;
024:
025: //{{{ Imports
026: import java.awt.*;
027:
028: //}}}
029:
030: public class DockableLayout implements LayoutManager2 {
031: // for backwards compatibility with plugins that fiddle with
032: // jEdit's UI layout
033: static final String CENTER = BorderLayout.CENTER;
034:
035: public static final String TOP_TOOLBARS = "top-toolbars";
036: public static final String BOTTOM_TOOLBARS = "bottom-toolbars";
037:
038: static final String TOP_BUTTONS = "top-buttons";
039: static final String LEFT_BUTTONS = "left-buttons";
040: static final String BOTTOM_BUTTONS = "bottom-buttons";
041: static final String RIGHT_BUTTONS = "right-buttons";
042:
043: private boolean alternateLayout;
044: private Component topToolbars, bottomToolbars;
045: private Component center;
046:
047: /* No good */
048: private DockablePanel top;
049: private DockablePanel left;
050: private DockablePanel bottom;
051: private DockablePanel right;
052:
053: private Component topButtons, leftButtons, bottomButtons,
054: rightButtons;
055:
056: /** @deprecated use isAlternateLayout */
057: public boolean setAlternateLayout() {
058: return isAlternateLayout();
059: }
060:
061: //{{{ isAlternateLayout() method
062:
063: /**
064: * jEdit View option: wide horizontal docking areas versus tall vertical docking areas
065: * @return true if using the "alternate layout"
066: */
067: public boolean isAlternateLayout() {
068: return alternateLayout;
069: } //}}}
070:
071: //{{{ setAlternateLayout() method
072: public void setAlternateLayout(boolean alternateLayout) {
073: this .alternateLayout = alternateLayout;
074: } //}}}
075:
076: //{{{ addLayoutComponent() method
077: public void addLayoutComponent(String name, Component comp) {
078: addLayoutComponent(comp, name);
079: } //}}}
080:
081: //{{{ addLayoutComponent() method
082: public void addLayoutComponent(Component comp, Object cons) {
083: if (cons == null || CENTER.equals(cons))
084: center = comp;
085: else if (TOP_TOOLBARS.equals(cons))
086: topToolbars = comp;
087: else if (BOTTOM_TOOLBARS.equals(cons))
088: bottomToolbars = comp;
089: else if (DockableWindowManager.TOP.equals(cons))
090: top = (DockablePanel) comp;
091: else if (DockableWindowManager.LEFT.equals(cons))
092: left = (DockablePanel) comp;
093: else if (DockableWindowManager.BOTTOM.equals(cons))
094: bottom = (DockablePanel) comp;
095: else if (DockableWindowManager.RIGHT.equals(cons))
096: right = (DockablePanel) comp;
097: else if (TOP_BUTTONS.equals(cons))
098: topButtons = comp;
099: else if (LEFT_BUTTONS.equals(cons))
100: leftButtons = comp;
101: else if (BOTTOM_BUTTONS.equals(cons))
102: bottomButtons = comp;
103: else if (RIGHT_BUTTONS.equals(cons))
104: rightButtons = comp;
105: } //}}}
106:
107: //{{{ removeLayoutComponent() method
108: public void removeLayoutComponent(Component comp) {
109: if (center == comp)
110: center = null;
111: else if (comp == topToolbars)
112: topToolbars = null;
113: else if (comp == bottomToolbars)
114: bottomToolbars = null;
115: else if (comp == top)
116: top = null;
117: else if (comp == left)
118: left = null;
119: else if (comp == bottom)
120: bottom = null;
121: else if (comp == right)
122: right = null;
123: } //}}}
124:
125: //{{{ preferredLayoutSize() method
126: public Dimension preferredLayoutSize(Container parent) {
127: Dimension prefSize = new Dimension(0, 0);
128: Dimension _top = top.getPreferredSize();
129: Dimension _left = left.getPreferredSize();
130: Dimension _bottom = bottom.getPreferredSize();
131: Dimension _right = right.getPreferredSize();
132: Dimension _topButtons = topButtons.getPreferredSize();
133: Dimension _leftButtons = leftButtons.getPreferredSize();
134: Dimension _bottomButtons = bottomButtons.getPreferredSize();
135: Dimension _rightButtons = rightButtons.getPreferredSize();
136: Dimension _center = (center == null ? new Dimension(0, 0)
137: : center.getPreferredSize());
138: Dimension _topToolbars = (topToolbars == null ? new Dimension(
139: 0, 0) : topToolbars.getPreferredSize());
140: Dimension _bottomToolbars = (bottomToolbars == null ? new Dimension(
141: 0, 0)
142: : bottomToolbars.getPreferredSize());
143:
144: prefSize.height = _top.height + _bottom.height + _center.height
145: + _topButtons.height + _bottomButtons.height
146: + _topToolbars.height + _bottomToolbars.height;
147: prefSize.width = _left.width
148: + _right.width
149: + Math.max(_center.width, Math.max(_topToolbars.width,
150: _bottomToolbars.width)) + _leftButtons.width
151: + _rightButtons.width;
152:
153: return prefSize;
154: } //}}}
155:
156: //{{{ minimumLayoutSize() method
157: public Dimension minimumLayoutSize(Container parent) {
158: // I'm lazy
159: return preferredLayoutSize(parent);
160: } //}}}
161:
162: //{{{ maximumLayoutSize() method
163: public Dimension maximumLayoutSize(Container parent) {
164: return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
165: } //}}}
166:
167: //{{{ layoutContainer() method
168: public void layoutContainer(Container parent) {
169: Dimension size = parent.getSize();
170:
171: Dimension _topToolbars = (topToolbars == null ? new Dimension(
172: 0, 0) : topToolbars.getPreferredSize());
173: Dimension _bottomToolbars = (bottomToolbars == null ? new Dimension(
174: 0, 0)
175: : bottomToolbars.getPreferredSize());
176:
177: int topButtonHeight = -1;
178: int bottomButtonHeight = -1;
179: int leftButtonWidth = -1;
180: int rightButtonWidth = -1;
181:
182: Dimension _top = top.getPreferredSize();
183: Dimension _left = left.getPreferredSize();
184: Dimension _bottom = bottom.getPreferredSize();
185: Dimension _right = right.getPreferredSize();
186:
187: int topHeight = _top.height;
188: int bottomHeight = _bottom.height;
189: int leftWidth = _left.width;
190: int rightWidth = _right.width;
191:
192: boolean topEmpty = ((Container) topButtons).getComponentCount() <= 2;
193: boolean leftEmpty = ((Container) leftButtons)
194: .getComponentCount() <= 2;
195: boolean bottomEmpty = ((Container) bottomButtons)
196: .getComponentCount() <= 2;
197: boolean rightEmpty = ((Container) rightButtons)
198: .getComponentCount() <= 2;
199:
200: Dimension closeBoxSize;
201: if (((Container) topButtons).getComponentCount() == 0)
202: closeBoxSize = new Dimension(0, 0);
203: else {
204: closeBoxSize = ((Container) topButtons).getComponent(0)
205: .getPreferredSize();
206: }
207:
208: int closeBoxWidth = Math.max(closeBoxSize.width,
209: closeBoxSize.height) + 1;
210:
211: if (alternateLayout) {
212: //{{{ Lay out independent buttons
213: int _width = size.width;
214:
215: int padding = (leftEmpty && rightEmpty) ? 0 : closeBoxWidth;
216:
217: topButtonHeight = top.getWindowContainer()
218: .getWrappedDimension(_width - closeBoxWidth * 2);
219: topButtons.setBounds(padding, 0, size.width - padding * 2,
220: topButtonHeight);
221:
222: bottomButtonHeight = bottom.getWindowContainer()
223: .getWrappedDimension(_width);
224: bottomButtons.setBounds(padding, size.height
225: - bottomButtonHeight, size.width - padding * 2,
226: bottomButtonHeight);
227:
228: int _height = size.height - topButtonHeight
229: - bottomButtonHeight;
230: //}}}
231:
232: //{{{ Lay out dependent buttons
233: leftButtonWidth = left.getWindowContainer()
234: .getWrappedDimension(_height);
235: leftButtons
236: .setBounds(0, topHeight + topButtonHeight,
237: leftButtonWidth, _height - topHeight
238: - bottomHeight);
239:
240: rightButtonWidth = right.getWindowContainer()
241: .getWrappedDimension(_height);
242: rightButtons.setBounds(size.width - rightButtonWidth,
243: topHeight + topButtonHeight, rightButtonWidth,
244: _height - topHeight - bottomHeight);
245: //}}}
246:
247: int[] dimensions = adjustDockingAreasToFit(size, topHeight,
248: leftWidth, bottomHeight, rightWidth,
249: topButtonHeight, leftButtonWidth,
250: bottomButtonHeight, rightButtonWidth, _topToolbars,
251: _bottomToolbars);
252:
253: topHeight = dimensions[0];
254: leftWidth = dimensions[1];
255: bottomHeight = dimensions[2];
256: rightWidth = dimensions[3];
257:
258: //{{{ Lay out docking areas
259: top.setBounds(0, topButtonHeight, size.width, topHeight);
260:
261: bottom.setBounds(0, size.height - bottomHeight
262: - bottomButtonHeight, size.width, bottomHeight);
263:
264: left.setBounds(leftButtonWidth,
265: topButtonHeight + topHeight, leftWidth, _height
266: - topHeight - bottomHeight);
267:
268: right.setBounds(_width - rightButtonWidth - rightWidth,
269: topButtonHeight + topHeight, rightWidth, _height
270: - topHeight - bottomHeight); //}}}
271: } else {
272: //{{{ Lay out independent buttons
273: int _height = size.height;
274:
275: int padding = (topEmpty && bottomEmpty ? 0 : closeBoxWidth);
276:
277: leftButtonWidth = left.getWindowContainer()
278: .getWrappedDimension(_height - closeBoxWidth * 2);
279: leftButtons.setBounds(0, padding, leftButtonWidth, _height
280: - padding * 2);
281:
282: rightButtonWidth = right.getWindowContainer()
283: .getWrappedDimension(_height);
284: rightButtons.setBounds(size.width - rightButtonWidth,
285: padding, rightButtonWidth, _height - padding * 2);
286:
287: int _width = size.width - leftButtonWidth
288: - rightButtonWidth;
289: //}}}
290:
291: //{{{ Lay out dependent buttons
292: topButtonHeight = top.getWindowContainer()
293: .getWrappedDimension(_width);
294: topButtons.setBounds(leftButtonWidth + leftWidth, 0, _width
295: - leftWidth - rightWidth, topButtonHeight);
296:
297: bottomButtonHeight = bottom.getWindowContainer()
298: .getWrappedDimension(_width);
299: bottomButtons.setBounds(leftButtonWidth + leftWidth,
300: _height - bottomButtonHeight, _width - leftWidth
301: - rightWidth, bottomButtonHeight); //}}}
302:
303: int[] dimensions = adjustDockingAreasToFit(size, topHeight,
304: leftWidth, bottomHeight, rightWidth,
305: topButtonHeight, leftButtonWidth,
306: bottomButtonHeight, rightButtonWidth, _topToolbars,
307: _bottomToolbars);
308:
309: topHeight = dimensions[0];
310: leftWidth = dimensions[1];
311: bottomHeight = dimensions[2];
312: rightWidth = dimensions[3];
313:
314: //{{{ Lay out docking areas
315: top.setBounds(leftButtonWidth + leftWidth, topButtonHeight,
316: _width - leftWidth - rightWidth, topHeight);
317:
318: bottom.setBounds(leftButtonWidth + leftWidth, size.height
319: - bottomHeight - bottomButtonHeight, _width
320: - leftWidth - rightWidth, bottomHeight);
321:
322: left.setBounds(leftButtonWidth, 0, leftWidth, _height);
323:
324: right.setBounds(size.width - rightWidth - rightButtonWidth,
325: 0, rightWidth, _height); //}}}
326: }
327:
328: //{{{ Position tool bars if they are managed by us
329: if (topToolbars != null) {
330: topToolbars.setBounds(leftButtonWidth + leftWidth,
331: topButtonHeight + topHeight, size.width - leftWidth
332: - rightWidth - leftButtonWidth
333: - rightButtonWidth, _topToolbars.height);
334: }
335:
336: if (bottomToolbars != null) {
337: bottomToolbars.setBounds(leftButtonWidth + leftWidth,
338: size.height - bottomHeight - bottomButtonHeight
339: - _bottomToolbars.height, size.width
340: - leftWidth - rightWidth - leftButtonWidth
341: - rightButtonWidth, _bottomToolbars.height);
342: } //}}}
343:
344: //{{{ Position center (edit pane, or split pane)
345: if (center != null) {
346: center.setBounds(leftButtonWidth + leftWidth,
347: topButtonHeight + topHeight + _topToolbars.height,
348: size.width - leftWidth - rightWidth
349: - leftButtonWidth - rightButtonWidth,
350: size.height - topHeight - topButtonHeight
351: - bottomHeight - bottomButtonHeight
352: - _topToolbars.height
353: - _bottomToolbars.height);
354: } //}}}
355: } //}}}
356:
357: //{{{ adjustDockingAreasToFit() method
358: private int[] adjustDockingAreasToFit(Dimension size,
359: int topHeight, int leftWidth, int bottomHeight,
360: int rightWidth, int topButtonHeight, int leftButtonWidth,
361: int bottomButtonHeight, int rightButtonWidth,
362: Dimension _topToolbars, Dimension _bottomToolbars) {
363: int maxTopHeight = size.height - bottomHeight - topButtonHeight
364: - bottomButtonHeight - _topToolbars.height
365: - _bottomToolbars.height;
366: topHeight = Math.min(Math.max(0, maxTopHeight), topHeight);
367: leftWidth = Math.min(Math.max(0, size.width - leftButtonWidth
368: - rightButtonWidth - rightWidth), leftWidth);
369: int maxBottomHeight = size.height - topHeight - topButtonHeight
370: - bottomButtonHeight - _topToolbars.height
371: - _bottomToolbars.height;
372: bottomHeight = Math.min(Math.max(0, maxBottomHeight),
373: bottomHeight);
374: rightWidth = Math.min(Math.max(0, size.width - leftButtonWidth
375: - rightButtonWidth - leftWidth), rightWidth);
376:
377: top.getWindowContainer().setDimension(topHeight);
378: left.getWindowContainer().setDimension(leftWidth);
379: bottom.getWindowContainer().setDimension(bottomHeight);
380: right.getWindowContainer().setDimension(rightWidth);
381:
382: return new int[] { topHeight, leftWidth, bottomHeight,
383: rightWidth };
384: } //}}}
385:
386: //{{{ getLayoutAlignmentX() method
387: public float getLayoutAlignmentX(Container target) {
388: return 0.5f;
389: } //}}}
390:
391: //{{{ getLayoutAlignmentY() method
392: public float getLayoutAlignmentY(Container target) {
393: return 0.5f;
394: } //}}}
395:
396: //{{{ invalidateLayout() method
397: public void invalidateLayout(Container target) {
398: }
399: //}}}
400: }
|