Skip to content

Commit

Permalink
8334874: Horizontal scroll events from touch pads should scroll the T…
Browse files Browse the repository at this point in the history
…abPane tabs

Backport-of: 1bdb93c792cf7c218c74ec5cacda8bac1242f73b
  • Loading branch information
Johan Vos committed Aug 19, 2024
1 parent d0c5cd4 commit b8a7a68
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -934,17 +934,23 @@ public TabHeaderArea() {
// Scrolling the mouse wheel downwards results in the tabs scrolling left (i.e. exposing the right-most tabs)
// Scrolling the mouse wheel upwards results in the tabs scrolling right (i.e. exposing th left-most tabs)
addEventHandler(ScrollEvent.SCROLL, (ScrollEvent e) -> {
double dx = e.getDeltaX();
double dy = e.getDeltaY();

Side side = getSkinnable().getSide();
side = side == null ? Side.TOP : side;
switch (side) {
default:
case TOP:
case BOTTOM:
setScrollOffset(scrollOffset + e.getDeltaY());
// Consider vertical scroll events (dy > dx) from mouse wheel and trackpad,
// and horizontal scroll events from a trackpad (dx > dy)
dx = Math.abs(dy) > Math.abs(dx) ? dy : dx;
setScrollOffset(scrollOffset + dx);
break;
case LEFT:
case RIGHT:
setScrollOffset(scrollOffset - e.getDeltaY());
setScrollOffset(scrollOffset - dy);
break;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -38,6 +38,7 @@
import static org.junit.Assert.fail;

import javafx.scene.control.SelectionModel;
import javafx.scene.input.ScrollEvent;
import test.com.sun.javafx.scene.control.infrastructure.StageLoader;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
Expand Down Expand Up @@ -1241,4 +1242,104 @@ public void testSMLeakOnSwitchSkinAndSM() {
attemptGC(10, weakSMRef);
assertNull(weakSMRef.get());
}

@Test
public void testVerticalScrollTopSide() {
scrollTabPane(Side.TOP, 0, -100);
}

@Test
public void testVerticalScrollRightSide() {
scrollTabPane(Side.RIGHT, 0, 100);
}

@Test
public void testVerticalScrollBottomSide() {
scrollTabPane(Side.BOTTOM, 0, -100);
}

@Test
public void testVerticalScrollLeftSide() {
scrollTabPane(Side.LEFT, 0, 100);
}

@Test
public void testHorizontalScrollTopSide() {
scrollTabPane(Side.TOP, -100, 0);
}

@Test
public void testHorizontalScrollRightSide() {
scrollTabPane(Side.RIGHT, 100, 0);
}

@Test
public void testHorizontalScrollBottomSide() {
scrollTabPane(Side.BOTTOM, -100, 0);
}

@Test
public void testHorizontalScrollLeftSide() {
scrollTabPane(Side.LEFT, 100, 0);
}

private void scrollTabPane(Side side, double deltaX, double deltaY) {
tabPane.setMaxSize(400, 100);
tabPane.setSide(side);
for (int i = 0; i < 40; i++) {
Tab tab = new Tab("Tab " + (1000 + i));
tabPane.getTabs().add(tab);
}
root.getChildren().add(tabPane);
stage.show();

Bounds firstTabBounds = tabPane.lookupAll(".tab-label")
.stream()
.findFirst()
.map(n -> n.localToScene(n.getLayoutBounds()))
.orElse(null);
assertNotNull(firstTabBounds);

Bounds layoutBounds = tabPane.getLayoutBounds();
double minX = tabPane.localToScene(layoutBounds).getMinX();
double minY = tabPane.localToScene(layoutBounds).getMinY();
double minScrX = tabPane.localToScreen(layoutBounds).getMinX();
double minScrY = tabPane.localToScreen(layoutBounds).getMinY();
double x = 50;
double y = 10;

SceneHelper.processMouseEvent(scene,
MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_MOVED, minX + x, minY + y));
tk.firePulse();

StackPane tabHeaderArea = (StackPane) tabPane.lookup(".tab-header-area");
assertNotNull(tabHeaderArea);

Event.fireEvent(tabHeaderArea, new ScrollEvent(
ScrollEvent.SCROLL,
minX + x, minY + y,
minScrX + x, minScrY + y,
false, false, false, false, true, false,
deltaX, deltaY, deltaX, deltaY,
ScrollEvent.HorizontalTextScrollUnits.NONE, 0.0,
ScrollEvent.VerticalTextScrollUnits.NONE, 0.0,
0, null));
tk.firePulse();

Bounds newFirstTabBounds = tabPane.lookupAll(".tab-label")
.stream()
.findFirst()
.map(n -> n.localToScene(n.getLayoutBounds()))
.orElse(null);
assertNotNull(newFirstTabBounds);

if (side.equals(Side.TOP) || side.equals(Side.BOTTOM)) {
double delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX;
assertEquals(firstTabBounds.getMinX() + delta, newFirstTabBounds.getMinX(), 0);
assertEquals(firstTabBounds.getMinY(), newFirstTabBounds.getMinY(), 0);
} else {
assertEquals(firstTabBounds.getMinX(), newFirstTabBounds.getMinX(), 0);
assertEquals(firstTabBounds.getMinY() - deltaY, newFirstTabBounds.getMinY(), 0);
}
}
}

1 comment on commit b8a7a68

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.