Java tutorial
/***************************************************************************** * Copyright (c) 2009 g-Eclipse Consortium * 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 * * Initial development of the original code was made for the * g-Eclipse project founded by European Union * project number: FP6-IST-034327 http://www.geclipse.eu/ * * Contributors: * Thomas Koeckerbauer - MNM-Team, LMU Munich, code cleanup of logical and physical trace viewers *****************************************************************************/ package eu.geclipse.traceview.internal; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.LinkedList; import java.util.Set; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.ui.PartInitException; import eu.geclipse.traceview.IProcess; public abstract class AbstractGraphMouseAdapter implements MouseListener, MouseMoveListener { protected AbstractGraphVisualization graph; private int vRulerSelection; private Cursor moveProcCursor; private Rectangle selectionRect; protected AbstractGraphMouseAdapter(final AbstractGraphVisualization graph) { this.graph = graph; this.moveProcCursor = new Cursor(this.graph.getDisplay(), SWT.CURSOR_SIZENS); } public void mouseDoubleClick(MouseEvent e) { int graphHeight = this.graph.getClientArea().height - 30; if (e.x > 0 && e.y > 0 && e.x < 30 && e.y < graphHeight) { int y = getLineNumber(e.y); if (y != -1) { boolean[] hideProcs = this.graph.getHideProcess(); Set<Integer> procs = this.graph.getLineToProcessMapping().get(y); for (Integer proc : procs) { hideProcs[proc.intValue()] ^= true; } this.graph.setHideProcess(hideProcs); } } } public void mouseMove(final MouseEvent e) { if ((e.stateMask & SWT.BUTTON1) != 0) { if (this.vRulerSelection != -1) { GC rulerGC = new GC(this.graph); this.graph.getEventGraphPaintListener().drawVRulerWithMovingLine(rulerGC, this.vRulerSelection, e.y); rulerGC.dispose(); } if (selectionRect != null) { this.graph.getEventGraphPaintListener().updateSelectionRectangle(selectionRect, e); } } else if ((e.stateMask & SWT.BUTTON1) == 0) { updateMouseCursor(e); } } protected void updateMouseCursor(final MouseEvent e) { int graphHeight = this.graph.getClientArea().height - 30; if (e.x > 0 && e.y > 0 && e.x < 30 && e.y < graphHeight && getLineNumber(e.y) != -1) { this.graph.setCursor(this.moveProcCursor); } else { this.graph.setCursor(null); } } public void mouseUp(MouseEvent e) { checkVRuler(e.x, e.y, false); updateMouseCursor(e); if (selectionRect != null) { this.graph.getEventGraphPaintListener().updateSelectionRectangle(selectionRect, null); Object[] objs = getObjectsForArea(selectionRect); List<Object> objList = Arrays.asList(objs); if (!objList.isEmpty()) { updateSelection(e, objList); this.graph.redraw(); } selectionRect = null; } } private void updateSelection(final MouseEvent e, final List<Object> newSelection) { try { ISelection selection = null; ISelectionProvider selectionProvider = Activator.getDefault().getWorkbench().getActiveWorkbenchWindow() .getActivePage().showView("eu.geclipse.traceview.views.TraceView").getSite() .getSelectionProvider(); StructuredSelection oldSelection = (StructuredSelection) selectionProvider.getSelection(); if ((e.stateMask & SWT.CTRL) != 0 && oldSelection != null) { List oldSelectionList = new ArrayList(oldSelection.toList()); if (!oldSelectionList.containsAll(newSelection)) { if (e.button == 1) { for (Object obj : newSelection) { if (!oldSelectionList.contains(obj)) oldSelectionList.add(obj); } selection = new StructuredSelection(oldSelectionList); } } else { selection = new StructuredSelection(oldSelectionList); } } if (selection == null) { selection = new StructuredSelection(newSelection); } selectionProvider.setSelection(selection); } catch (PartInitException exception) { Activator.logException(exception); } } public void mouseDown(final MouseEvent e) { checkVRuler(e.x, e.y, true); Object[] objs = getObjectsForPosition(e.x, e.y, (e.stateMask & SWT.CTRL) == 0); if (objs.length != 0 && (e.button == 1 || e.button == 3)) { List<Object> objList = Arrays.asList(objs); updateSelection(e, objList); this.graph.redraw(); } if (e.button == 1 && this.graph.getEventGraphPaintListener().isInGraphArea(e.x, e.y)) { selectionRect = new Rectangle(e.x, e.y, 0, 0); } } protected int getLineNumber(final int yPos) { return getLineNumber(yPos, false, false); } protected int getLineNumber(final int yPos, boolean areaBelowProcess, boolean mapAreaBelowLastLineToLastLine) { int yOffset = this.graph.getEventGraphPaintListener().getYOffset(); int eventSize = this.graph.getEventGraphPaintListener().getEventSize(); int vSpace = this.graph.getEventGraphPaintListener().getVSpace(); int numProcLines = this.graph.getLineToProcessMapping().size(); int processLine = -1; int tmp = yPos + yOffset - eventSize / 2; if (areaBelowProcess) { if (tmp < 0) processLine = -1; else processLine = tmp / vSpace; } else { if (tmp % vSpace <= eventSize / 2) { processLine = tmp / vSpace; } if (vSpace - (tmp % vSpace) <= eventSize / 2) { processLine = tmp / vSpace + 1; } } if (processLine != -1) { processLine += this.graph.getEventGraphPaintListener().getFromProcessLine(); if (processLine >= numProcLines) { if (mapAreaBelowLastLineToLastLine) { processLine = numProcLines - 1; } else { processLine = -1; } } } return processLine; } public void checkVRuler(int xPos, int yPos, boolean clicked) { int graphHeight = this.graph.getClientArea().height - 30; int y = getLineNumber(yPos); if (clicked) this.vRulerSelection = -1; if (xPos > 0 && yPos > 0 && xPos < 30 && yPos < graphHeight && (clicked || this.vRulerSelection != -1)) { if (y != -1) { if (clicked) this.vRulerSelection = y; else { this.graph.mergeProcessLines(this.vRulerSelection, y); } } else { if (!clicked) { y = getLineNumber(yPos, true, true); if (y < this.vRulerSelection) { if (y + 1 < this.graph.getLineToProcessMapping().size()) { this.graph.moveProcessLine(this.vRulerSelection, y + 1); } } else { this.graph.moveProcessLine(this.vRulerSelection, y); } } } } else if (!clicked && this.vRulerSelection != -1) { this.vRulerSelection = -1; this.graph.redraw(); } } public Object[] getObjectsForPosition(int xPos, int yPos, boolean allowTraceObj) { List<Object> objList = new LinkedList<Object>(); int y = getLineNumber(yPos); if (this.graph.getEventGraphPaintListener().isInGraphArea(xPos, yPos)) { if (y != -1) { for (Integer proc : this.graph.getLineToProcessMapping().get(y)) { Object obj = getObjectOnProcess(xPos, proc.intValue()); if (obj != null) { objList.add(obj); } } if (objList.size() == 0) { objList.addAll(getProcessesOnLine(y)); } } else { if (allowTraceObj) objList.add(this.graph.getTrace()); } } return objList.toArray(); } public Object[] getObjectsForArea(final Rectangle rect) { Rectangle rect2 = new Rectangle(rect.x, rect.y, rect.width, rect.height); if (rect2.width < 0) { rect2.x += rect2.width; rect2.width *= -1; } if (rect2.height < 0) { rect2.y += rect2.height; rect2.height *= -1; } List<Object> objList = new LinkedList<Object>(); int yStart = getLineNumber(rect2.y, true, true) + 1; int yEnd = getLineNumber(rect2.y + rect2.height, true, true); for (int y = yStart; y <= yEnd; y++) { if (y != -1) { for (Integer proc : this.graph.getLineToProcessMapping().get(y)) { List<Object> objs = getObjectsOnProcess(rect2.x, rect2.x + rect2.width, proc.intValue()); objList.addAll(objs); } } } return objList.toArray(); } public List<IProcess> getProcessesOnLine(int line) { List<IProcess> procList = new LinkedList<IProcess>(); for (Integer proc : this.graph.getLineToProcessMapping().get(line)) { procList.add(this.graph.getTrace().getProcess(proc.intValue())); } return procList; } public abstract Object getObjectOnProcess(final int xPos, final int procNr); public abstract List<Object> getObjectsOnProcess(final int xStart, final int xEnd, final int procNr); }