/******************************************************************************* * Copyright (c) 2009 the CHISEL group and contributors. * 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: * Del Myers -- initial API and implementation *******************************************************************************/ package org.eclipse.zest.custom.sequence.figures; import java.util.List; import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.Figure; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.LayoutManager; import org.eclipse.draw2d.MouseEvent; import org.eclipse.draw2d.MouseListener; import org.eclipse.draw2d.MouseMotionListener; import org.eclipse.draw2d.PolylineDecoration; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.widgets.Display; /** * A figure that holds children in a sash-form way. * @author Del Myers */ public class SashFigure extends Figure { private boolean isHorizontal; private boolean drawBars; private SashBarMouseListener sashBarMouseListener; protected class SashBarFigure extends Figure { private boolean backArrows; private int index; private IFigure connectedFigure; /* (non-Javadoc) * @see org.eclipse.draw2d.Figure#paintClientArea(org.eclipse.draw2d.Graphics) */ @Override protected void paintClientArea(Graphics graphics) { if (!drawBars) return; double initialRotation = (isHorizontal) ? 0 : Math.PI/2; PolylineDecoration d = new PolylineDecoration(); if (getConnectedFigure() != null) { backArrows = getConnectedFigure().getBounds().isEmpty(); } int translate = 3; if (!backArrows) { initialRotation += Math.PI; translate = 0; } Rectangle bounds = getClientArea().getCopy(); graphics.pushState(); graphics.setBackgroundColor(Display.getCurrent().getSystemColor((SWT.COLOR_WIDGET_BACKGROUND))); graphics.fillRectangle(bounds); graphics.setForegroundColor(ColorConstants.black); d.setScale(3, 3); //d.setReferencePoint(d.getBounds().getCenter()); d.setRotation(initialRotation); Point center = bounds.getCenter(); if (isHorizontal) { d.setLocation(new Point(bounds.x + translate, center.y -8)); } else { d.setLocation(new Point(center.x-8, bounds.y + translate)); } PointList ps = d.getPoints(); graphics.setLineWidth(2); graphics.drawPolyline(ps); if (isHorizontal) { ps.translate(0,8); } else { ps.translate(8, 0); } graphics.drawPolyline(ps); graphics.popState(); } protected void setBackArrows(boolean back) { if (this.backArrows == back) return; this.backArrows = back; repaint(); } protected void setIndex(int index) { this.index = index; } protected int getIndex() { return this.index; } protected void setConnectedFigure(IFigure figure) { this.connectedFigure = figure; } protected IFigure getConnectedFigure() { return connectedFigure; } } IFigure mouseSource = null; Point lastPoint = null; private class SashBarMouseListener implements MouseListener, MouseMotionListener { /* (non-Javadoc) * @see org.eclipse.draw2d.MouseListener#mouseDoubleClicked(org.eclipse.draw2d.MouseEvent) */ public void mouseDoubleClicked(MouseEvent me) { if (me.getSource() instanceof SashBarFigure && me.button == 1) { toggle(((SashBarFigure)me.getSource()).getConnectedFigure()); } } /* (non-Javadoc) * @see org.eclipse.draw2d.MouseListener#mousePressed(org.eclipse.draw2d.MouseEvent) */ public void mousePressed(MouseEvent me) { if (me.button == 1) { mouseSource = (IFigure) me.getSource(); lastPoint = me.getLocation().getCopy(); mouseSource.translateToAbsolute(lastPoint); me.consume(); } } /* (non-Javadoc) * @see org.eclipse.draw2d.MouseListener#mouseReleased(org.eclipse.draw2d.MouseEvent) */ public void mouseReleased(MouseEvent me) { if (me.button == 1) { mouseSource = null; lastPoint = null; me.consume(); } } /* (non-Javadoc) * @see org.eclipse.draw2d.MouseMotionListener#mouseDragged(org.eclipse.draw2d.MouseEvent) */ public void mouseDragged(MouseEvent me) { if (mouseSource instanceof SashBarFigure) { SashBarFigure bar = (SashBarFigure) mouseSource; int diff = 0; if (isHorizontal) { diff = me.getLocation().x - lastPoint.x; } else { diff = me.getLocation().y - lastPoint.y; } lastPoint = me.getLocation().getCopy(); bar.translateToAbsolute(lastPoint); getSashLayout().moveSashBar(SashFigure.this, bar.getIndex(), diff); me.consume(); return; } } /* (non-Javadoc) * @see org.eclipse.draw2d.MouseMotionListener#mouseEntered(org.eclipse.draw2d.MouseEvent) */ public void mouseEntered(MouseEvent me) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.eclipse.draw2d.MouseMotionListener#mouseExited(org.eclipse.draw2d.MouseEvent) */ public void mouseExited(MouseEvent me) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.eclipse.draw2d.MouseMotionListener#mouseHover(org.eclipse.draw2d.MouseEvent) */ public void mouseHover(MouseEvent me) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.eclipse.draw2d.MouseMotionListener#mouseMoved(org.eclipse.draw2d.MouseEvent) */ public void mouseMoved(MouseEvent me) { if (mouseSource != null && (me.getState() & SWT.BUTTON1) == 0) { mouseSource = null; lastPoint = null; } } } /* (non-Javadoc) * @see org.eclipse.draw2d.Figure#handleMouseDragged(org.eclipse.draw2d.MouseEvent) */ @Override public void handleMouseDragged(MouseEvent me) { super.handleMouseDragged(me); } /* (non-Javadoc) * @see org.eclipse.draw2d.Figure#handleMouseMoved(org.eclipse.draw2d.MouseEvent) */ // @Override // public void handleMouseMoved(MouseEvent event) { // if ((event.getState() & SWT.BUTTON1) == 0) { // mouseSource = null; // lastPoint = null; // return; // } else if (mouseSource instanceof SashBarFigure) { // handleMouseDragged(event); // return; // } // super.handleMouseDragged(event); // } /* (non-Javadoc) * @see org.eclipse.draw2d.Figure#handleMouseReleased(org.eclipse.draw2d.MouseEvent) */ // @Override // public void handleMouseReleased(MouseEvent event) { // if (event.button == 1 && mouseSource instanceof SashBarFigure) { // mouseSource = null; // lastPoint = null; // return; // } // super.handleMouseReleased(event); // } /** * Creates a sash form with a horizontal layout. * Same as SashFigure(true, true, false). */ public SashFigure() { this (true, false); } /** * @param horizontal true for horizontal layout. False for vertical layout. * @param drawBorder draw a border surrounding the sashes. * @param drawBars draw sash bars. */ public SashFigure(boolean horizontal, boolean drawBars) { this.isHorizontal = horizontal; super.setLayoutManager(new SashLayout(horizontal)); this.drawBars = true; this.sashBarMouseListener = new SashBarMouseListener(); } /* (non-Javadoc) * @see org.eclipse.draw2d.Figure#add(org.eclipse.draw2d.IFigure, java.lang.Object, int) */ @Override public void add(IFigure figure, Object constraint, int index) { boolean addEnd = index == -1; if (addEnd) index = getChildren().size(); boolean addBarBefore = (index > 0); IFigure connected = (index > 0) ? (IFigure)getChildren().get(index-1) : figure; if (connected instanceof SashBarFigure) { connected = figure; addBarBefore = false; } SashBarFigure bar = null; if (getChildren().size() != 0) { bar = new SashBarFigure(); bar.setConnectedFigure(connected); bar.addMouseListener(sashBarMouseListener); bar.addMouseMotionListener(sashBarMouseListener); Cursor c = (isHorizontal) ? Display.getCurrent().getSystemCursor(SWT.CURSOR_SIZEW) : Display.getCurrent().getSystemCursor(SWT.CURSOR_SIZENS); bar.setCursor(c); } if (addBarBefore && bar != null) { super.add(bar, null, addEnd ? -1 : index); index++; } super.add(figure, constraint, addEnd ? -1 : index); index++; if (!addBarBefore && bar!= null) { super.add(bar, null, addEnd ? -1 : index); } reorderBars(); } /* (non-Javadoc) * @see org.eclipse.draw2d.Figure#remove(org.eclipse.draw2d.IFigure) */ @Override public void remove(IFigure figure) { if (figure instanceof SashBarFigure) return; int index = getChildren().indexOf(figure); if (index > 0) { //remove the sash IFigure sash = (IFigure) getChildren().get(index-1); super.remove(sash); } super.remove(figure); reorderBars(); } private void reorderBars() { for (int i = 0; i < getChildren().size(); i++) { IFigure child = (IFigure) getChildren().get(i); if (child instanceof SashBarFigure) { ((SashBarFigure)child).setIndex(i/2); } } } /* (non-Javadoc) * @see org.eclipse.draw2d.Figure#paintChildren(org.eclipse.draw2d.Graphics) */ @Override protected void paintChildren(Graphics graphics) { super.paintChildren(graphics); } /** * Layout managers are not allowed in sash figures. */ @Override public void setLayoutManager(LayoutManager manager) { } /** * Toggles the child figure between the "open" (size maximized) and "closed" * (size 0) state. */ public void toggle(IFigure child) { List<?> children = getChildren(); int i; for (i = 0; i < children.size(); i++) { IFigure next = (IFigure) children.get(i); if (next == child) break; } if (i >= children.size()) return; int size = getSashLayout().getSashBarSize(this, i); if (size > 0) { getSashLayout().moveSashBar(this, i, -size); } else { Dimension psize = child.getPreferredSize(); int newSize = (isHorizontal) ? psize.width : psize.height; getSashLayout().moveSashBar(this, i, newSize); } } private SashLayout getSashLayout() { return ((SashLayout)getLayoutManager()); } /** * @param figure */ public void maximize(IFigure child) { List<?> children = getChildren(); int i; for (i = 0; i < children.size(); i++) { IFigure next = (IFigure) children.get(i); if (next == child) break; } if (i >= children.size()) return; Dimension psize = child.getPreferredSize(); int newSize = (isHorizontal) ? psize.width : psize.height; newSize -= getSashLayout().getSashBarSize(this, i/2); if (newSize > 0) { getSashLayout().moveSashBar(this, i/2, newSize); } } public void minimize (IFigure child) { List<?> children = getChildren(); int i; for (i = 0; i < children.size(); i++) { IFigure next = (IFigure)children.get(i); if (next == child) break; } if (i >= children.size()) return; int size = getSashLayout().getSashBarSize(this, i/2); if (size > 0) { getSashLayout().moveSashBar(this, i/2, -size); } } }