Skip to content

Commit

Permalink
Zoomer: add a user definable predicate for panning (#631)
Browse files Browse the repository at this point in the history
* Zoomer: add a user definable predicate for panning
* ZoomerSample: add a chart with a user-defined panning predicate

---------

Co-authored-by: Markus Weber <[email protected]>
  • Loading branch information
ichaus-we and Markus Weber authored Oct 10, 2023
1 parent 7164e6b commit ed86318
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 23 deletions.
71 changes: 50 additions & 21 deletions chartfx-chart/src/main/java/io/fair_acc/chartfx/plugins/Zoomer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<MouseEvent> DEFAULT_MOUSE_FILTER = MouseEventsHelper::isOnlyMiddleButtonDown;
private double panShiftX;
private double panShiftY;
Expand All @@ -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<MouseEvent> panStartHandler = event -> {
if (isPannerEnabled() && DEFAULT_MOUSE_FILTER.test(event)) {
panStarted(event);
event.consume();
}
};

private final EventHandler<MouseEvent> panDragHandler = event -> {
if (panOngoing()) {
panDragged(event);
event.consume();
}
};

private final EventHandler<MouseEvent> panEndHandler = event -> {
if (panOngoing()) {
panEnded();
event.consume();
}
};

/**
* Default zoom-in mouse filter passing on left mouse button (only).
Expand All @@ -125,6 +106,11 @@ public class Zoomer extends ChartPlugin {
*/
public final Predicate<MouseEvent> defaultZoomOutMouseFilter = event -> MouseEventsHelper.isOnlySecondaryButtonDown(event) && MouseEventsHelper.modifierKeysUp(event) && isMouseEventWithinCanvas(event);

/**
* Default pan mouse filter passing on middle mouse button (only).
*/
public final Predicate<MouseEvent> 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}.
Expand All @@ -138,6 +124,7 @@ public class Zoomer extends ChartPlugin {

private Predicate<MouseEvent> zoomInMouseFilter = defaultZoomInMouseFilter;
private Predicate<MouseEvent> zoomOutMouseFilter = defaultZoomOutMouseFilter;
private Predicate<MouseEvent> panMouseFilter = defaultPanMouseFilter;
private Predicate<MouseEvent> zoomOriginMouseFilter = defaultZoomOriginFilter;
private Predicate<ScrollEvent> zoomScrollFilter = defaultScrollFilter;

Expand Down Expand Up @@ -226,6 +213,27 @@ protected void invalidated() {
}
};

private final EventHandler<MouseEvent> panStartHandler = event -> {
if (isPannerEnabled() && (panMouseFilter == null || panMouseFilter.test(event))) {
panStarted(event);
event.consume();
}
};

private final EventHandler<MouseEvent> panDragHandler = event -> {
if (panOngoing()) {
panDragged(event);
event.consume();
}
};

private final EventHandler<MouseEvent> panEndHandler = event -> {
if (panOngoing()) {
panEnded();
event.consume();
}
};

private final EventHandler<MouseEvent> zoomOriginHandler = event -> {
if (getZoomOriginMouseFilter() == null || getZoomOriginMouseFilter().test(event)) {
final boolean zoomOutPerformed = zoomOrigin();
Expand Down Expand Up @@ -462,6 +470,16 @@ public Predicate<MouseEvent> getZoomOutMouseFilter() {
return zoomOutMouseFilter;
}

/**
* Returns pan mouse filter.
*
* @return pan mouse filter
* @see #setPanMouseFilter(Predicate)
*/
public Predicate<MouseEvent> getPanMouseFilter() {
return panMouseFilter;
}

/**
* Returns zoom-scroll filter.
*
Expand Down Expand Up @@ -649,6 +667,17 @@ public void setZoomOutMouseFilter(final Predicate<MouseEvent> 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<MouseEvent> panMouseFilter) {
this.panMouseFilter = panMouseFilter;
}

/**
* Sets filter on {@link MouseEvent#MOUSE_CLICKED MOUSE_CLICKED} events that should trigger zoom-origin operation.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit ed86318

Please sign in to comment.