提交 6e1f8128 编写于 作者: M Mathieu Bastian

Preview sketch mouse events

上级 4afd75b3
......@@ -42,19 +42,39 @@
package org.gephi.desktop.preview;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.gephi.preview.api.PreviewController;
import org.gephi.preview.api.PreviewMouseEvent;
import org.gephi.preview.api.ProcessingTarget;
import org.gephi.preview.api.Vector;
import org.openide.util.Lookup;
/**
*
* @author mbastian
*/
public class PreviewSketch extends JPanel {
public class PreviewSketch extends JPanel implements MouseListener, MouseWheelListener, MouseMotionListener {
private static final int WHEEL_TIMER = 500;
//Data
private final PreviewController previewController;
private final ProcessingTarget target;
//Geometry
private final Vector ref = new Vector();
private final Vector lastMove = new Vector();
//Utils
private final RefreshLoop refreshLoop = new RefreshLoop();
private Timer wheelTimer;
private boolean inited;
public PreviewSketch(ProcessingTarget target) {
this.target = target;
......@@ -65,11 +85,170 @@ public class PreviewSketch extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (!inited) {
//Listeners
addMouseListener(this);
addMouseMotionListener(this);
addMouseWheelListener(this);
inited = true;
}
if (target.getWidth() != getWidth() || target.getHeight() != getHeight()) {
System.out.println("Resizing to " + getWidth() + " " + getHeight());
target.resize(getWidth(), getHeight());
}
g.drawImage(target.getImage(), 0, 0, this);
}
public void setMoving(boolean moving) {
target.setMoving(moving);
}
@Override
public void mouseClicked(MouseEvent e) {
if (previewController.sendMouseEvent(buildPreviewMouseEvent(e, PreviewMouseEvent.Type.CLICKED))) {
refreshLoop.refreshSketch();
}
}
@Override
public void mousePressed(MouseEvent e) {
previewController.sendMouseEvent(buildPreviewMouseEvent(e, PreviewMouseEvent.Type.PRESSED));
ref.set(e.getX(), e.getY());
refreshLoop.refreshSketch();
}
@Override
public void mouseReleased(MouseEvent e) {
if (!previewController.sendMouseEvent(buildPreviewMouseEvent(e, PreviewMouseEvent.Type.RELEASED))) {
lastMove.set(target.getTranslate());
setMoving(false);
}
refreshLoop.refreshSketch();
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getUnitsToScroll() == 0) {
return;
}
float way = -e.getUnitsToScroll() / Math.abs(e.getUnitsToScroll());
target.setScaling(target.getScaling() * (way > 0 ? 2f : 0.5f));
setMoving(true);
if (wheelTimer != null) {
wheelTimer.cancel();
wheelTimer = null;
}
wheelTimer = new Timer();
wheelTimer.schedule(new TimerTask() {
@Override
public void run() {
setMoving(false);
refreshLoop.refreshSketch();
wheelTimer = null;
}
}, WHEEL_TIMER);
refreshLoop.refreshSketch();
}
@Override
public void mouseDragged(MouseEvent e) {
if (!previewController.sendMouseEvent(buildPreviewMouseEvent(e, PreviewMouseEvent.Type.DRAGGED))) {
setMoving(true);
Vector trans = target.getTranslate();
trans.set(e.getX(), e.getY());
trans.sub(ref);
trans.div(target.getScaling()); // ensure const. moving speed whatever the zoom is
trans.add(lastMove);
refreshLoop.refreshSketch();
}
}
@Override
public void mouseMoved(MouseEvent e) {
}
private Vector screenPositionToModelPosition(Vector screenPos) {
Vector center = new Vector(getWidth() / 2f, getHeight() / 2f);
Vector scaledCenter = Vector.mult(center, target.getScaling());
Vector scaledTrans = Vector.sub(center, scaledCenter);
Vector modelPos = new Vector(screenPos.x, screenPos.y);
modelPos.sub(scaledTrans);
modelPos.div(target.getScaling());
modelPos.sub(target.getTranslate());
return modelPos;
}
private PreviewMouseEvent buildPreviewMouseEvent(MouseEvent evt, PreviewMouseEvent.Type type) {
int mouseX = evt.getX();
int mouseY = evt.getY();
PreviewMouseEvent.Button button = PreviewMouseEvent.Button.LEFT;
if (SwingUtilities.isMiddleMouseButton(evt)) {
button = PreviewMouseEvent.Button.MIDDLE;
} else if (SwingUtilities.isLeftMouseButton(evt)) {
button = PreviewMouseEvent.Button.LEFT;
} else if (SwingUtilities.isRightMouseButton(evt)) {
button = PreviewMouseEvent.Button.RIGHT;
}
Vector pos = screenPositionToModelPosition(new Vector(mouseX, mouseY));
return new PreviewMouseEvent((int) pos.x, (int) pos.y, type, button, null);
}
private class RefreshLoop {
private final long DELAY = 100;
private final AtomicBoolean running = new AtomicBoolean();
private final AtomicBoolean refresh = new AtomicBoolean();
//Timer
private long timeout = DELAY * 10;
private Timer timer;
public RefreshLoop() {
super();
}
public void refreshSketch() {
refresh.set(true);
if (!running.getAndSet(true)) {
startTimer();
}
}
private void startTimer() {
timer = new Timer("PreviewRefreshLoop", true);
timer.schedule(new TimerTask() {
@Override
public void run() {
if (refresh.getAndSet(false)) {
target.refresh();
repaint();
} else if (timeout == 0) {
timeout = DELAY * 10;
stopTimer();
} else {
timeout -= DELAY;
}
}
}, 0, DELAY);
}
private void stopTimer() {
timer.cancel();
running.set(false);
}
}
}
......@@ -178,6 +178,7 @@ public final class PreviewTopComponent extends TopComponent implements PropertyC
}
public void initTarget(PreviewUIModel previewUIModel) {
System.out.println("INIT T");
// inits the preview applet
if (previewUIModel != null && target == null) {
PreviewController previewController = Lookup.getDefault().lookup(PreviewController.class);
......
......@@ -67,18 +67,18 @@ public class ProcessingGraphics {
private final PreviewController previewController = Lookup.getDefault().lookup(PreviewController.class);
private PreviewModel model;
private RenderTarget target;
private boolean inited;
//Drawing
private final Image image;
private final int width;
private final int height;
private final Graphics2D g2;
private final Vector ref = new Vector();
private final Vector trans = new Vector();
private final Vector lastMove = new Vector();
private float scaling;
private Color background = Color.WHITE;
public ProcessingGraphics(int width, int height) {
System.out.println("Creating new graphcis " + width + " " + height);
this.width = width;
this.height = height;
GraphicsConfiguration graphicsConfiguration = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
......@@ -98,11 +98,9 @@ public class ProcessingGraphics {
background = model.getProperties().getColorValue(PreviewProperty.BACKGROUND_COLOR);
initAppletLayout();
g2.clearRect(0, 0, width, height);
g2.setTransform(new AffineTransform());
if (background != null) {
g2.setColor(background);
g2.fillRect(0, 0, width, height);
......@@ -123,6 +121,18 @@ public class ProcessingGraphics {
}
}
public Vector getTranslate() {
return trans;
}
public float getScaling() {
return scaling;
}
public void setScaling(float scaling) {
this.scaling = scaling;
}
public Graphics2D getGraphics() {
return g2;
}
......@@ -144,7 +154,7 @@ public class ProcessingGraphics {
*/
private void initAppletLayout() {
// graphSheet.setMargin(MARGIN);
if (model != null && model.getDimensions() != null && model.getTopLeftPosition() != null) {
if (!inited && model != null && model.getDimensions() != null && model.getTopLeftPosition() != null) {
// initializes zoom
Dimension dimensions = model.getDimensions();
......@@ -161,7 +171,9 @@ public class ProcessingGraphics {
Vector scaledCenter = Vector.add(topLeftVector, semiBox);
trans.set(center);
trans.sub(scaledCenter);
lastMove.set(trans);
// lastMove.set(trans);
inited = true;
}
}
}
......@@ -45,8 +45,10 @@ import java.awt.Graphics2D;
import java.awt.Image;
import org.gephi.preview.api.PreviewController;
import org.gephi.preview.api.PreviewModel;
import org.gephi.preview.api.PreviewProperty;
import org.gephi.preview.api.ProcessingTarget;
import org.gephi.preview.api.RenderTarget;
import org.gephi.preview.api.Vector;
import org.gephi.preview.spi.RenderTargetBuilder;
import org.openide.util.Lookup;
import org.openide.util.lookup.ServiceProvider;
......@@ -65,9 +67,9 @@ public class ProcessingRenderTargetBuilder implements RenderTargetBuilder {
if (width != null && height != null) {
width = Math.max(1, width);
height = Math.max(1, height);
return new ProcessingTargetImpl(width, height);
return new ProcessingTargetImpl(previewModel, width, height);
} else {
return new ProcessingTargetImpl(1, 1);
return new ProcessingTargetImpl(previewModel, 1, 1);
}
}
......@@ -79,11 +81,13 @@ public class ProcessingRenderTargetBuilder implements RenderTargetBuilder {
public static class ProcessingTargetImpl extends AbstractRenderTarget implements ProcessingTarget {
private final PreviewController previewController;
private final PreviewModel previewModel;
private ProcessingGraphics graphics;
public ProcessingTargetImpl(int width, int height) {
public ProcessingTargetImpl(PreviewModel model, int width, int height) {
graphics = new ProcessingGraphics(width, height);
previewController = Lookup.getDefault().lookup(PreviewController.class);
previewModel = model;
}
@Override
......@@ -114,6 +118,26 @@ public class ProcessingRenderTargetBuilder implements RenderTargetBuilder {
return graphics.getHeight();
}
@Override
public Vector getTranslate() {
return graphics.getTranslate();
}
@Override
public float getScaling() {
return graphics.getScaling();
}
@Override
public void setScaling(float scaling) {
graphics.setScaling(scaling);
}
@Override
public void setMoving(boolean moving) {
previewModel.getProperties().putValue(PreviewProperty.MOVING, moving);
}
@Override
public void refresh() {
if (graphics != null) {
......
......@@ -95,6 +95,14 @@ public interface ProcessingTarget extends RenderTarget {
public void resize(int width, int height);
public void setMoving(boolean moving);
public Vector getTranslate();
public float getScaling();
public void setScaling(float scaling);
/**
* Redraw the Processing canvas
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册