blob: 63bff4e333f94148b7d978e7b0b329ec3a608cb2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2006 Sybase, Inc. and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsf.facesconfig.ui.preference;
import java.util.Iterator;
import org.eclipse.draw2d.ActionEvent;
import org.eclipse.draw2d.ActionListener;
import org.eclipse.draw2d.FreeformFigure;
import org.eclipse.draw2d.FreeformListener;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.Layer;
import org.eclipse.draw2d.LayoutManager;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jst.jsf.facesconfig.ui.EditorPlugin;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
/**
* The figure for Compound nodes
*/
/*package*/ class CompoundNodeFigure extends BaseNodeFigure implements
FreeformFigure, IContainerFigure {
private final static int MINIMIZED = 1;
final static int RESTORED = 2;
private final static int MAXIMIZED = 3;
private int state = RESTORED;
private TitleBarButton minButton;
private TitleBarButton maxButton;
private IconFigure iconFigure;
private WindowFigure windowFigure;
private static String DEFAULT_NAME = "CompoundNode";
private static String DEFAULT_ICON = "editor/CompoundNode.gif";
private static Image minimizeImage = EditorPlugin.getDefault().getImage(
"minimize.gif");
private static Image minimizeHiliteImage = EditorPlugin.getDefault()
.getImage("minimize_hilite.gif");
private static Image maximizeImage = EditorPlugin.getDefault().getImage(
"maximize.gif");
private static Image maximizeHiliteImage = EditorPlugin.getDefault()
.getImage("maximize_hilite.gif");
private static Image restoreImage = EditorPlugin.getDefault().getImage(
"restore.gif");
private static Image restoreHiliteImage = EditorPlugin.getDefault()
.getImage("restore_hilite.gif");
/**
* Default constructor
*/
public CompoundNodeFigure() {
// create all of the figures and adornments:
// the icon figure
super(new IconFigure(DEFAULT_NAME, EditorPlugin.getDefault().getImage(
DEFAULT_ICON)));
iconFigure = (IconFigure) getBaseFigure();
// and the window figure
windowFigure = new WindowFigure();
windowFigure.setForegroundColor(IconFigure.defaultForegroundColor);
windowFigure.setFont(IconFigure.defaultFont);
// then the minimize/maximize buttons.
// Note that the maxButton is also used for the "Restore" action
// TODO:
// The reason for putting these buttons in CompoundNodeFigure instead of
// WindowFigure where they really belong, is that the TitleBarButton is
// a
// draw2d Button (which subclasses Figure) and these must be placed in
// the
// titlebar (i.e. a SchemeBorder) because that's where they belong. The
// problem
// with this is that the Figure.paint() method first draws all of its
// children
// figures, then the border which means that the buttons would be
// obscured.
// This should be fixed as time allows and the WindowFigureListener
// interface
// should then also be modified to include a buttonPressed()
// notification
// for which CompoundNodeFigure can be a listener.
minButton = new TitleBarButton(minimizeImage, minimizeHiliteImage,
null, null);
maxButton = new TitleBarButton(maximizeImage, maximizeHiliteImage,
restoreImage, restoreHiliteImage);
add(minButton);
add(maxButton);
minButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
setState(CompoundNodeFigure.MINIMIZED);
}
});
maxButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
setState(maxButton.getState() ? CompoundNodeFigure.MAXIMIZED
: CompoundNodeFigure.RESTORED);
}
});
// show as a normal window initially
showIcon();
// testing BaseFigureDecorators:
// BaseFigureDecorator decorator;
// decorator = new
// BaseFigureDecorator(EditorPlugin.getDefault().getGEMImage("delete.gif"),
// "top right",
// PositionConstants.NORTH_EAST);
// addDecorator(decorator);
// decorator = new
// BaseFigureDecorator(EditorPlugin.getDefault().getGEMImage("delete.gif"),
// "top left",
// PositionConstants.NORTH_WEST);
// addDecorator(decorator);
// decorator = new
// BaseFigureDecorator(EditorPlugin.getDefault().getGEMImage("delete.gif"),
// "bottom right",
// PositionConstants.SOUTH_EAST);
// addDecorator(decorator);
// decorator = new
// BaseFigureDecorator(EditorPlugin.getDefault().getGEMImage("delete.gif"),
// "bottom left",
// PositionConstants.SOUTH_WEST);
// addDecorator(decorator);
}
public void setOpaque(boolean flag) {
windowFigure.setOpaque(flag);
}
/*
* Remove the window figure and its buttons and replace them with the icon
* figure.
*/
private void showIcon() {
// CR400779: GEM minimizing a complex activity sometimes leaves junk on
// the screen
setVisible(false);
minButton.setVisible(false);
maxButton.setVisible(false);
super.setBaseFigure(iconFigure);
setAnchorsVisible(true);
// CR400779: GEM minimizing a complex activity sometimes leaves junk on
// the screen
setVisible(true);
}
/*
* Remove the icon figure and replace with the window figure. Make sure the
* buttons are reset to their correct states.
*/
private void showWindow() {
// CR400779: GEM minimizing a complex activity sometimes leaves junk on
// the screen
setVisible(false);
if (state == RESTORED) {
super.setBaseFigure(windowFigure);
minButton.setVisible(true);
minButton.setState(false);
minButton.setToolTip(new Label("Minimize"));
maxButton.setVisible(true);
maxButton.setState(false);
maxButton.setToolTip(new Label("Maximize"));
setAnchorsVisible(true);
} else if (state == MAXIMIZED) {
setAnchorsVisible(false);
Rectangle constraint = new Rectangle(0, 0, -1, -1);
IFigure parent = getParent();
if (parent != null) {
constraint = parent.getBounds().getCopy();
constraint.width += constraint.x;
constraint.height += constraint.y;
constraint.x = 0;
constraint.y = 0;
}
super.setBaseFigure(windowFigure, constraint);
if (parent != null && parent.getLayoutManager() != null) {
// System.out.println("CompoundNode.showWindow: maximize
// "+constraint);
parent.getLayoutManager().setConstraint(this, constraint);
}
// the maximize button is used for both Maximize and Restore actions
minButton.setVisible(false);
maxButton.setVisible(true);
maxButton.setState(true);
maxButton.setToolTip(new Label("Restore"));
}
// CR400779: GEM minimizing a complex activity sometimes leaves junk on
// the screen
setVisible(true);
}
public void addDecorator(BaseFigureDecorator decorator) {
iconFigure.addDecorator(decorator);
}
public void removeDecorator() {
iconFigure.removeDecorator();
}
public void removeDecorator(int position) {
iconFigure.removeDecorator(position);
}
/**
* @param flag
*/
public void setHilight(boolean flag) {
windowFigure.setHighlight(flag);
if (flag)
moveToTop();
}
public void setText(String name) {
iconFigure.setText(name);
windowFigure.setText(name);
}
public void setIcon(Image image) {
iconFigure.setIcon(image);
}
public void setToolTipText(String text) {
iconFigure.setToolTipText(text);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Figure#layout()
*/
public void validate() {
LayoutManager layout = getLayoutManager();
if (state == MINIMIZED) {
// iconFigure.validate();
} else if (state == RESTORED) {
Rectangle r = windowFigure.getBounds().getCopy();
Insets i = windowFigure.getInsets();
Dimension dm = maxButton.getSize();
Insets p = windowFigure.getTabbedTitleBarBorder().getPadding();
layout.setConstraint(maxButton, new Rectangle(r.x + r.width
- dm.width - p.right - i.right, r.y + p.top + i.top
- dm.height - i.bottom, -1, -1));
layout.setConstraint(minButton, new Rectangle(r.x + r.width - 2
* dm.width - 2 * p.right - i.right, r.y + p.top + i.top
- dm.height - i.bottom, -1, -1));
} else if (state == MAXIMIZED) {
// CR387660: restore icon on complex activity bounces around
// we need to use the parent's bounds when maximized instead of
// current window bounds
if (getParent() == null)
return;
Rectangle r = getParent().getBounds().getCopy();
Insets i = windowFigure.getInsets();
Dimension dm = maxButton.getSize();
Insets p = windowFigure.getTabbedTitleBarBorder().getPadding();
layout.setConstraint(maxButton, new Rectangle(r.x + r.width
- dm.width - p.right - i.right, r.y + p.top, -1, -1));
}
super.validate();
}
/**
* @return the window figure
*/
public WindowFigure getWindowFigure() {
return windowFigure;
}
public void setFont(Font f) {
iconFigure.setFont(f);
windowFigure.setFont(f);
}
public void setForegroundColor(Color c) {
iconFigure.setForegroundColor(c);
windowFigure.setForegroundColor(c);
}
public void setBackgroundColor(Color c) {
iconFigure.setBackgroundColor(c);
windowFigure.setBackgroundColor(c);
}
/**
* @return the state
*/
public int getState() {
return state;
}
/**
* @param newState
*/
public void setState(int newState) {
int oldState = state;
state = newState;
if (state == CompoundNodeFigure.MINIMIZED) {
if (getParent() != null && getParent().getLayoutManager() != null) {
Rectangle constraint = (Rectangle) getParent()
.getLayoutManager().getConstraint(this);
constraint.width = -1;
constraint.height = -1;
}
showIcon();
} else if (state == CompoundNodeFigure.MAXIMIZED) {
if (getParent() != null && getParent().getLayoutManager() != null) {
Rectangle constraint = (Rectangle) getParent()
.getLayoutManager().getConstraint(this);
constraint.x = 0;
constraint.y = 0;
constraint.width = -1;
constraint.height = -1;
}
showWindow();
} else if (state == CompoundNodeFigure.RESTORED) {
if (getParent() != null && getParent().getLayoutManager() != null) {
Rectangle constraint = (Rectangle) getParent()
.getLayoutManager().getConstraint(this);
constraint.setSize(windowFigure.getBounds().getSize());
}
showWindow();
}
fireStateChanged(oldState, newState);
}
private void fireStateChanged(int oldState, int newState) {
Object l[] = windowFigure.getTabbedTitleBarBorder().getListeners();
for (int i = 0; i < l.length; ++i) {
if (l[i] instanceof CompoundFigureListener)
((CompoundFigureListener) l[i])
.stateChanged(oldState, newState);
}
}
public Dimension getMinimumSize(int wHint, int hHint) {
if (getState() == CompoundNodeFigure.RESTORED) {
Dimension d = windowFigure.getMinimumSize(wHint, hHint);
d.width += minButton.getSize().width
+ maxButton.getSize().width
+ 2
* windowFigure.getTabbedTitleBarBorder().getPadding()
.getWidth();
return d;
}
if (getState() == CompoundNodeFigure.MINIMIZED)
return iconFigure.getMinimumSize(wHint, hHint);
return super.getMinimumSize(wHint, hHint);
}
// //////////////////////////////////////////////////////////////////////
// FreeformFigure methods
// //////////////////////////////////////////////////////////////////////
private WindowFreeformHelper helper = new WindowFreeformHelper(this);
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.FreeformFigure#addFreeformListener(org.eclipse.draw2d.FreeformListener)
*/
public void addFreeformListener(FreeformListener listener) {
addListener(FreeformListener.class, listener);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.FreeformFigure#fireExtentChanged()
*/
public void fireExtentChanged() {
// CR389495: Working with nested complex activities causes in the BP
// editor causes lockup
// not specifically related to this CR, but caused a problem when
// compound node
// was moved beyond viewport's client area and de-selected - this would
// resize
// the viewport so that compound node no longer participated in bounds
// calculation.
if (state == MAXIMIZED) {
Iterator iter = getListeners(FreeformListener.class);
while (iter.hasNext())
((FreeformListener) iter.next()).notifyFreeformExtentChanged();
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.FreeformFigure#getFreeformExtent()
*/
public Rectangle getFreeformExtent() {
// CR389495: Working with nested complex activities causes in the BP
// editor causes lockup
// same as above
if (state == MAXIMIZED)
return helper.getFreeformExtent();
return getBounds();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.FreeformFigure#removeFreeformListener(org.eclipse.draw2d.FreeformListener)
*/
public void removeFreeformListener(FreeformListener listener) {
removeListener(FreeformListener.class, listener);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.FreeformFigure#setFreeformBounds(org.eclipse.draw2d.geometry.Rectangle)
*/
public void setFreeformBounds(Rectangle bounds) {
if (getState() == MAXIMIZED)
helper.setFreeformBounds(bounds);
}
/*
* CR389070: Figures are abbreviating rule figures names and making them
* unreadable New Method on IContainerFigure
*
* @see com.sybase.stf.gem.diagram.editor.figures.IContainerFigure#getLayer(java.lang.Object)
*/
public Layer getLayer(Object key) {
if (windowFigure != null && windowFigure.isVisible())
return windowFigure.getLayer(key);
return null;
}
}