/******************************************************************************* * Copyright (c) 2009 the CHISEL group and contributors. * 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: * Del Myers - initial API and implementation *******************************************************************************/ package ca.uvic.chisel.widgets; 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.Point; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; /** * @author Del Myers * */ class RangeSliderHelper implements MouseListener, MouseMoveListener { int armedLocation; private RangeSlider slider; private boolean armedLow; private boolean armedHigh; private boolean dragging; private class EventForwarder implements Listener { /* (non-Javadoc) * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event e) { if (e.type == SWT.MenuDetect) { return; } Event fe = new Event(); fe.button = e.button; fe.character = e.character; fe.count = e.count; fe.data = e.data; fe.detail = e.detail; fe.display = e.display; fe.doit = e.doit; fe.gc = e.gc; fe.height = e.height; fe.index = e.index; fe.item = e.item; fe.keyCode = e.keyCode; fe.start = e.start; fe.stateMask = e.stateMask; fe.time = e.time; fe.type = e.type; fe.widget = slider; fe.width = e.width; fe.x = e.x; fe.y = e.y; fe.item = slider.itemAt(new Point(e.x, e.y)); slider.notifyListeners(e.type, fe); } } RangeSliderHelper(RangeSlider slider) { this.slider = slider; armedLocation = -1; Canvas canvas = slider.getCanvas(); canvas.addMouseListener(this); canvas.addMouseMoveListener(this); Listener listener = new EventForwarder(); canvas.addListener(SWT.MouseMove, listener); canvas.addListener(SWT.MouseDown, listener); canvas.addListener(SWT.MouseEnter, listener); canvas.addListener(SWT.MouseUp, listener); canvas.addListener(SWT.MouseExit, listener); canvas.addListener(SWT.MouseHover, listener); canvas.addListener(SWT.MouseMove, listener); canvas.addListener(SWT.MouseWheel, listener); canvas.addListener(SWT.MouseDoubleClick, listener); canvas.addListener(SWT.KeyDown, listener); canvas.addListener(SWT.KeyUp, listener); canvas.addListener(SWT.MenuDetect, listener); } /* (non-Javadoc) * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) */ public void mouseDoubleClick(MouseEvent e) {} /* (non-Javadoc) * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent) */ public void mouseDown(MouseEvent e) { if (e.x < slider.getVisualLow()) { slider.internalSetVisualMinimum(e.x); } else if (e.x > slider.getVisualHigh()) { slider.internalSetVisualMaximum(e.x); } arm(e); } /** * */ private void arm(MouseEvent e) { if (e.button == 1) { int visualLow = slider.getVisualLow(); int visualHigh = slider.getVisualHigh(); armedLocation = e.x; boolean aboveMin = e.x >= visualLow-RangeSlider.HANDLE_SIZE; boolean belowMinHandle = e.x <= visualLow; boolean belowMax = e.x <= visualHigh + RangeSlider.HANDLE_SIZE; boolean aboveMaxHandle = e.x >= visualHigh; if (aboveMin && belowMinHandle) { armedLow = true; } else if (belowMax && aboveMaxHandle) { armedHigh = true; } else if (aboveMin && belowMax) { //make sure that there is no item under the cursor if (slider.itemAt(new Point(e.x, e.y)) == null) { armedLow = armedHigh = true; } else { armedLocation = -1; armedLow = armedHigh = false; } } } else { armedLocation = -1; armedLow = armedHigh = false; } } /* (non-Javadoc) * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) */ public void mouseUp(MouseEvent e) { if (armed() && armedLocation != e.x) { } armedLow = armedHigh = false; armedLocation = -1; if (!dragging) { slider.updateSelection(e); } //notify listeners of the change dragging = false; } /* (non-Javadoc) * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent) */ public void mouseMove(MouseEvent e) { if (e.button != 0) { dragging = true; } if (inHandle(e.x) || armed()) { slider.getCanvas().setCursor(slider.getCanvas().getDisplay().getSystemCursor(SWT.CURSOR_SIZEW)); } else { slider.getCanvas().setCursor(slider.getCursor()); } if (armedLow && armedHigh) { int visualHigh = slider.getVisualHigh(); int visualLow = slider.getVisualLow(); int diff = e.x - armedLocation; slider.internalSetVisualMaximum(visualHigh + diff); slider.internalSetVisualMinimum(visualLow + diff); armedLocation = e.x; } else if (armedLow) { slider.internalSetVisualMinimum(e.x); } else if (armedHigh) { slider.internalSetVisualMaximum(e.x); } } /** * @return */ private boolean armed() { return armedLow || armedHigh; } private boolean inHandle(int x) { int visualLow = slider.getVisualLow(); int visualHigh = slider.getVisualHigh(); boolean inLow = (x >= visualLow-RangeSlider.HANDLE_SIZE) && (x <= visualLow+RangeSlider.HANDLE_SIZE); boolean inHigh = (x >= visualHigh - RangeSlider.HANDLE_SIZE) && (x <= visualHigh + RangeSlider.HANDLE_SIZE); return (inLow || inHigh);// && (slider.itemAt(new Point(x, 0)) == null); } }