Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 67116 Details for
Bug 186859
Expose MarqueeSelectionTool api
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
Increased visibility
MarqueeSelectionTool.java (text/plain), 15.74 KB, created by
Pratik Shah
on 2007-05-14 14:48:42 EDT
(
hide
)
Description:
Increased visibility
Filename:
MIME Type:
Creator:
Pratik Shah
Created:
2007-05-14 14:48:42 EDT
Size:
15.74 KB
patch
obsolete
>/******************************************************************************* > * Copyright (c) 2000, 2007 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 > *******************************************************************************/ > >import java.util.ArrayList; >import java.util.Collection; >import java.util.HashSet; >import java.util.Iterator; >import java.util.LinkedHashSet; >import java.util.List; >import java.util.Set; > >import org.eclipse.swt.SWT; >import org.eclipse.swt.events.KeyEvent; >import org.eclipse.swt.widgets.Display; > >import org.eclipse.draw2d.ColorConstants; >import org.eclipse.draw2d.Cursors; >import org.eclipse.draw2d.Figure; >import org.eclipse.draw2d.Graphics; >import org.eclipse.draw2d.IFigure; >import org.eclipse.draw2d.PolylineConnection; >import org.eclipse.draw2d.geometry.Rectangle; > >import org.eclipse.gef.ConnectionEditPart; >import org.eclipse.gef.EditPart; >import org.eclipse.gef.EditPartViewer; >import org.eclipse.gef.GraphicalEditPart; >import org.eclipse.gef.GraphicalViewer; >import org.eclipse.gef.Request; >import org.eclipse.gef.RequestConstants; >import org.eclipse.gef.tools.AbstractTool; > >import org.eclipse.jface.viewers.StructuredSelection; > >/** > * A Tool which selects multiple objects inside a rectangular area of a Graphical Viewer. > * If the SHIFT key is pressed at the beginning of the drag, the enclosed items will be > * appended to the current selection. If the MOD1 key is pressed at the beginning of > * the drag, the enclosed items will have their selection state inverted. > * <P> > * By default, only editparts whose figure's are on the primary layer will be considered > * within the enclosed rectangle. > */ >public class MarqueeSelectionTool > extends AbstractTool >{ > >/** > * The property to be used in {@link AbstractTool#setProperties(java.util.Map)} for > * {@link #setMarqueeBehavior(int)}. > */ >public static final Object PROPERTY_MARQUEE_BEHAVIOR = "marqueeBehavior"; //$NON-NLS-1$ > >/** > * This behaviour selects nodes completely encompassed by the marquee rectangle. This > * is the default behaviour for this tool. > * @since 3.1 > */ >public static final int BEHAVIOR_NODES_CONTAINED = new Integer(1).intValue(); >/** > * This behaviour selects connections that intersect the marquee rectangle. > * @since 3.1 > */ >public static final int BEHAVIOR_CONNECTIONS_TOUCHED = new Integer(2).intValue(); >/** > * This behaviour selects nodes completely encompassed by the marquee rectangle, and > * all connections between those nodes. > * @since 3.1 > */ >public static final int BEHAVIOR_NODES_AND_CONNECTIONS = new Integer(3).intValue(); > >protected static final int DEFAULT_MODE = 0; >protected static final int TOGGLE_MODE = 1; >protected static final int APPEND_MODE = 2; > >private Figure marqueeRectangleFigure; >private Set allChildren = new HashSet(); >private Collection selectedEditParts; >private Request targetRequest; >private int marqueeBehavior = BEHAVIOR_NODES_CONTAINED; >protected int mode; > >protected static final Request MARQUEE_REQUEST = > new Request(RequestConstants.REQ_SELECTION); > >/** > * Creates a new MarqueeSelectionTool of default type {@link #BEHAVIOR_NODES_CONTAINED}. > */ >public MarqueeSelectionTool() { > setDefaultCursor(Cursors.CROSS); > setUnloadWhenFinished(false); >} > >/** > * @see org.eclipse.gef.tools.AbstractTool#applyProperty(java.lang.Object, java.lang.Object) > */ >protected void applyProperty(Object key, Object value) { > if (PROPERTY_MARQUEE_BEHAVIOR.equals(key)) { > if (value instanceof Integer) > setMarqueeBehavior(((Integer)value).intValue()); > return; > } > super.applyProperty(key, value); >} > >private void calculateConnections(Collection newSelections, Collection deselections) { > // determine the currently selected nodes minus the ones that are to be deselected > Collection currentNodes = new HashSet(); > if (getSelectionMode() != DEFAULT_MODE) { // everything is deselected in default mode > Iterator iter = getCurrentViewer().getSelectedEditParts().iterator(); > while (iter.hasNext()) { > EditPart selected = (EditPart) iter.next(); > if (!(selected instanceof ConnectionEditPart) > && !deselections.contains(selected)) > currentNodes.add(selected); > } > } > // add new connections to be selected to newSelections > Collection connections = new ArrayList(); > for (Iterator nodes = newSelections.iterator(); nodes.hasNext();) { > GraphicalEditPart node = (GraphicalEditPart) nodes.next(); > for (Iterator itr = node.getSourceConnections().iterator(); itr.hasNext();) { > ConnectionEditPart sourceConn = (ConnectionEditPart) itr.next(); > if (sourceConn.getSelected() == EditPart.SELECTED_NONE > && (newSelections.contains(sourceConn.getTarget()) > || currentNodes.contains(sourceConn.getTarget()))) > connections.add(sourceConn); > } > for (Iterator itr = node.getTargetConnections().iterator(); itr.hasNext();) { > ConnectionEditPart targetConn = (ConnectionEditPart) itr.next(); > if (targetConn.getSelected() == EditPart.SELECTED_NONE > && (newSelections.contains(targetConn.getSource()) > || currentNodes.contains(targetConn.getSource()))) > connections.add(targetConn); > } > } > newSelections.addAll(connections); > // add currently selected connections that are to be deselected to deselections > connections = new HashSet(); > for (Iterator nodes = deselections.iterator(); nodes.hasNext();) { > GraphicalEditPart node = (GraphicalEditPart) nodes.next(); > for (Iterator itr = node.getSourceConnections().iterator(); itr.hasNext();) { > ConnectionEditPart sourceConn = (ConnectionEditPart) itr.next(); > if (sourceConn.getSelected() != EditPart.SELECTED_NONE) > connections.add(sourceConn); > } > for (Iterator itr = node.getTargetConnections().iterator(); itr.hasNext();) { > ConnectionEditPart targetConn = (ConnectionEditPart) itr.next(); > if (targetConn.getSelected() != EditPart.SELECTED_NONE) > connections.add(targetConn); > } > } > deselections.addAll(connections); >} > >private void calculateNewSelection(Collection newSelections, Collection deselections) { > Rectangle marqueeRect = getMarqueeSelectionRectangle(); > for (Iterator itr = getAllChildren().iterator(); itr.hasNext();) { > GraphicalEditPart child = (GraphicalEditPart)itr.next(); > IFigure figure = child.getFigure(); > if (!child.isSelectable() > || child.getTargetEditPart(MARQUEE_REQUEST) != child > || !isFigureVisible(figure) > || !figure.isShowing()) > continue; > > Rectangle r = figure.getBounds().getCopy(); > figure.translateToAbsolute(r); > boolean included = false; > if (child instanceof ConnectionEditPart && marqueeRect.intersects(r)) { > Rectangle relMarqueeRect = Rectangle.SINGLETON; > figure.translateToRelative(relMarqueeRect.setBounds(marqueeRect)); > included = ((PolylineConnection)figure).getPoints().intersects(relMarqueeRect); > } else > included = marqueeRect.contains(r); > > if (included) > if (child.getSelected() == EditPart.SELECTED_NONE > || getSelectionMode() != TOGGLE_MODE) > newSelections.add(child); > else > deselections.add(child); > } > > if (marqueeBehavior == BEHAVIOR_NODES_AND_CONNECTIONS) > calculateConnections(newSelections, deselections); >} > >private Request createTargetRequest() { > return MARQUEE_REQUEST; >} > >/** > * Erases feedback if necessary and puts the tool into the terminal state. > */ >public void deactivate() { > if (isInState(STATE_DRAG_IN_PROGRESS)) { > eraseMarqueeFeedback(); > eraseTargetFeedback(); > } > super.deactivate(); > allChildren.clear(); > setState(STATE_TERMINAL); >} > >protected void eraseMarqueeFeedback() { > if (marqueeRectangleFigure != null) { > removeFeedback(marqueeRectangleFigure); > marqueeRectangleFigure = null; > } >} > >protected void eraseTargetFeedback() { > if (selectedEditParts == null) > return; > Iterator oldEditParts = selectedEditParts.iterator(); > while (oldEditParts.hasNext()) { > EditPart editPart = (EditPart)oldEditParts.next(); > editPart.eraseTargetFeedback(getTargetRequest()); > } >} > >protected Set getAllChildren() { > if (allChildren.isEmpty()) > getAllChildren(getCurrentViewer().getRootEditPart(), allChildren); > return allChildren; >} > >private void getAllChildren(EditPart editPart, Set allChildren) { > List children = editPart.getChildren(); > for (int i = 0; i < children.size(); i++) { > GraphicalEditPart child = (GraphicalEditPart) children.get(i); > if (marqueeBehavior == BEHAVIOR_NODES_CONTAINED > || marqueeBehavior == BEHAVIOR_NODES_AND_CONNECTIONS) > allChildren.add(child); > if (marqueeBehavior == BEHAVIOR_CONNECTIONS_TOUCHED) { > allChildren.addAll(child.getSourceConnections()); > allChildren.addAll(child.getTargetConnections()); > } > getAllChildren(child, allChildren); > } >} > >/** > * @see org.eclipse.gef.tools.AbstractTool#getCommandName() > */ >protected String getCommandName() { > return REQ_SELECTION; >} > >/** > * @see org.eclipse.gef.tools.AbstractTool#getDebugName() > */ >protected String getDebugName() { > return "Marquee Tool: " + marqueeBehavior;//$NON-NLS-1$ >} > >private IFigure getMarqueeFeedbackFigure() { > if (marqueeRectangleFigure == null) { > marqueeRectangleFigure = new MarqueeRectangleFigure(); > addFeedback(marqueeRectangleFigure); > } > return marqueeRectangleFigure; >} > >protected Rectangle getMarqueeSelectionRectangle() { > return new Rectangle(getStartLocation(), getLocation()); >} > >protected int getSelectionMode() { > return mode; >} > >private Request getTargetRequest() { > if (targetRequest == null) > targetRequest = createTargetRequest(); > return targetRequest; >} > >/** > * @see org.eclipse.gef.tools.AbstractTool#handleButtonDown(int) > */ >protected boolean handleButtonDown(int button) { > if (!isGraphicalViewer()) > return true; > if (button != 1) { > setState(STATE_INVALID); > handleInvalidInput(); > } > if (stateTransition(STATE_INITIAL, STATE_DRAG_IN_PROGRESS)) > if (getCurrentInput().isModKeyDown(SWT.MOD1)) > setSelectionMode(TOGGLE_MODE); > else if (getCurrentInput().isShiftKeyDown()) > setSelectionMode(APPEND_MODE); > else > setSelectionMode(DEFAULT_MODE); > return true; >} > >/** > * @see org.eclipse.gef.tools.AbstractTool#handleButtonUp(int) > */ >protected boolean handleButtonUp(int button) { > if (stateTransition(STATE_DRAG_IN_PROGRESS, STATE_TERMINAL)) { > eraseTargetFeedback(); > eraseMarqueeFeedback(); > performMarqueeSelect(); > } > handleFinished(); > return true; >} > >/** > * @see org.eclipse.gef.tools.AbstractTool#handleDragInProgress() > */ >protected boolean handleDragInProgress() { > if (isInState(STATE_DRAG | STATE_DRAG_IN_PROGRESS)) { > showMarqueeFeedback(); > eraseTargetFeedback(); > calculateNewSelection(selectedEditParts = new ArrayList(), new ArrayList()); > showTargetFeedback(); > } > return true; >} > >/** > * @see org.eclipse.gef.tools.AbstractTool#handleFocusLost() > */ >protected boolean handleFocusLost() { > if (isInState(STATE_DRAG | STATE_DRAG_IN_PROGRESS)) { > handleFinished(); > return true; > } > return false; >} > >/** > * This method is called when mouse or keyboard input is invalid and erases the feedback. > * @return <code>true</code> > */ >protected boolean handleInvalidInput() { > eraseTargetFeedback(); > eraseMarqueeFeedback(); > return true; >} > >/** > * Handles high-level processing of a key down event. > * KeyEvents are forwarded to the current viewer's {@link KeyHandler}, > * via {@link KeyHandler#keyPressed(KeyEvent)}. > * @see AbstractTool#handleKeyDown(KeyEvent) > */ >public boolean handleKeyDown(KeyEvent e) { > if (super.handleKeyDown(e)) > return true; > if (getCurrentViewer().getKeyHandler() != null) > return getCurrentViewer().getKeyHandler().keyPressed(e); > return false; >} > >protected boolean isFigureVisible(IFigure fig) { > Rectangle figBounds = fig.getBounds().getCopy(); > IFigure walker = fig.getParent(); > while (!figBounds.isEmpty() && walker != null) { > walker.translateToParent(figBounds); > figBounds.intersect(walker.getBounds()); > walker = walker.getParent(); > } > return !figBounds.isEmpty(); >} > >private boolean isGraphicalViewer() { > return getCurrentViewer() instanceof GraphicalViewer; >} > >/** > * MarqueeSelectionTool is only interested in GraphicalViewers, not TreeViewers. > * @see org.eclipse.gef.tools.AbstractTool#isViewerImportant(org.eclipse.gef.EditPartViewer) > */ >protected boolean isViewerImportant(EditPartViewer viewer) { > return viewer instanceof GraphicalViewer; >} > >protected void performMarqueeSelect() { > EditPartViewer viewer = getCurrentViewer(); > Collection newSelections = new LinkedHashSet(), deselections = new HashSet(); > calculateNewSelection(newSelections, deselections); > if (getSelectionMode() != DEFAULT_MODE) { > newSelections.addAll(viewer.getSelectedEditParts()); > newSelections.removeAll(deselections); > } > viewer.setSelection(new StructuredSelection(newSelections.toArray())); >} > >/** > * Sets the type of parts that this tool will select. This method should only be > * invoked once: when the tool is being initialized. > * @param type {@link #BEHAVIOR_CONNECTIONS_TOUCHED} or {@link #BEHAVIOR_NODES_CONTAINED} > * or {@link #BEHAVIOR_NODES_AND_CONNECTIONS} > * @since 3.1 > */ >public void setMarqueeBehavior(int type) { > if (type != BEHAVIOR_CONNECTIONS_TOUCHED && type != BEHAVIOR_NODES_CONTAINED > && type != BEHAVIOR_NODES_AND_CONNECTIONS) > throw new IllegalArgumentException("Invalid marquee behaviour specified."); //$NON-NLS-1$ > marqueeBehavior = type; >} > >private void setSelectionMode(int mode) { > this.mode = mode; >} > >/** > * @see org.eclipse.gef.Tool#setViewer(org.eclipse.gef.EditPartViewer) > */ >public void setViewer(EditPartViewer viewer) { > if (viewer == getCurrentViewer()) > return; > super.setViewer(viewer); > if (viewer instanceof GraphicalViewer) > setDefaultCursor(Cursors.CROSS); > else > setDefaultCursor(Cursors.NO); >} > >protected void showMarqueeFeedback() { > Rectangle rect = getMarqueeSelectionRectangle().getCopy(); > getMarqueeFeedbackFigure().translateToRelative(rect); > getMarqueeFeedbackFigure().setBounds(rect); >} > >private void showTargetFeedback() { > for (Iterator itr = selectedEditParts.iterator(); itr.hasNext();) { > EditPart editPart = (EditPart) itr.next(); > editPart.showTargetFeedback(getTargetRequest()); > } >} > >class MarqueeRectangleFigure > extends Figure { > > private static final int DELAY = 110; //animation delay in millisecond > private int offset = 0; > private boolean schedulePaint = true; > /** > * @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics) > */ > protected void paintFigure(Graphics graphics) { > Rectangle bounds = getBounds().getCopy(); > graphics.translate(getLocation()); > > graphics.setXORMode(true); > graphics.setForegroundColor(ColorConstants.white); > graphics.setBackgroundColor(ColorConstants.black); > > graphics.setLineStyle(Graphics.LINE_DOT); > > int[] points = new int[6]; > > points[0] = 0 + offset; > points[1] = 0; > points[2] = bounds.width - 1; > points[3] = 0; > points[4] = bounds.width - 1; > points[5] = bounds.height - 1; > > graphics.drawPolyline(points); > > points[0] = 0; > points[1] = 0 + offset; > points[2] = 0; > points[3] = bounds.height - 1; > points[4] = bounds.width - 1; > points[5] = bounds.height - 1; > > graphics.drawPolyline(points); > > graphics.translate(getLocation().getNegated()); > > if (schedulePaint) > Display.getCurrent().timerExec(DELAY, new Runnable() { > public void run() { > offset++; > if (offset > 5) > offset = 0; > > schedulePaint = true; > repaint(); > } > }); > > schedulePaint = false; > } > >} > >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 186859
: 67116