| /******************************************************************************* |
| * Copyright (c) 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.pagedesigner.editpolicies; |
| |
| import java.util.List; |
| |
| import org.eclipse.draw2d.Figure; |
| import org.eclipse.draw2d.Graphics; |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.LineBorder; |
| import org.eclipse.draw2d.Locator; |
| import org.eclipse.draw2d.PositionConstants; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.PrecisionRectangle; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.gef.DragTracker; |
| import org.eclipse.gef.GraphicalEditPart; |
| import org.eclipse.gef.Handle; |
| import org.eclipse.gef.handles.AbstractHandle; |
| import org.eclipse.gef.tools.DragEditPartsTracker; |
| import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure; |
| import org.eclipse.jst.pagedesigner.css2.layout.FlowBox; |
| |
| /** |
| * @author mengbo |
| * @version 1.5 |
| */ |
| public class FragmentHandle extends AbstractHandle implements Handle { |
| public FragmentHandle(GraphicalEditPart owner) { |
| super(owner, new FragmentLocator()); |
| this.setOpaque(false); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.draw2d.IFigure#paint(org.eclipse.draw2d.Graphics) |
| */ |
| public void paint(Graphics graphics) { |
| graphics.setClip(this.getBounds().getCopy().expand(7, 7)); |
| super.paint(graphics); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.gef.handles.AbstractHandle#createDragTracker() |
| */ |
| protected DragTracker createDragTracker() { |
| DragEditPartsTracker tracker = new DragEditPartsTracker(getOwner()); |
| tracker.setDefaultCursor(getCursor()); |
| return tracker; |
| } |
| |
| public void refresh() { |
| // TODO: not ref Insets insets = getOwnerFigure().getInsets(); |
| // TODO: not ref Rectangle bounds; |
| |
| // set the bounds of this figure, so it could cover all children. |
| bounds = getOwnerFigure().getBounds(); |
| bounds = new PrecisionRectangle(bounds.getResized(-1, -1)); |
| getOwnerFigure().translateToAbsolute(bounds); |
| this.translateToRelative(bounds); |
| this.setBounds(bounds); |
| |
| this.removeAll(); |
| // ok, recreate all children. |
| CSSFigure cssfigure = (CSSFigure) getOwner().getFigure(); |
| List fragments = cssfigure.getFragmentsForRead(); |
| for (int i = 0, size = fragments.size(); i < size; i++) { |
| // the rectangle. |
| Figure childFigure = new BorderFigure(); |
| childFigure.setBorder(new LineBorder(1)); |
| this.add(childFigure); |
| |
| FlowBox box = (FlowBox) fragments.get(i); |
| Rectangle rect = new Rectangle(box._x, box._y, box.getWidth(), box |
| .getHeight()); |
| cssfigure.translateToAbsolute(rect); |
| |
| childFigure.translateToRelative(rect); |
| childFigure.setBounds(rect); |
| |
| createCornerHandles(cssfigure, box); |
| } |
| } |
| |
| /** |
| * |
| */ |
| private void createCornerHandles(CSSFigure reference, FlowBox referencebox) { |
| createHandle(reference, referencebox, PositionConstants.SOUTH_EAST); |
| createHandle(reference, referencebox, PositionConstants.SOUTH_WEST); |
| createHandle(reference, referencebox, PositionConstants.NORTH_WEST); |
| createHandle(reference, referencebox, PositionConstants.NORTH_EAST); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.draw2d.IFigure#containsPoint(int, int) |
| */ |
| public boolean containsPoint(int x, int y) { |
| List children = this.getChildren(); |
| for (int i = 0, n = children.size(); i < n; i++) { |
| if (((IFigure) children.get(i)).containsPoint(x, y)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * @param north_east |
| */ |
| private void createHandle(CSSFigure reference, FlowBox referencebox, |
| int location) { |
| double relativeX, relativeY; |
| switch (location & PositionConstants.NORTH_SOUTH) { |
| case PositionConstants.NORTH: |
| relativeY = 0; |
| break; |
| case PositionConstants.SOUTH: |
| relativeY = 1.0; |
| break; |
| default: |
| relativeY = 0.5; |
| } |
| |
| switch (location & PositionConstants.EAST_WEST) { |
| case PositionConstants.WEST: |
| relativeX = 0; |
| break; |
| case PositionConstants.EAST: |
| relativeX = 1.0; |
| break; |
| default: |
| relativeX = 0.5; |
| } |
| |
| FragmentCornerHandle target = new FragmentCornerHandle(getOwner()); |
| this.add(target); |
| |
| // for corner small box. |
| Rectangle targetBounds = new Rectangle(referencebox._x, |
| referencebox._y, referencebox.getWidth(), referencebox |
| .getHeight()); |
| targetBounds = new PrecisionRectangle(targetBounds); |
| reference.translateToAbsolute(targetBounds); |
| target.translateToRelative(targetBounds); |
| // targetBounds.resize(1, 1); |
| |
| Dimension targetSize = target.getPreferredSize(); |
| |
| targetBounds.x += (int) (targetBounds.width * relativeX - ((targetSize.width + 1) / 2)); |
| targetBounds.y += (int) (targetBounds.height * relativeY - ((targetSize.height + 1) / 2)); |
| targetBounds.setSize(targetSize); |
| target.setBounds(targetBounds); |
| } |
| |
| public static class FragmentLocator implements Locator { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.draw2d.Locator#relocate(org.eclipse.draw2d.IFigure) |
| */ |
| public void relocate(IFigure target) { |
| ((FragmentHandle) target).refresh(); |
| } |
| } |
| |
| public static class BorderFigure extends Figure { |
| public static final int INNER_PAD = 2; |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.draw2d.IFigure#containsPoint(int, int) |
| */ |
| public boolean containsPoint(int x, int y) { |
| if (!super.containsPoint(x, y)) |
| return false; |
| return !Rectangle.SINGLETON.setBounds(getBounds()).shrink( |
| INNER_PAD, INNER_PAD).contains(x, y); |
| } |
| } |
| } |