package jfxtras.scene.menu.test;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.event.ActionEvent;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Popup;
import javafx.stage.Window;
import jfxtras.test.JFXtrasGuiTest;
import jfxtras.scene.layout.CircularPane;
import jfxtras.scene.menu.CirclePopupMenu;
import jfxtras.test.AssertNode;
import jfxtras.test.AssertNode.A;
import jfxtras.test.TestUtil;
import jfxtras.util.Implements;
import jfxtras.util.NodeUtil;
import org.junit.Assert;
import org.junit.Test;
/**
*
* @author Tom Eugelink
*
*/
public class CirclePopupMenuTest extends JFXtrasGuiTest {
@Override
protected Parent getRootNode() {
// use a pane to force the scene large enough
stackPane = new StackPane();
stackPane.setMinSize(600, 600);
// place label
label = new Label();
stackPane.getChildren().add(label);
// create menu
circlePopupMenu = new CirclePopupMenu(this.stackPane, MouseButton.SECONDARY)
.withAnimationInterpolation(null);
circlePopupMenu.getItems().addAll(facebookMenuItem, googleMenuItem, skypeMenuItem, twitterMenuItem, windowsMenuItem);
return stackPane;
}
private StackPane stackPane = null;
private Label label = null;
private CirclePopupMenu circlePopupMenu = null;
final private MenuItem facebookMenuItem = new MenuItem("Facebook", new ImageView(new Image(this.getClass().getResourceAsStream("social_facebook_button_blue.png"))));
final private MenuItem googleMenuItem = new MenuItem("Google", new ImageView(new Image(this.getClass().getResourceAsStream("social_google_button_blue.png"))));
final private MenuItem skypeMenuItem = new MenuItem("Skype", new ImageView(new Image(this.getClass().getResourceAsStream("social_skype_button_blue.png"))));
final private MenuItem twitterMenuItem = new MenuItem("Twitter", new ImageView(new Image(this.getClass().getResourceAsStream("social_twitter_button_blue.png"))));
final private MenuItem windowsMenuItem = new MenuItem("Windows", new ImageView(new Image(this.getClass().getResourceAsStream("social_windows_button.png"))));
@Test
public void showAndHide() {
setLabel("showAndHide");
// not visible
Assert.assertFalse(circlePopupMenu.isShown());
// click in the center
moveMouseToCenter();
click(MouseButton.SECONDARY);
Assert.assertTrue(circlePopupMenu.isShown());
//generateSource();
assertWH(findCircularPane(), 118.47869355660265, 114.89486277938934);
new AssertNode(findCircularPane().getChildren().get(0)).assertXYWH(65.86676377627084, 6.627416997969522, 32.0, 32.0, 0.01).assertClassName("jfxtras.scene.menu.CirclePopupMenu$CirclePopupMenuNode");
new AssertNode(findCircularPane().getChildren().get(1)).assertXYWH(79.85127655863312, 49.66732176366279, 32.0, 32.0, 0.01).assertClassName("jfxtras.scene.menu.CirclePopupMenu$CirclePopupMenuNode");
new AssertNode(findCircularPane().getChildren().get(2)).assertXYWH(43.239346778301325, 76.26744578141981, 32.0, 32.0, 0.01).assertClassName("jfxtras.scene.menu.CirclePopupMenu$CirclePopupMenuNode");
new AssertNode(findCircularPane().getChildren().get(3)).assertXYWH(6.627416997969522, 49.66732176366279, 32.0, 32.0, 0.01).assertClassName("jfxtras.scene.menu.CirclePopupMenu$CirclePopupMenuNode");
new AssertNode(findCircularPane().getChildren().get(4)).assertXYWH(20.611929780331792, 6.627416997969526, 32.0, 32.0, 0.01).assertClassName("jfxtras.scene.menu.CirclePopupMenu$CirclePopupMenuNode");
// move out of the menu
moveMouseToLeftCorner();
Assert.assertFalse(circlePopupMenu.isShown());
}
@Test
public void isClickHandled() {
setLabel("isClickHandled");
// show menu
moveMouseToCenter();
click(MouseButton.SECONDARY);
// click first item
Assert.assertEquals(0, menuItemClickAtomicInteger.get());
facebookMenuItem.setOnAction(this::handleByIncrementingMenuItemClick); // this should be #1
click("#CirclePopupMenuNode#1");
Assert.assertEquals(1, menuItemClickAtomicInteger.get());
Assert.assertFalse(circlePopupMenu.isShown());
// show menu
moveMouseToCenter();
click(MouseButton.SECONDARY);
// click second menu item
click("#CirclePopupMenuNode#2"); // this has no action handler attached
Assert.assertEquals(1, menuItemClickAtomicInteger.get());
Assert.assertFalse(circlePopupMenu.isShown());
}
@Test
public void isClickedThrough() {
setLabel("isClickedThrough");
// create underlying button
AtomicInteger underlyingClickAtomicInteger = new AtomicInteger();
TestUtil.runThenWaitForPaintPulse( () -> {
Button lUnderlyingButton = new Button("click me but a bit longer");
lUnderlyingButton.setId("UnderlyingButton");
stackPane.getChildren().add(1, lUnderlyingButton); // index = 1: below menu, above label
lUnderlyingButton.setOnAction((actionEvent) -> {
underlyingClickAtomicInteger.incrementAndGet();
});
});
// click underlying button
Assert.assertEquals(0, underlyingClickAtomicInteger.get());
click("#UnderlyingButton");
Assert.assertEquals(1, underlyingClickAtomicInteger.get());
// show menu (positioned over the button)
moveMouseToCenter();
click(MouseButton.SECONDARY);
// click item that is placed over the button
click("#CirclePopupMenuNode#4");
Assert.assertFalse(circlePopupMenu.isShown());
// click underlying button again
click("#UnderlyingButton");
Assert.assertEquals(2, underlyingClickAtomicInteger.get());
}
// =============================================================================================================================================================================================================================
// SUPPORT
@Implements(interfaces=javafx.event.EventHandler.class)
public void handleByIncrementingMenuItemClick(ActionEvent actionEvent) {
menuItemClickAtomicInteger.incrementAndGet();
}
private final AtomicInteger menuItemClickAtomicInteger = new AtomicInteger();
private void assertWH(Pane pane, double w, double h) {
Assert.assertEquals(w, pane.getWidth(), 0.01);
Assert.assertEquals(h, pane.getHeight(), 0.01);
}
private void setLabel(String s) {
TestUtil.runThenWaitForPaintPulse( () -> {
label.setText(s);
});
}
private void generateSource() {
Pane pane = findCircularPane();
System.out.println("> " + label.getText());
System.out.println("assertWH(findCircularPane(), " + pane.getWidth() + ", " + pane.getHeight() + ");");
AssertNode.generateSource("findCircularPane()", pane.getChildren(), EXCLUDED_CLASSES, false, A.XYWH, A.CLASSNAME);
TestUtil.sleep(3000);
}
List<String> EXCLUDED_CLASSES = java.util.Arrays.asList(new String[]{"jfxtras.scene.layout.CircularPane$Bead", "jfxtras.scene.layout.CircularPane$Connector"});
private CircularPane findCircularPane() {
return (CircularPane)findPopup(null).getContent().get(0);
}
private void moveMouseToCenter() {
move(NodeUtil.screenX(stackPane) + (stackPane.getWidth() / 2), NodeUtil.screenY(stackPane) + (stackPane.getHeight() / 2));
}
private void moveMouseToLeftCorner() {
move(NodeUtil.screenX(stackPane) + 5, NodeUtil.screenY(stackPane) + 5);
}
protected Popup findPopup(Node ownedBy) {
TestUtil.waitForPaintPulse();
for (Window w : getWindows() ) {
if (w instanceof Popup) {
Popup lPopup = (Popup)w;
if (ownedBy == null || ownedBy.equals(lPopup.getOwnerNode())) {
return lPopup;
}
}
}
return null;
}
}