/******************************************************************************* * Copyright (c) 2003, 2005 IBM Corporation 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.gef.internal.ui.rulers; import java.beans.PropertyChangeEvent; import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.RangeModel; import org.eclipse.draw2d.Viewport; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.AutoexposeHelper; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.editparts.SimpleRootEditPart; import org.eclipse.gef.editparts.ViewportAutoexposeHelper; /** * RootEditPart for a ruler. * * @author Pratik Shah * @since 3.0 */ public class RulerRootEditPart extends SimpleRootEditPart { private static final Insets VERTICAL_THRESHOLD = new Insets(18, 0, 18, 0); private static final Insets HORIZONTAL_THRESHOLD = new Insets(0, 18, 0, 18); private boolean horizontal; /** * Constructor * * @param isHorzontal whether or not the corresponding model ruler is horizontal */ public RulerRootEditPart(boolean isHorzontal) { super(); horizontal = isHorzontal; } /** * @see org.eclipse.gef.editparts.AbstractEditPart#addChildVisual(org.eclipse.gef.EditPart, int) */ protected void addChildVisual(EditPart childEditPart, int index) { IFigure child = ((GraphicalEditPart)childEditPart).getFigure(); getViewport().setContents(child); } /** * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure() */ protected IFigure createFigure() { return new RulerViewport(); } /** * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) */ public Object getAdapter(Class adapter) { if (adapter == AutoexposeHelper.class) { if (((RulerEditPart)getContents()).isHorizontal()) return new ViewportAutoexposeHelper(this, HORIZONTAL_THRESHOLD); return new ViewportAutoexposeHelper(this, VERTICAL_THRESHOLD); } return super.getAdapter(adapter); } /** * Convenience method to get to the viewport * @return the figure cast as a viewport */ protected Viewport getViewport() { return (Viewport)getFigure(); } /** * @see org.eclipse.gef.editparts.AbstractEditPart#removeChildVisual(org.eclipse.gef.EditPart) */ protected void removeChildVisual(EditPart childEditPart) { getViewport().setContents(null); } /** * A RulerViewport shares a RangeModel with that of the primary GraphicalViewer. The * shared RangeModel is set on this viewport externally by a client (in this case, * RulerComposite). * * @author Pratik Shah * @since 3.0 */ public class RulerViewport extends Viewport { /** * Constructor */ public RulerViewport() { super(true); setLayoutManager(null); // The range model that's not shared is initialized such that it can't scroll // anymore (otherwise, CTRL + SHIFT + ARROW scrolls it). RangeModel bogusRangeModel; if (horizontal) bogusRangeModel = getVerticalRangeModel(); else bogusRangeModel = getHorizontalRangeModel(); bogusRangeModel.setMinimum(0); bogusRangeModel.setMaximum(100); bogusRangeModel.setValue(0); bogusRangeModel.setExtent(100); } /** * This is the method that does the actual layout. We don't want a layout to occur * when layout() is invoked, rather when something changes in the shared RangeModel. * @param force if <code>true</code>, the contents will be resized and * revalidated; otherwise, just a repaint will occur. */ protected void doLayout(boolean force) { repaint(); /* * @TODO:Pratik It seems you don't really need this force argument. Those that * invoke doLayout(false) can invoke repaint() themselves. doLayout() should * just layout. */ if (force) { RangeModel rModel; if (horizontal) rModel = getHorizontalRangeModel(); else rModel = getVerticalRangeModel(); Rectangle contentBounds = Rectangle.SINGLETON; if (horizontal) { contentBounds.y = 0; contentBounds.x = rModel.getMinimum(); contentBounds.height = this.getContents().getPreferredSize().height; contentBounds.width = rModel.getMaximum() - rModel.getMinimum(); } else { contentBounds.y = rModel.getMinimum(); contentBounds.x = 0; contentBounds.height = rModel.getMaximum() - rModel.getMinimum(); contentBounds.width = this.getContents().getPreferredSize().width; } if (!this.getContents().getBounds().equals(contentBounds)) { this.getContents().setBounds(contentBounds); this.getContents().revalidate(); } } } /** * @see org.eclipse.draw2d.IFigure#getPreferredSize(int, int) */ public Dimension getPreferredSize(int wHint, int hHint) { if (this.getContents() == null) return new Dimension(); Dimension pSize = this.getContents().getPreferredSize(wHint, hHint); if (horizontal) { RangeModel rModel = getHorizontalRangeModel(); pSize.width = rModel.getMaximum() - rModel.getMinimum(); } else { RangeModel rModel = getVerticalRangeModel(); pSize.height = rModel.getMaximum() - rModel.getMinimum(); } return pSize.expand(getInsets().getWidth(), getInsets().getHeight()); } /** * Since the RangeModel is shared with that of the editor's, a RulerViewport should * not adjust it. * * @see org.eclipse.draw2d.Viewport#readjustScrollBars() */ protected void readjustScrollBars() { } /** * @see org.eclipse.draw2d.Figure#paintBorder(org.eclipse.draw2d.Graphics) */ protected void paintBorder(Graphics graphics) { super.paintBorder(graphics); if (this.getContents() != null && ((RulerFigure)this.getContents()).getDrawFocus()) { Rectangle focusBounds = getBounds().getCopy(); if (((RulerFigure)this.getContents()).isHorizontal()) { focusBounds.resize(-2, -4); focusBounds.x++; } else { focusBounds.resize(-4, -2); focusBounds.y++; } graphics.setForegroundColor(ColorConstants.black); graphics.setBackgroundColor(ColorConstants.white); graphics.drawFocus(focusBounds); } } /** * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent event) { if (this.getContents() != null && event.getSource() instanceof RangeModel) { String property = event.getPropertyName(); doLayout(RangeModel.PROPERTY_MAXIMUM.equals(property) || RangeModel.PROPERTY_MINIMUM.equals(property) || RangeModel.PROPERTY_VALUE.equals(property)); } } /** * @see org.eclipse.draw2d.Viewport#setContents(org.eclipse.draw2d.IFigure) */ public void setContents(IFigure figure) { super.setContents(figure); // Need to layout when contents change if (this.getContents() != null) doLayout(true); } /** * RulerViewport uses local coordinates. * @see org.eclipse.draw2d.Figure#useLocalCoordinates() */ protected boolean useLocalCoordinates() { return true; } } }