pinch zooming for mac

This commit is contained in:
bancika
2020-12-09 21:30:08 +01:00
parent caf9b3b5d5
commit 77ab989334
8 changed files with 159 additions and 77 deletions
@@ -3269,5 +3269,25 @@
</changes>
<url>https://github.com/bancika/diy-layout-creator/releases</url>
</org.diylc.appframework.update.Version>
<org.diylc.appframework.update.Version>
<versionNumber>
<major>4</major>
<minor>12</minor>
<build>0</build>
</versionNumber>
<releaseDate>2020-11-19 00:00:00.000 CET</releaseDate>
<name></name>
<changes>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>macOS: added pinch zooming functionality</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>macOS: added meta +/- (minus and equal keys) keyboard shortcuts for zooming</description>
</org.diylc.appframework.update.Change>
</changes>
<url>https://github.com/bancika/diy-layout-creator/releases</url>
</org.diylc.appframework.update.Version>
</a>
</java.util.Arrays_-ArrayList>
+1
View File
@@ -15,6 +15,7 @@
<classpathentry kind="lib" path="lib/poi-3.5-FINAL-20090928.jar"/>
<classpathentry kind="lib" path="lib/AppleJavaExtensions.jar"/>
<classpathentry kind="lib" path="lib/orsonpdf-1.8.jar"/>
<classpathentry kind="lib" path="lib/gestures-wrapper-0.2.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/diylc-core"/>
<classpathentry kind="lib" path="lib/xstream-1.4.3.jar"/>
<classpathentry kind="lib" path="lib/java-http-proxy.jar"/>
+1 -1
View File
@@ -10,7 +10,7 @@
<property name="jar.dir" value="${build.dir}/jar" />
<property name="report.dir" value="${build.dir}/junitreport" />
<property name="main.class" value="org.diylc.DIYLCStarter" />
<property name="diylc.version" value="4.11.0" />
<property name="diylc.version" value="4.12.0" />
<property name="osx.jre8.path" value="jre\osx\jdk8u275-b01-jre\Contents\Home\" />
Binary file not shown.
Binary file not shown.
@@ -29,15 +29,15 @@ import java.awt.event.MouseEvent;
import org.diylc.common.IPlugInPort;
/**
* {@link DragGestureListener} for {@link CanvasPanel}.
* {@link DragGestureListener} implementation for {@link CanvasPanel}.
*
* @author Branislav Stojkovic
*/
class CanvasGestureListener implements DragGestureListener {
class CanvasDragGestureListener implements DragGestureListener {
private IPlugInPort presenter;
public CanvasGestureListener(IPlugInPort presenter) {
public CanvasDragGestureListener(IPlugInPort presenter) {
super();
this.presenter = presenter;
}
@@ -124,7 +124,7 @@ public class CanvasPanel extends JComponent implements Autoscroll {
// Initialize drag source recognizer.
DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(this,
DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK,
new CanvasGestureListener(plugInPort));
new CanvasDragGestureListener(plugInPort));
// Initialize drop target.
new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, new CanvasTargetListener(plugInPort),
true);
@@ -143,8 +143,12 @@ public class CanvasPanel extends JComponent implements Autoscroll {
.put(KeyStroke.getKeyStroke(KeyEvent.VK_SUBTRACT, KeyEvent.CTRL_DOWN_MASK), "zoomOut");
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, KeyEvent.META_DOWN_MASK), "zoomIn");
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, KeyEvent.META_DOWN_MASK), "zoomIn");
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_SUBTRACT, KeyEvent.META_DOWN_MASK), "zoomOut");
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, KeyEvent.META_DOWN_MASK), "zoomOut");
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_0, KeyEvent.CTRL_DOWN_MASK), "resetZoom");
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
@@ -169,35 +173,35 @@ public class CanvasPanel extends JComponent implements Autoscroll {
});
}
getActionMap().put("zoomIn", new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
LOG.debug("Keyboard zoom-in triggered");
double oldZoom = CanvasPanel.this.plugInPort.getZoomLevel();
Double[] availableZoomLevels = CanvasPanel.this.plugInPort.getAvailableZoomLevels();
int index = Arrays.binarySearch(availableZoomLevels, oldZoom);
if (index < availableZoomLevels.length - 1)
CanvasPanel.this.plugInPort.setZoomLevel(availableZoomLevels[index + 1]);
}
});
getActionMap().put("zoomOut", new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
LOG.debug("Keyboard zoom-out triggered");
double oldZoom = CanvasPanel.this.plugInPort.getZoomLevel();
Double[] availableZoomLevels = CanvasPanel.this.plugInPort.getAvailableZoomLevels();
int index = Arrays.binarySearch(availableZoomLevels, oldZoom);
if (index > 0)
CanvasPanel.this.plugInPort.setZoomLevel(availableZoomLevels[index - 1]);
}
});
// getActionMap().put("zoomIn", new AbstractAction() {
//
// private static final long serialVersionUID = 1L;
//
// @Override
// public void actionPerformed(ActionEvent e) {
// LOG.debug("Keyboard zoom-in triggered");
// double oldZoom = CanvasPanel.this.plugInPort.getZoomLevel();
// Double[] availableZoomLevels = CanvasPanel.this.plugInPort.getAvailableZoomLevels();
// int index = Arrays.binarySearch(availableZoomLevels, oldZoom);
// if (index < availableZoomLevels.length - 1)
// CanvasPanel.this.plugInPort.setZoomLevel(availableZoomLevels[index + 1]);
// }
// });
//
// getActionMap().put("zoomOut", new AbstractAction() {
//
// private static final long serialVersionUID = 1L;
//
// @Override
// public void actionPerformed(ActionEvent e) {
// LOG.debug("Keyboard zoom-out triggered");
// double oldZoom = CanvasPanel.this.plugInPort.getZoomLevel();
// Double[] availableZoomLevels = CanvasPanel.this.plugInPort.getAvailableZoomLevels();
// int index = Arrays.binarySearch(availableZoomLevels, oldZoom);
// if (index > 0)
// CanvasPanel.this.plugInPort.setZoomLevel(availableZoomLevels[index - 1]);
// }
// });
getActionMap().put("resetZoom", new AbstractAction() {
@@ -61,19 +61,24 @@ import org.diylc.common.IPlugInPort;
import org.diylc.core.ExpansionMode;
import org.diylc.core.IDIYComponent;
import org.diylc.core.Template;
import org.diylc.swing.images.IconLoader;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.swing.ActionFactory;
import org.diylc.swing.ISwingUI;
import org.diylc.swing.gui.TranslatedMenu;
import org.diylc.swing.gui.TranslatedPopupMenu;
import org.diylc.swing.images.IconLoader;
import org.diylc.swing.plugins.edit.ComponentTransferable;
import org.diylc.swing.plugins.file.ProjectDrawingProvider;
import org.diylc.swingframework.ruler.IRulerListener;
import org.diylc.swingframework.ruler.Ruler.InchSubdivision;
import org.diylc.swingframework.ruler.RulerScrollPane;
import com.guigarage.gestures.GestureMagnificationEvent;
import com.guigarage.gestures.GestureMagnificationListener;
import com.guigarage.gestures.GestureUtilities;
import com.guigarage.gestures.GesturesNotSupportedException;
public class CanvasPlugin implements IPlugIn, ClipboardOwner {
private static final Logger LOG = Logger.getLogger(CanvasPlugin.class);
@@ -343,6 +348,55 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
e.isShiftDown(), e.isAltDown());
}
});
canvasPanel.getActionMap().put("zoomIn", new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
LOG.debug("Keyboard zoom-in triggered");
zoom(-1);
}
});
canvasPanel.getActionMap().put("zoomOut", new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
LOG.debug("Keyboard zoom-out triggered");
zoom(1);
}
});
if (!GestureUtilities.isSupported()) {
LOG.info("Gestures are not supported, skipping initialization");
}
try {
GestureUtilities.registerListener(canvasPanel, new GestureMagnificationListener() {
private long prevEventTime = 0;
private static final int DELAY = 100;
@Override
public void magnify(GestureMagnificationEvent e) {
if (System.currentTimeMillis() - this.prevEventTime < DELAY)
return;
if (e.getMagnification() > 0)
CanvasPlugin.this.zoom(-1);
else if (e.getMagnification() < 0)
CanvasPlugin.this.zoom(1);
prevEventTime = System.currentTimeMillis();
}
});
LOG.info("Magnification gesture listener initialized.");
} catch (GesturesNotSupportedException e) {
LOG.error("Error registering gesture listener", e);
}
}
return canvasPanel;
}
@@ -390,48 +444,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
configManager.readBoolean(IPlugInPort.WHEEL_ZOOM_KEY, false);
if (wheelZoom || (Utils.isMac() ? e.isMetaDown() : e.isControlDown())) {
Point mousePos = getCanvasPanel().getMousePosition(true);
// change zoom level
double oldZoom = plugInPort.getZoomLevel();
double newZoom;
Double[] availableZoomLevels = plugInPort.getAvailableZoomLevels();
if (e.getWheelRotation() > 0) {
int i = availableZoomLevels.length - 1;
while (i > 0 && availableZoomLevels[i] >= oldZoom) {
i--;
}
plugInPort.setZoomLevel(newZoom = availableZoomLevels[i]);
} else {
int i = 0;
while (i < availableZoomLevels.length - 1 && availableZoomLevels[i] <= oldZoom) {
i++;
}
plugInPort.setZoomLevel(newZoom = availableZoomLevels[i]);
}
Rectangle2D selectionBounds = plugInPort.getSelectionBounds(true);
Rectangle visibleRect = scrollPane.getVisibleRect();
JScrollBar horizontal = scrollPane.getHorizontalScrollBar();
JScrollBar vertical = scrollPane.getVerticalScrollBar();
if (selectionBounds == null) {
// center to cursor
Point desiredPos = new Point((int) (1d * mousePos.x / oldZoom * newZoom),
(int) (1d * mousePos.y / oldZoom * newZoom));
int dx = desiredPos.x - mousePos.x;
int dy = desiredPos.y - mousePos.y;
horizontal.setValue(horizontal.getValue() + dx);
vertical.setValue(vertical.getValue() + dy);
} else {
// center to selection
horizontal.setValue((int) (selectionBounds.getX() + selectionBounds.getWidth() / 2
- visibleRect.getWidth() / 2));
vertical.setValue((int) (selectionBounds.getY() + selectionBounds.getHeight() / 2
- visibleRect.getHeight() / 2));
}
CanvasPlugin.this.zoom(e.getWheelRotation());
}
if (e.isShiftDown()) {
int iScrollAmount = e.getScrollAmount();
@@ -451,6 +464,50 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
}
return scrollPane;
}
public void zoom(int direction) {
Point mousePos = canvasPanel.getMousePosition(true);
// change zoom level
double oldZoom = plugInPort.getZoomLevel();
double newZoom;
Double[] availableZoomLevels = plugInPort.getAvailableZoomLevels();
if (direction > 0) {
int i = availableZoomLevels.length - 1;
while (i > 0 && availableZoomLevels[i] >= oldZoom) {
i--;
}
plugInPort.setZoomLevel(newZoom = availableZoomLevels[i]);
} else {
int i = 0;
while (i < availableZoomLevels.length - 1 && availableZoomLevels[i] <= oldZoom) {
i++;
}
plugInPort.setZoomLevel(newZoom = availableZoomLevels[i]);
}
Rectangle2D selectionBounds = plugInPort.getSelectionBounds(true);
Rectangle visibleRect = scrollPane.getVisibleRect();
JScrollBar horizontal = scrollPane.getHorizontalScrollBar();
JScrollBar vertical = scrollPane.getVerticalScrollBar();
if (selectionBounds == null) {
// center to cursor
Point desiredPos = new Point((int) (1d * mousePos.x / oldZoom * newZoom),
(int) (1d * mousePos.y / oldZoom * newZoom));
int dx = desiredPos.x - mousePos.x;
int dy = desiredPos.y - mousePos.y;
horizontal.setValue(horizontal.getValue() + dx);
vertical.setValue(vertical.getValue() + dy);
} else {
// center to selection
horizontal.setValue((int) (selectionBounds.getX() + selectionBounds.getWidth() / 2
- visibleRect.getWidth() / 2));
vertical.setValue((int) (selectionBounds.getY() + selectionBounds.getHeight() / 2
- visibleRect.getHeight() / 2));
}
}
private void showPopupAt(int x, int y) {
updateSelectionMenu(x, y);