From 68073e314a1f85e97b0d5fa91c94f1fcd0780c13 Mon Sep 17 00:00:00 2001 From: Markus Weber Date: Mon, 9 Oct 2023 16:17:53 +0200 Subject: [PATCH 1/3] Zoomer: add a user definable predicate for panning --- .../io/fair_acc/chartfx/plugins/Zoomer.java | 73 +++++++++++++------ 1 file changed, 51 insertions(+), 22 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..bae126a77 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,27 +95,7 @@ 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. * From d82d0b79f22c8cb8bd46b640096f5888a77f681c Mon Sep 17 00:00:00 2001 From: Markus Weber Date: Mon, 9 Oct 2023 16:20:37 +0200 Subject: [PATCH 2/3] ZoomerSample: add a chart with a user-defined panning predicate --- .../java/io/fair_acc/sample/chart/ZoomerSample.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) 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..ac084100a 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; } From 27a078ba3d985ee3dbae6342e71107fc594212d5 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 9 Oct 2023 15:02:55 +0000 Subject: [PATCH 3/3] Restyled by clang-format --- .../src/main/java/io/fair_acc/chartfx/plugins/Zoomer.java | 2 +- .../src/main/java/io/fair_acc/sample/chart/ZoomerSample.java | 2 +- 2 files changed, 2 insertions(+), 2 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 bae126a77..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 @@ -95,7 +95,7 @@ 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); - + /** * Default zoom-in mouse filter passing on left mouse button (only). */ 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 ac084100a..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 @@ -81,7 +81,7 @@ public Node getChartPanel(final Stage primaryStage) { 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;