/*FreeMind - A Program for creating and viewing Mindmaps *Copyright (C) 2000-2007 Joerg Mueller, Daniel Polansky, Christian Foltin, Dimitri Polivaev and others. *See COPYING for Details * *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 (at your option) 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 freemind.view.mindmapview; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Point; import javax.swing.JComponent; import freemind.main.Tools; import freemind.modes.MindMapNode; /** * @author foltin * @date 11.07.2013 */ abstract public class NodeViewLayoutAdapter implements NodeViewLayout { protected final int LISTENER_VIEW_WIDTH = 10; protected static java.util.logging.Logger logger = null; protected Point location = new Point(); private static Dimension minDimension; private NodeView view; private MindMapNode model; private int childCount; private JComponent content; private int vGap; private int spaceAround; public NodeViewLayoutAdapter() { if (logger == null) { logger = freemind.main.Resources.getInstance().getLogger( this.getClass().getName()); } } public void addLayoutComponent(String arg0, Component arg1) { } /* * (non-Javadoc) * * @see java.awt.LayoutManager#removeLayoutComponent(java.awt.Component) */ public void removeLayoutComponent(Component arg0) { } /* * (non-Javadoc) * * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container) */ public Dimension minimumLayoutSize(Container arg0) { if (minDimension == null) minDimension = new Dimension(0, 0); return minDimension; } /* * (non-Javadoc) * * @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container) */ public Dimension preferredLayoutSize(Container c) { if (!c.isValid()) { c.validate(); } return c.getSize(); } public void layoutContainer(Container c) { setUp(c); layout(); Point location2 = view.getLocation(); Tools.convertPointToAncestor(view, location2, view.getMap()); // logger.info("Layouting node '" + view.getModel() + "' to " + location2); layoutOtherItems(); shutDown(); } /** * */ private void layoutOtherItems() { final int componentCount = view.getComponentCount(); for (int i = 0; i < componentCount; i++) { final Component component = view.getComponent(i); if (component instanceof NodeMotionListenerView) { NodeMotionListenerView nodeMotionListenerView = (NodeMotionListenerView) component; layoutNodeMotionListenerView(nodeMotionListenerView); } else if (component instanceof NodeFoldingComponent) { NodeFoldingComponent foldingComponent = (NodeFoldingComponent) component; layoutNodeFoldingComponent(foldingComponent); } } } abstract protected void layout(); private void setUp(Container c) { final NodeView localView = (NodeView) c; localView.syncronizeAttributeView(); final int localChildCount = localView.getComponentCount() - 1; for (int i = 0; i < localChildCount; i++) { localView.getComponent(i).validate(); } this.view = localView; this.model = localView.getModel(); this.childCount = localChildCount; this.content = localView.getContent(); if (getModel().isVisible()) { this.vGap = getView().getVGap(); } else { this.vGap = getView().getVisibleParentView().getVGap(); } spaceAround = view.getMap().getZoomed(NodeView.SPACE_AROUND); } private void shutDown() { this.view = null; this.model = null; this.content = null; this.childCount = 0; this.vGap = 0; this.spaceAround = 0; } /** * @return Returns the view. */ protected NodeView getView() { return view; } /** * @return Returns the model. */ protected MindMapNode getModel() { return model; } /** * @return Returns the childCount. */ protected int getChildCount() { return childCount; } /** * @return Returns the content. */ protected JComponent getContent() { return content; } protected int getChildContentHeight(boolean isLeft) { final int childCount = getChildCount(); if (childCount == 0) { return 0; } int height = 0; int count = 0; for (int i = 0; i < childCount; i++) { Component component = getView().getComponent(i); if (component instanceof NodeView) { NodeView child = (NodeView) component; if (child.isLeft() == isLeft) { final int additionalCloudHeigth = child .getAdditionalCloudHeigth(); final int contentHeight = child.getContent().getHeight(); height += contentHeight + additionalCloudHeigth; count++; } } } return height + vGap * (count - 1); } /** * @param isLeft * @return a shift, which is less than or equal zero */ protected int getChildVerticalShift(boolean isLeft) { int shift = 0; boolean isFirstNodeView = false; boolean foundNodeView = false; for (int i = 0; i < getChildCount(); i++) { Component component = getView().getComponent(i); if (component instanceof NodeView) { NodeView child = (NodeView) component; if (child.isLeft() == isLeft) { final int childShift = child.getShift(); if (childShift < 0 || isFirstNodeView) { shift += childShift; isFirstNodeView = false; } shift -= (child.getContent().getY() - getSpaceAround()); foundNodeView = true; } } } if(foundNodeView) { shift -= getSpaceAround(); } return shift; } protected int getChildHorizontalShift() { if (getChildCount() == 0) return 0; int shift = 0; for (int i = 0; i < getChildCount(); i++) { Component component = getView().getComponent(i); if (component instanceof NodeView) { NodeView child = (NodeView) component; int shiftCandidate; if (child.isLeft()) { shiftCandidate = -child.getContent().getX() - child.getContent().getWidth(); if (child.isContentVisible()) { shiftCandidate -= child.getHGap() + child.getAdditionalCloudHeigth() / 2; } } else { shiftCandidate = -child.getContent().getX(); if (child.isContentVisible()) { shiftCandidate += child.getHGap(); } } shift = Math.min(shift, shiftCandidate); } } return shift; } /** * Implemented in the base class, as the root layout needs it, too. * @param childVerticalShift */ protected void placeRightChildren(int childVerticalShift) { final int baseX = getContent().getX() + getContent().getWidth(); int y = getContent().getY() + childVerticalShift; int right = baseX + getSpaceAround(); NodeView child = null; for (int i = 0; i < getChildCount(); i++) { Component componentC = getView().getComponent(i); if (componentC instanceof NodeView) { NodeView component = (NodeView) componentC; if (component.isLeft()) { continue; } child = component; final int additionalCloudHeigth = child.getAdditionalCloudHeigth() / 2; y += additionalCloudHeigth; int shiftY = child.getShift(); final int childHGap = child.getContent().isVisible() ? child .getHGap() : 0; int x = baseX + childHGap - child.getContent().getX(); if (shiftY < 0) { child.setLocation(x, y); y -= shiftY; } else { y += shiftY; child.setLocation(x, y); } // logger.info("Place of child " + component.getModel().getText() + ": " + child.getLocation()); y += child.getHeight() - 2 * getSpaceAround() + getVGap() + additionalCloudHeigth; right = Math.max(right, x + child.getWidth() + additionalCloudHeigth); } } int bottom = getContent().getY() + getContent().getHeight() + getSpaceAround(); if (child != null) { getView().setSize( right, Math.max( bottom, child.getY() + child.getHeight() + child.getAdditionalCloudHeigth() / 2)); } else { getView().setSize(right, bottom); } } /** * Implemented in the base class, as the root layout needs it, too. * @param childVerticalShift */ protected void placeLeftChildren(int childVerticalShift) { final int baseX = getContent().getX(); int y = getContent().getY() + childVerticalShift; int right = baseX + getContent().getWidth() + getSpaceAround(); NodeView child = null; for (int i = 0; i < getChildCount(); i++) { Component componentC = getView().getComponent(i); if (componentC instanceof NodeView) { NodeView component = (NodeView) componentC; if (!component.isLeft()) { continue; } child = component; final int additionalCloudHeigth = child.getAdditionalCloudHeigth() / 2; y += additionalCloudHeigth; int shiftY = child.getShift(); final int childHGap = child.getContent().isVisible() ? child .getHGap() : 0; int x = baseX - childHGap - child.getContent().getX() - child.getContent().getWidth(); if (shiftY < 0) { child.setLocation(x, y); y -= shiftY; } else { y += shiftY; child.setLocation(x, y); } y += child.getHeight() - 2 * getSpaceAround() + getVGap() + additionalCloudHeigth; right = Math.max(right, x + child.getWidth()); } } int bottom = getContent().getY() + getContent().getHeight() + getSpaceAround(); if (child != null) { getView().setSize( right, Math.max( bottom, child.getY() + child.getHeight() + child.getAdditionalCloudHeigth() / 2)); } else { getView().setSize(right, bottom); } } /** * @return Returns the vGap. */ int getVGap() { return vGap; } /** * @return Returns the spaceAround. */ int getSpaceAround() { return spaceAround; } /* (non-Javadoc) * @see freemind.view.mindmapview.NodeViewLayout#layoutNodeFoldingComponent(freemind.view.mindmapview.NodeFoldingListenerView) */ public void layoutNodeFoldingComponent( NodeFoldingComponent pFoldingComponent) { NodeView movedView = pFoldingComponent.getNodeView(); Point location = movedView.getFoldingMarkPosition(); JComponent content = movedView.getContent(); Tools.convertPointToAncestor(content, location, pFoldingComponent.getParent()); pFoldingComponent.setCorrectedLocation(location); Dimension preferredSize = pFoldingComponent.getPreferredSize(); pFoldingComponent.setSize(preferredSize.width, preferredSize.height); } }