/jEdit/branches/4.3.x-merge-request-2980833/org/gjt/sp/jedit/gui/DockableLayout.java

# · Java · 470 lines · 355 code · 59 blank · 56 comment · 40 complexity · bb38cf8e03dbbf1013e2f81e0904d0f0 MD5 · raw file

  1. /*
  2. * DockableLayout.java -- a more flexible BorderLayout
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000, 2005 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.gui;
  23. //{{{ Imports
  24. import java.awt.*;
  25. //}}}
  26. public class DockableLayout implements LayoutManager2
  27. {
  28. // for backwards compatibility with plugins that fiddle with
  29. // jEdit's UI layout
  30. static final String CENTER = BorderLayout.CENTER;
  31. static final String TOP_BUTTONS = "top-buttons";
  32. static final String LEFT_BUTTONS = "left-buttons";
  33. static final String BOTTOM_BUTTONS = "bottom-buttons";
  34. static final String RIGHT_BUTTONS = "right-buttons";
  35. private boolean alternateLayout;
  36. private Component center;
  37. /* No good */
  38. private DockablePanel top;
  39. private DockablePanel left;
  40. private DockablePanel bottom;
  41. private DockablePanel right;
  42. private Component topButtons, leftButtons, bottomButtons, rightButtons;
  43. /** @deprecated use isAlternateLayout */
  44. @Deprecated
  45. public boolean setAlternateLayout()
  46. {
  47. return isAlternateLayout();
  48. }
  49. //{{{ isAlternateLayout() method
  50. /**
  51. * jEdit View option: wide horizontal docking areas versus tall vertical docking areas
  52. * @return true if using the "alternate layout"
  53. */
  54. public boolean isAlternateLayout()
  55. {
  56. return alternateLayout;
  57. } //}}}
  58. //{{{ setAlternateLayout() method
  59. public void setAlternateLayout(boolean alternateLayout)
  60. {
  61. this.alternateLayout = alternateLayout;
  62. } //}}}
  63. //{{{ addLayoutComponent() method
  64. public void addLayoutComponent(String name, Component comp)
  65. {
  66. addLayoutComponent(comp, name);
  67. } //}}}
  68. //{{{ addLayoutComponent() method
  69. public void addLayoutComponent(Component comp, Object cons)
  70. {
  71. if(cons == null || CENTER.equals(cons))
  72. center = comp;
  73. else if(DockableWindowManager.TOP.equals(cons))
  74. top = (DockablePanel)comp;
  75. else if(DockableWindowManager.LEFT.equals(cons))
  76. left = (DockablePanel)comp;
  77. else if(DockableWindowManager.BOTTOM.equals(cons))
  78. bottom = (DockablePanel)comp;
  79. else if(DockableWindowManager.RIGHT.equals(cons))
  80. right = (DockablePanel)comp;
  81. else if(TOP_BUTTONS.equals(cons))
  82. topButtons = comp;
  83. else if(LEFT_BUTTONS.equals(cons))
  84. leftButtons = comp;
  85. else if(BOTTOM_BUTTONS.equals(cons))
  86. bottomButtons = comp;
  87. else if(RIGHT_BUTTONS.equals(cons))
  88. rightButtons = comp;
  89. } //}}}
  90. //{{{ removeLayoutComponent() method
  91. public void removeLayoutComponent(Component comp)
  92. {
  93. if(center == comp)
  94. center = null;
  95. else if(comp == top)
  96. top = null;
  97. else if(comp == left)
  98. left = null;
  99. else if(comp == bottom)
  100. bottom = null;
  101. else if(comp == right)
  102. right = null;
  103. } //}}}
  104. //{{{ preferredLayoutSize() method
  105. public Dimension preferredLayoutSize(Container parent)
  106. {
  107. Dimension prefSize = new Dimension(0,0);
  108. Dimension _top = top.getPreferredSize();
  109. Dimension _left = left.getPreferredSize();
  110. Dimension _bottom = bottom.getPreferredSize();
  111. Dimension _right = right.getPreferredSize();
  112. Dimension _topButtons = topButtons.getPreferredSize();
  113. Dimension _leftButtons = leftButtons.getPreferredSize();
  114. Dimension _bottomButtons = bottomButtons.getPreferredSize();
  115. Dimension _rightButtons = rightButtons.getPreferredSize();
  116. Dimension _center = (center == null
  117. ? new Dimension(0,0)
  118. : center.getPreferredSize());
  119. Dimension _topToolbars = new Dimension(0,0);
  120. Dimension _bottomToolbars = new Dimension(0,0);
  121. prefSize.height = _top.height + _bottom.height + _center.height
  122. + _topButtons.height + _bottomButtons.height
  123. + _topToolbars.height + _bottomToolbars.height;
  124. prefSize.width = _left.width + _right.width
  125. + Math.max(_center.width,
  126. Math.max(_topToolbars.width,_bottomToolbars.width))
  127. + _leftButtons.width + _rightButtons.width;
  128. return prefSize;
  129. } //}}}
  130. //{{{ minimumLayoutSize() method
  131. public Dimension minimumLayoutSize(Container parent)
  132. {
  133. // I'm lazy
  134. return preferredLayoutSize(parent);
  135. } //}}}
  136. //{{{ maximumLayoutSize() method
  137. public Dimension maximumLayoutSize(Container parent)
  138. {
  139. return new Dimension(Integer.MAX_VALUE,Integer.MAX_VALUE);
  140. } //}}}
  141. //{{{ layoutContainer() method
  142. public void layoutContainer(Container parent)
  143. {
  144. Dimension size = parent.getSize();
  145. Dimension _topToolbars = new Dimension(0,0);
  146. Dimension _bottomToolbars = new Dimension(0,0);
  147. int topButtonHeight = -1;
  148. int bottomButtonHeight = -1;
  149. int leftButtonWidth = -1;
  150. int rightButtonWidth = -1;
  151. Dimension _top = top.getPreferredSize();
  152. Dimension _left = left.getPreferredSize();
  153. Dimension _bottom = bottom.getPreferredSize();
  154. Dimension _right = right.getPreferredSize();
  155. int topHeight = _top.height;
  156. int bottomHeight = _bottom.height;
  157. int leftWidth = _left.width;
  158. int rightWidth = _right.width;
  159. boolean topEmpty = ((Container)topButtons)
  160. .getComponentCount() <= 2;
  161. boolean leftEmpty = ((Container)leftButtons)
  162. .getComponentCount() <= 2;
  163. boolean bottomEmpty = ((Container)bottomButtons)
  164. .getComponentCount() <= 2;
  165. boolean rightEmpty = ((Container)rightButtons)
  166. .getComponentCount() <= 2;
  167. Dimension closeBoxSize;
  168. if(((Container)topButtons).getComponentCount() == 0)
  169. closeBoxSize = new Dimension(0,0);
  170. else
  171. {
  172. closeBoxSize = ((Container)topButtons)
  173. .getComponent(0).getPreferredSize();
  174. }
  175. int closeBoxWidth = Math.max(closeBoxSize.width,
  176. closeBoxSize.height) + 1;
  177. if(alternateLayout)
  178. {
  179. //{{{ Lay out independent buttons
  180. int _width = size.width;
  181. int padding = (leftEmpty&&rightEmpty)
  182. ? 0 : closeBoxWidth;
  183. topButtonHeight = top.getWindowContainer()
  184. .getWrappedDimension(_width
  185. - closeBoxWidth * 2);
  186. topButtons.setBounds(
  187. padding,
  188. 0,
  189. size.width - padding * 2,
  190. topButtonHeight);
  191. bottomButtonHeight = bottom.getWindowContainer()
  192. .getWrappedDimension(_width);
  193. bottomButtons.setBounds(
  194. padding,
  195. size.height - bottomButtonHeight,
  196. size.width - padding * 2,
  197. bottomButtonHeight);
  198. int _height = size.height
  199. - topButtonHeight
  200. - bottomButtonHeight;
  201. //}}}
  202. //{{{ Lay out dependent buttons
  203. leftButtonWidth = left.getWindowContainer()
  204. .getWrappedDimension(_height);
  205. leftButtons.setBounds(
  206. 0,
  207. topHeight + topButtonHeight,
  208. leftButtonWidth,
  209. _height - topHeight - bottomHeight);
  210. rightButtonWidth = right.getWindowContainer()
  211. .getWrappedDimension(_height);
  212. rightButtons.setBounds(
  213. size.width - rightButtonWidth,
  214. topHeight + topButtonHeight,
  215. rightButtonWidth,
  216. _height - topHeight - bottomHeight);
  217. //}}}
  218. int[] dimensions = adjustDockingAreasToFit(
  219. size,
  220. topHeight,
  221. leftWidth,
  222. bottomHeight,
  223. rightWidth,
  224. topButtonHeight,
  225. leftButtonWidth,
  226. bottomButtonHeight,
  227. rightButtonWidth,
  228. _topToolbars,
  229. _bottomToolbars);
  230. topHeight = dimensions[0];
  231. leftWidth = dimensions[1];
  232. bottomHeight = dimensions[2];
  233. rightWidth = dimensions[3];
  234. //{{{ Lay out docking areas
  235. top.setBounds(
  236. 0,
  237. topButtonHeight,
  238. size.width,
  239. topHeight);
  240. bottom.setBounds(
  241. 0,
  242. size.height
  243. - bottomHeight
  244. - bottomButtonHeight,
  245. size.width,
  246. bottomHeight);
  247. left.setBounds(
  248. leftButtonWidth,
  249. topButtonHeight + topHeight,
  250. leftWidth,
  251. _height - topHeight - bottomHeight);
  252. right.setBounds(
  253. _width - rightButtonWidth - rightWidth,
  254. topButtonHeight + topHeight,
  255. rightWidth,
  256. _height - topHeight - bottomHeight); //}}}
  257. }
  258. else
  259. {
  260. //{{{ Lay out independent buttons
  261. int _height = size.height;
  262. int padding = (topEmpty && bottomEmpty
  263. ? 0 : closeBoxWidth);
  264. leftButtonWidth = left.getWindowContainer()
  265. .getWrappedDimension(_height
  266. - closeBoxWidth * 2);
  267. leftButtons.setBounds(
  268. 0,
  269. padding,
  270. leftButtonWidth,
  271. _height - padding * 2);
  272. rightButtonWidth = right.getWindowContainer()
  273. .getWrappedDimension(_height);
  274. rightButtons.setBounds(
  275. size.width - rightButtonWidth,
  276. padding,
  277. rightButtonWidth,
  278. _height - padding * 2);
  279. int _width = size.width
  280. - leftButtonWidth
  281. - rightButtonWidth;
  282. //}}}
  283. //{{{ Lay out dependent buttons
  284. topButtonHeight = top.getWindowContainer()
  285. .getWrappedDimension(_width);
  286. topButtons.setBounds(
  287. leftButtonWidth + leftWidth,
  288. 0,
  289. _width - leftWidth - rightWidth,
  290. topButtonHeight);
  291. bottomButtonHeight = bottom.getWindowContainer()
  292. .getWrappedDimension(_width);
  293. bottomButtons.setBounds(
  294. leftButtonWidth + leftWidth,
  295. _height - bottomButtonHeight,
  296. _width - leftWidth - rightWidth,
  297. bottomButtonHeight); //}}}
  298. int[] dimensions = adjustDockingAreasToFit(
  299. size,
  300. topHeight,
  301. leftWidth,
  302. bottomHeight,
  303. rightWidth,
  304. topButtonHeight,
  305. leftButtonWidth,
  306. bottomButtonHeight,
  307. rightButtonWidth,
  308. _topToolbars,
  309. _bottomToolbars);
  310. topHeight = dimensions[0];
  311. leftWidth = dimensions[1];
  312. bottomHeight = dimensions[2];
  313. rightWidth = dimensions[3];
  314. //{{{ Lay out docking areas
  315. top.setBounds(
  316. leftButtonWidth + leftWidth,
  317. topButtonHeight,
  318. _width - leftWidth - rightWidth,
  319. topHeight);
  320. bottom.setBounds(
  321. leftButtonWidth + leftWidth,
  322. size.height - bottomHeight - bottomButtonHeight,
  323. _width - leftWidth - rightWidth,
  324. bottomHeight);
  325. left.setBounds(
  326. leftButtonWidth,
  327. 0,
  328. leftWidth,
  329. _height);
  330. right.setBounds(
  331. size.width - rightWidth - rightButtonWidth,
  332. 0,
  333. rightWidth,
  334. _height); //}}}
  335. }
  336. //{{{ Position center (edit pane, or split pane)
  337. if(center != null)
  338. {
  339. center.setBounds(
  340. leftButtonWidth + leftWidth,
  341. topButtonHeight + topHeight
  342. + _topToolbars.height,
  343. size.width
  344. - leftWidth
  345. - rightWidth
  346. - leftButtonWidth
  347. - rightButtonWidth,
  348. size.height
  349. - topHeight
  350. - topButtonHeight
  351. - bottomHeight
  352. - bottomButtonHeight
  353. - _topToolbars.height
  354. - _bottomToolbars.height);
  355. } //}}}
  356. } //}}}
  357. //{{{ adjustDockingAreasToFit() method
  358. private int[] adjustDockingAreasToFit(
  359. Dimension size,
  360. int topHeight,
  361. int leftWidth,
  362. int bottomHeight,
  363. int rightWidth,
  364. int topButtonHeight,
  365. int leftButtonWidth,
  366. int bottomButtonHeight,
  367. int rightButtonWidth,
  368. Dimension _topToolbars,
  369. Dimension _bottomToolbars)
  370. {
  371. int maxTopHeight = size.height - bottomHeight
  372. - topButtonHeight - bottomButtonHeight
  373. - _topToolbars.height - _bottomToolbars.height;
  374. topHeight = Math.min(Math.max(0,maxTopHeight),
  375. topHeight);
  376. leftWidth = Math.min(Math.max(0,
  377. size.width - leftButtonWidth
  378. - rightButtonWidth - rightWidth),leftWidth);
  379. int maxBottomHeight = size.height - topHeight
  380. - topButtonHeight - bottomButtonHeight
  381. - _topToolbars.height - _bottomToolbars.height;
  382. bottomHeight = Math.min(Math.max(0,maxBottomHeight),
  383. bottomHeight);
  384. rightWidth = Math.min(Math.max(0,
  385. size.width - leftButtonWidth
  386. - rightButtonWidth - leftWidth),rightWidth);
  387. top.getWindowContainer().setDimension(topHeight);
  388. left.getWindowContainer().setDimension(leftWidth);
  389. bottom.getWindowContainer().setDimension(bottomHeight);
  390. right.getWindowContainer().setDimension(rightWidth);
  391. return new int[] {
  392. topHeight,
  393. leftWidth,
  394. bottomHeight,
  395. rightWidth
  396. };
  397. } //}}}
  398. //{{{ getLayoutAlignmentX() method
  399. public float getLayoutAlignmentX(Container target)
  400. {
  401. return 0.5f;
  402. } //}}}
  403. //{{{ getLayoutAlignmentY() method
  404. public float getLayoutAlignmentY(Container target)
  405. {
  406. return 0.5f;
  407. } //}}}
  408. //{{{ invalidateLayout() method
  409. public void invalidateLayout(Container target) {}
  410. //}}}
  411. }