From ed86318c5a1bde23d285633a94860648aee5fb32 Mon Sep 17 00:00:00 2001 From: ichaus-we <64585037+ichaus-we@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:45:06 +0200 Subject: [PATCH] Zoomer: add a user definable predicate for panning (#631) * Zoomer: add a user definable predicate for panning * ZoomerSample: add a chart with a user-defined panning predicate --------- Co-authored-by: Markus Weber --- .../io/fair_acc/chartfx/plugins/Zoomer.java | 71 +++++++++++++------ .../fair_acc/sample/chart/ZoomerSample.java | 12 +++- 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/chartfx-chart/src/main/java/io/fair_acc/chartfx/plugins/Zoomer.java b/chartfx-chart/src/main/java/io/fair_acc/chartfx/plugins/Zoomer.java index 793ae812a..e5c826d41 100644 --- a/chartfx-chart/src/main/java/io/fair_acc/chartfx/plugins/Zoomer.java +++ b/chartfx-chart/src/main/java/io/fair_acc/chartfx/plugins/Zoomer.java @@ -84,8 +84,9 @@ public class Zoomer extends ChartPlugin { private static final String ICON_ZOOM_V = "fa-arrows-v:" + FONT_SIZE; /** - * Default pan mouse filter passing on left mouse button with {@link MouseEvent#isControlDown() control key down}. + * Default pan mouse filter passing on middle mouse button {@link MouseEventsHelper#isOnlyMiddleButtonDown()}. */ + @Deprecated public static final Predicate DEFAULT_MOUSE_FILTER = MouseEventsHelper::isOnlyMiddleButtonDown; private double panShiftX; private double panShiftY; @@ -94,26 +95,6 @@ public class Zoomer extends ChartPlugin { private final BooleanProperty autoZoomEnable = new SimpleBooleanProperty(this, "enableAutoZoom", false); private final IntegerProperty autoZoomThreshold = new SimpleIntegerProperty(this, "autoZoomThreshold", DEFAULT_AUTO_ZOOM_THRESHOLD); - private final EventHandler panStartHandler = event -> { - if (isPannerEnabled() && DEFAULT_MOUSE_FILTER.test(event)) { - panStarted(event); - event.consume(); - } - }; - - private final EventHandler panDragHandler = event -> { - if (panOngoing()) { - panDragged(event); - event.consume(); - } - }; - - private final EventHandler panEndHandler = event -> { - if (panOngoing()) { - panEnded(); - event.consume(); - } - }; /** * Default zoom-in mouse filter passing on left mouse button (only). @@ -125,6 +106,11 @@ public class Zoomer extends ChartPlugin { */ public final Predicate defaultZoomOutMouseFilter = event -> MouseEventsHelper.isOnlySecondaryButtonDown(event) && MouseEventsHelper.modifierKeysUp(event) && isMouseEventWithinCanvas(event); + /** + * Default pan mouse filter passing on middle mouse button (only). + */ + public final Predicate defaultPanMouseFilter = event -> MouseEventsHelper.isOnlyMiddleButtonDown(event) && MouseEventsHelper.modifierKeysUp(event) && isMouseEventWithinCanvas(event); + /** * Default zoom-origin mouse filter passing on right mouse button with {@link MouseEvent#isControlDown() control key * down}. @@ -138,6 +124,7 @@ public class Zoomer extends ChartPlugin { private Predicate zoomInMouseFilter = defaultZoomInMouseFilter; private Predicate zoomOutMouseFilter = defaultZoomOutMouseFilter; + private Predicate panMouseFilter = defaultPanMouseFilter; private Predicate zoomOriginMouseFilter = defaultZoomOriginFilter; private Predicate zoomScrollFilter = defaultScrollFilter; @@ -226,6 +213,27 @@ protected void invalidated() { } }; + private final EventHandler panStartHandler = event -> { + if (isPannerEnabled() && (panMouseFilter == null || panMouseFilter.test(event))) { + panStarted(event); + event.consume(); + } + }; + + private final EventHandler panDragHandler = event -> { + if (panOngoing()) { + panDragged(event); + event.consume(); + } + }; + + private final EventHandler panEndHandler = event -> { + if (panOngoing()) { + panEnded(); + event.consume(); + } + }; + private final EventHandler zoomOriginHandler = event -> { if (getZoomOriginMouseFilter() == null || getZoomOriginMouseFilter().test(event)) { final boolean zoomOutPerformed = zoomOrigin(); @@ -462,6 +470,16 @@ public Predicate getZoomOutMouseFilter() { return zoomOutMouseFilter; } + /** + * Returns pan mouse filter. + * + * @return pan mouse filter + * @see #setPanMouseFilter(Predicate) + */ + public Predicate getPanMouseFilter() { + return panMouseFilter; + } + /** * Returns zoom-scroll filter. * @@ -649,6 +667,17 @@ public void setZoomOutMouseFilter(final Predicate zoomOutMouseFilter this.zoomOutMouseFilter = zoomOutMouseFilter; } + /** + * Sets filter on {@link MouseEvent#MOUSE_CLICKED MOUSE_CLICKED} events that should start pan operation. + * + * @param panMouseFilter the filter to accept pan mouse event. If {@code null} then any MOUSE_CLICKED event + * will start pan operation. By default it's set to {@link #defaultPanMouseFilter}. + * @see #getPanMouseFilter() + */ + public void setPanMouseFilter(final Predicate panMouseFilter) { + this.panMouseFilter = panMouseFilter; + } + /** * Sets filter on {@link MouseEvent#MOUSE_CLICKED MOUSE_CLICKED} events that should trigger zoom-origin operation. * diff --git a/chartfx-samples/src/main/java/io/fair_acc/sample/chart/ZoomerSample.java b/chartfx-samples/src/main/java/io/fair_acc/sample/chart/ZoomerSample.java index 2caa7654e..c593f22e2 100644 --- a/chartfx-samples/src/main/java/io/fair_acc/sample/chart/ZoomerSample.java +++ b/chartfx-samples/src/main/java/io/fair_acc/sample/chart/ZoomerSample.java @@ -20,6 +20,7 @@ import io.fair_acc.chartfx.XYChart; import io.fair_acc.chartfx.axes.Axis; import io.fair_acc.chartfx.axes.AxisMode; +import io.fair_acc.chartfx.plugins.MouseEventsHelper; import io.fair_acc.chartfx.plugins.Zoomer; import io.fair_acc.chartfx.plugins.Zoomer.ZoomState; import io.fair_acc.dataset.DataSet; @@ -68,13 +69,20 @@ public Node getChartPanel(final Stage primaryStage) { registerZoomerChangeListener(zoomer3, chart3.getTitle()); chart3.getPlugins().add(zoomer3); - // chart with x-only zoom + // chart with y-only zoom final Chart chart4 = getTestChart("y-only zoom", testDataSet); Zoomer zoomer4 = new Zoomer(AxisMode.Y); registerZoomerChangeListener(zoomer4, chart4.getTitle()); chart4.getPlugins().add(zoomer4); - root.getChildren().addAll(chart1, chart2, chart3, chart4, label); + // chart with control + LMB pan + final Chart chart5 = getTestChart("control + primary (left) button to pan", testDataSet); + Zoomer zoomer5 = new Zoomer(); + zoomer5.setPanMouseFilter(event -> MouseEventsHelper.isOnlyPrimaryButtonDown(event) && MouseEventsHelper.isOnlyCtrlModifierDown(event)); + registerZoomerChangeListener(zoomer5, chart5.getTitle()); + chart5.getPlugins().add(zoomer5); + + root.getChildren().addAll(chart1, chart2, chart3, chart4, chart5, label); return root; }