blob: 5e5de0fbe19084a65ab5994a578dc9a8ec19bc7e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2010 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.getSINGLETON();
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;
}
}
}