diff --git a/Dorkbox-Util/src/dorkbox/util/javafx/Growl.java b/Dorkbox-Util/src/dorkbox/util/javafx/Growl.java deleted file mode 100644 index 0b9c0a6..0000000 --- a/Dorkbox-Util/src/dorkbox/util/javafx/Growl.java +++ /dev/null @@ -1,281 +0,0 @@ -/** - * Copyright (c) 2014, ControlsFX - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of ControlsFX, any associated website, nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * MODIFIED BY DORKBOX, LLC - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.javafx; - -import com.sun.javafx.application.PlatformImpl; -import dorkbox.util.JavaFxUtil; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.geometry.Pos; -import javafx.scene.Node; -import javafx.scene.image.ImageView; -import javafx.stage.Window; -import javafx.util.Duration; -import org.controlsfx.tools.Utils; - -import java.util.ArrayList; -import java.util.List; - -/** - * An API to show popup notification messages to the user in the corner of their - * screen, unlike the {@link org.controlsfx.control.NotificationPane} which shows notification messages - * within your application itself. - * - *

Screenshot

- *

- * The following screenshot shows a sample notification rising from the - * bottom-right corner of my screen: - * - *
- *
- * - * - *

Code Example:

- *

- * To create the notification shown in the screenshot, simply do the following: - * - *

- * {@code
- * Notifications.create()
- *              .title("Title Text")
- *              .text("Hello World 0!")
- *              .showWarning();
- * }
- * 
- */ -public class Growl { - - /*************************************************************************** - * * Static fields * * - **************************************************************************/ - - private static final String STYLE_CLASS_DARK = "dark"; //$NON-NLS-1$ - - /*************************************************************************** - * * Private fields * * - **************************************************************************/ - - String title; - String text; - Node graphic; - - Pos position = Pos.BOTTOM_RIGHT; - private Duration hideAfterDuration = Duration.seconds(5); - boolean hideCloseButton; - private EventHandler onAction; - Window owner; - - List styleClass = new ArrayList<>(); - - /*************************************************************************** - * * Constructors * * - **************************************************************************/ - - // we do not allow instantiation of the Notifications class directly - users - // must go via the builder API (that is, calling create()) - private - Growl() { - // no-op - } - - /*************************************************************************** - * * Public API * * - **************************************************************************/ - - /** - * Call this to begin the process of building a notification to show. - */ - public static - Growl create() { - // make sure that javafx application thread is started - // Note that calling PlatformImpl.startup more than once is OK - PlatformImpl.startup(() -> { - // No need to do anything here - }); - - return new Growl(); - } - - /** - * Specify the text to show in the notification. - */ - public - Growl text(String text) { - this.text = text; - return this; - } - - /** - * Specify the title to show in the notification. - */ - public - Growl title(String title) { - this.title = title; - return this; - } - - /** - * Specify the graphic to show in the notification. - */ - public - Growl graphic(Node graphic) { - this.graphic = graphic; - return this; - } - - /** - * Specify the position of the notification on screen, by default it is - * {@link Pos#BOTTOM_RIGHT bottom-right}. - */ - public - Growl position(Pos position) { - this.position = position; - return this; - } - - /** - * The dialog window owner - if specified the notifications will be inside - * the owner, otherwise the notifications will be shown within the whole - * screen. - */ - public - Growl owner(Object owner) { - this.owner = Utils.getWindow(owner); - return this; - } - - /** - * Specify the duration that the notification should show, after which it - * will be hidden. - */ - public - Growl hideAfter(Duration duration) { - this.hideAfterDuration = duration; - return this; - } - - /** - * Specify what to do when the user clicks on the notification (in addition - * to the notification hiding, which happens whenever the notification is - * clicked on). - */ - public - Growl onAction(EventHandler onAction) { - this.onAction = onAction; - return this; - } - - /** - * Specify that the notification should use the built-in dark styling, - * rather than the default 'modena' notification style (which is a - * light-gray). - */ - public - Growl darkStyle() { - styleClass.add(STYLE_CLASS_DARK); - return this; - } - - /** - * Specify that the close button in the top-right corner of the notification - * should not be shown. - */ - public - Growl hideCloseButton() { - this.hideCloseButton = true; - return this; - } - - /** - * Instructs the notification to be shown, and that it should use the built-in 'warning' graphic. - */ - public - void showWarning() { - graphic(new ImageView(Growl.class.getResource("/org/controlsfx/dialog/dialog-warning.png") - .toExternalForm())); //$NON-NLS-1$ - show(); - } - - /** - * Instructs the notification to be shown, and that it should use the built-in 'information' graphic. - */ - public - void showInformation() { - graphic(new ImageView(Growl.class.getResource("/org/controlsfx/dialog/dialog-information.png") - .toExternalForm())); //$NON-NLS-1$ - show(); - } - - /** - * Instructs the notification to be shown, and that it should use the built-in 'error' graphic. - */ - public - void showError() { - graphic(new ImageView(Growl.class.getResource("/org/controlsfx/dialog/dialog-error.png") - .toExternalForm())); //$NON-NLS-1$ - show(); - } - - /** - * Instructs the notification to be shown, and that it should use the built-in 'confirm' graphic. - */ - public - void showConfirm() { - graphic(new ImageView(Growl.class.getResource("/org/controlsfx/dialog/dialog-confirm.png") - .toExternalForm())); //$NON-NLS-1$ - show(); - } - - /** - * Instructs the notification to be shown. - */ - public - void show() { - // we can't use regular popup, because IF WE HAVE NO OWNER, it won't work! - // instead, we just create a JFRAME (and use our StageViaSwing class) to put javaFX inside it - JavaFxUtil.invokeAndWait(() -> new GrowlPopup(this).show()); - } - - -} - diff --git a/Dorkbox-Util/src/dorkbox/util/javafx/GrowlNotification.java b/Dorkbox-Util/src/dorkbox/util/javafx/GrowlNotification.java deleted file mode 100644 index 10e6efb..0000000 --- a/Dorkbox-Util/src/dorkbox/util/javafx/GrowlNotification.java +++ /dev/null @@ -1,169 +0,0 @@ -/** - * Copyright (c) 2014, ControlsFX All rights reserved. - *

- * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are - * met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. * Neither the name of ControlsFX, any associated website, nor the - * names of its contributors may be used to endorse or promote products derived from this software without specific prior written - * permission. - *

- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CONTROLSFX - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *

- * MODIFIED BY DORKBOX, LLC Copyright 2015 dorkbox, llc - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may - * obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ -package dorkbox.util.javafx; - -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.geometry.VPos; -import javafx.scene.Node; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Priority; -import javafx.scene.layout.Region; -import javafx.scene.layout.StackPane; - -public -class GrowlNotification extends Region { - - private static final double MIN_HEIGHT = 40; - - private final String textText; - private final Node graphicNode; - - protected final GridPane pane; - - public - GrowlNotification(final Growl notification) { - this.textText = notification.text; - this.graphicNode = notification.graphic; - - getStyleClass().add("notification-bar"); //$NON-NLS-1$ - - setVisible(true); - - pane = new GridPane(); - pane.getStyleClass() - .add("pane"); //$NON-NLS-1$ - pane.setAlignment(Pos.BASELINE_LEFT); - getChildren().setAll(pane); - - // put it all together - pane.getChildren() - .clear(); - - int row = 0; - - // title - if (notification.title != null && !notification.title.isEmpty()) { - Label title = new Label(); - title.getStyleClass() - .add("title"); //$NON-NLS-1$ - title.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); - GridPane.setHgrow(title, Priority.ALWAYS); - - title.setText(notification.title); - pane.add(title, 0, row++); - } - - Region spacer = new Region(); - spacer.setPrefHeight(10); - - pane.add(spacer, 0, row++); - - // graphic + text area - Label label = new Label(); - label.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); - GridPane.setVgrow(label, Priority.ALWAYS); - GridPane.setHgrow(label, Priority.ALWAYS); - - label.setText(textText); - label.setGraphic(graphicNode); - pane.add(label, 0, row); - - - // close button - if (!notification.hideCloseButton) { - Button closeBtn = new Button(); - closeBtn.getStyleClass() - .setAll("close-button"); //$NON-NLS-1$ - - StackPane graphic = new StackPane(); - graphic.getStyleClass() - .setAll("graphic"); //$NON-NLS-1$ - - closeBtn.setGraphic(graphic); - closeBtn.setMinSize(17, 17); - closeBtn.setPrefSize(17, 17); - - GridPane.setMargin(closeBtn, new Insets(0, 0, 0, 8)); - - // position the close button in the best place, depending on the height - double minHeight = minHeight(-1); - GridPane.setValignment(closeBtn, minHeight == MIN_HEIGHT ? VPos.CENTER : VPos.TOP); - closeBtn.setOnAction(arg0 -> hide()); - - pane.add(closeBtn, 2, 0, 1, row + 1); - } - } - - public - void hide() { - } - - @Override - protected - void layoutChildren() { - final double w = getWidth(); - double h = computePrefHeight(-1); - - pane.resize(w, h); - } - - @Override - protected - double computeMinWidth(double height) { - String text = textText; - Node graphic = graphicNode; - - if ((text == null || text.isEmpty()) && (graphic != null)) { - return graphic.minWidth(height) + 20; - } - return 400; - } - - @Override - protected - double computeMinHeight(double width) { - String text = textText; - Node graphic = graphicNode; - - if ((text == null || text.isEmpty()) && (graphic != null)) { - return graphic.minHeight(width) + 20; - } - return 100; - } - - @Override - protected - double computePrefHeight(double width) { - return Math.max(pane.prefHeight(width), minHeight(width)); - } -} - diff --git a/Dorkbox-Util/src/dorkbox/util/javafx/GrowlPopup.java b/Dorkbox-Util/src/dorkbox/util/javafx/GrowlPopup.java deleted file mode 100644 index 6b6829e..0000000 --- a/Dorkbox-Util/src/dorkbox/util/javafx/GrowlPopup.java +++ /dev/null @@ -1,467 +0,0 @@ -package dorkbox.util.javafx; - -import dorkbox.util.ScreenUtil; -import dorkbox.util.SwingUtil; -import javafx.animation.*; -import javafx.collections.ObservableList; -import javafx.embed.swing.SwingFXUtils; -import javafx.geometry.Pos; -import javafx.geometry.VPos; -import javafx.scene.Scene; -import javafx.scene.image.ImageView; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Priority; -import javafx.scene.layout.StackPane; -import javafx.scene.layout.VBox; -import javafx.stage.Stage; -import javafx.util.Duration; -import org.controlsfx.tools.Utils; - -import java.awt.*; -import java.awt.geom.*; -import java.util.ArrayList; - -/** - * - */ -public -class GrowlPopup { - - private static final java.util.List popups = new ArrayList<>(); - // for animating in the notifications - private static final ParallelTransition parallelTransition = new ParallelTransition(); - - private static final double padding = 40; - - private final GrowlPopupViaSwing frame; - - final double startX; - final double startY; - final javafx.stage.Window window; - final double screenWidth; - final double screenHeight; - - private final Pos position; - - private final double anchorX; - private final double anchorY; - - final Timeline animationTimeline = new Timeline(); - private double newX; - private double newY; - - GrowlPopup(final Growl notification) { - final Image icon; - if (notification.graphic instanceof ImageView) { - icon = SwingFXUtils.fromFXImage(((ImageView) notification.graphic).getImage(), null); - } else { - icon = SwingUtil.BLANK_ICON; - } - - // created on the swing EDT - frame = GrowlPopupViaSwing.create(icon, notification.title); - // don't actually show anything. This will be done by our own animator - frame.setShowAnimation(() -> { - frame.completeShowTransition(); - }); - - // set screen position - final javafx.stage.Window owner = notification.owner; - if (owner == null) { - final Point mouseLocation = MouseInfo.getPointerInfo() - .getLocation(); - - final GraphicsDevice deviceAtMouse = ScreenUtil.getGraphicsDeviceAt(mouseLocation); - - final Rectangle screenBounds = deviceAtMouse.getDefaultConfiguration() - .getBounds(); - - /* - * If the owner is not set, we work with the whole screen. - * EDIT: we use the screen that the mouse is currently on. - */ - startX = screenBounds.getX(); - startY = screenBounds.getY(); - screenWidth = screenBounds.getWidth(); - screenHeight = screenBounds.getHeight(); - - window = Utils.getWindow(null); - } - else { - /* - * If the owner is set, we will make the notifications popup - * inside its window. - */ - startX = owner.getX(); - startY = owner.getY(); - screenWidth = owner.getWidth(); - screenHeight = owner.getHeight(); - window = owner; - } - - - // need to install our CSS - if (owner instanceof Stage) { - Scene ownerScene = owner.getScene(); - ownerScene.getStylesheets() - .add(org.controlsfx.control.Notifications.class.getResource("notificationpopup.css") - .toExternalForm()); //$NON-NLS-1$ - } - - - this.position = notification.position; - - - VBox region = new VBox(); - final ObservableList styleClass1 = region.getStyleClass(); - styleClass1.add("notification-bar"); - styleClass1.addAll(notification.styleClass); - - region.setVisible(true); - region.setMinWidth(300); - region.setMinHeight(40); - - - GridPane pane = new GridPane(); - pane.getStyleClass() - .add("pane"); - pane.setAlignment(Pos.BASELINE_LEFT); - region.getChildren() - .add(pane); - -// pane.setStyle("-fx-background-color: #2046ff;"); - - // title - if (notification.title != null && !notification.title.isEmpty()) { - javafx.scene.control.Label titleLabel = new javafx.scene.control.Label(); - titleLabel.getStyleClass() - .add("title"); - titleLabel.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); - GridPane.setHgrow(titleLabel, Priority.ALWAYS); - - titleLabel.setText(notification.title); - pane.add(titleLabel, 0, 0); - } - - - // close button - if (!notification.hideCloseButton) { - javafx.scene.control.Button closeBtn = new javafx.scene.control.Button(); - closeBtn.getStyleClass() - .setAll("close-button"); - - StackPane graphic = new StackPane(); - graphic.getStyleClass() - .setAll("graphic"); - - closeBtn.setGraphic(graphic); - closeBtn.setMinSize(17, 17); - closeBtn.setPrefSize(17, 17); - - GridPane.setMargin(closeBtn, new javafx.geometry.Insets(0, 0, 0, 8)); - - // position the close button in the best place, depending on the height - double minHeight = pane.minHeight(-1); - GridPane.setValignment(closeBtn, minHeight == 40 ? VPos.CENTER : VPos.TOP); - - closeBtn.setOnAction(arg0 -> createHideTimeline(Duration.ZERO).play()); - - pane.add(closeBtn, 2, 0, 1, 1); - } - - - // graphic + text area - javafx.scene.control.Label label = new javafx.scene.control.Label(); - label.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); - GridPane.setVgrow(label, Priority.ALWAYS); - GridPane.setHgrow(label, Priority.ALWAYS); - - label.setText(notification.text); - label.setGraphic(notification.graphic); - label.setPadding(new javafx.geometry.Insets(10, 0, 10, 5)); - pane.add(label, 0, 2); - - - region.setOnMouseClicked(e -> createHideTimeline(Duration.ZERO).play()); - - Scene scene = new Scene(region); - scene.getStylesheets() - .add(org.controlsfx.control.Notifications.class.getResource("notificationpopup.css") - .toExternalForm()); //$NON-NLS-1$ - frame.setScene(scene); - - frame.sizeToScene(); - - // determine location for the popup - final Dimension size = frame.getSize(); - final double barWidth = size.getWidth(); - final double barHeight = size.getHeight(); - - // get anchorX - switch (position) { - case TOP_LEFT: - case CENTER_LEFT: - case BOTTOM_LEFT: - anchorX = startX + padding; - break; - - case TOP_CENTER: - case CENTER: - case BOTTOM_CENTER: - anchorX = startX + (screenWidth / 2.0) - barWidth / 2.0 - padding / 2.0; - break; - - default: - case TOP_RIGHT: - case CENTER_RIGHT: - case BOTTOM_RIGHT: - anchorX = startX + screenWidth - barWidth - padding; - break; - } - - // get anchorY - switch (position) { - case TOP_LEFT: - case TOP_CENTER: - case TOP_RIGHT: - anchorY = padding + startY; - break; - - case CENTER_LEFT: - case CENTER: - case CENTER_RIGHT: - anchorY = startY + (screenHeight / 2.0) - barHeight / 2.0 - padding / 2.0; - break; - - default: - case BOTTOM_LEFT: - case BOTTOM_CENTER: - case BOTTOM_RIGHT: - anchorY = startY + screenHeight - barHeight - padding; - break; - } - } - - public - void show() { - this.newX = anchorX; - this.newY = anchorY; - frame.show(anchorX, anchorY); - - addPopupToMap(); - - // begin a timeline to get rid of the popup (default is 5 seconds) -// if (notification.hideAfterDuration != Duration.INDEFINITE) { -// Timeline timeline = createHideTimeline(popup, growlNotification, p, notification.hideAfterDuration); -// timeline.play(); -// } - } - - @Override - public - boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - final GrowlPopup that = (GrowlPopup) o; - return frame.equals(that.frame); - } - - @Override - public - int hashCode() { - return frame.hashCode(); - } - - void close() { - // set it off screen (which is what the close method also does) - this.newX = Short.MIN_VALUE; - this.newY = Short.MIN_VALUE; - - frame.close(); - } - - Dimension2D getSize() { - return frame.getSize(); - } - - void animateToTarget(final boolean shouldFadeIn, final double x, final double y) { - - if (shouldFadeIn) { - if (frame.getOpacityProperty().getValue() == 0F) { - frame.setLocation((int)x, (int)y); - Timeline timeline = new Timeline(); - timeline.getKeyFrames() - .addAll(new KeyFrame(Duration.millis(500), new KeyValue(frame.getOpacityProperty(), 1F, Interpolator.LINEAR))); - timeline.play(); - } - } else { - frame.setLocation((int)x, (int)y); - -// final boolean xEqual = x == frame.getX(); -// final boolean yEqual = y == frame.getY(); -// -// if (xEqual && yEqual) { -// return; -// } -//Transition t = new Transition() { -// { -// setCycleDuration(Duration.millis(500)); -// } -// -// @Override -// protected -// void interpolate(final double frac) { -// final double y1 = frame.getY(); -// final double distance = ((y-y1) * frac); -// -// frame.setLocation(x, y1 + distance); -// } -// }; -// parallelTransition.getChildren().add(t); - } - -// final ObservableList keyFrames = animationTimeline.getKeyFrames(); -// keyFrames.clear(); -// -// if (!xEqual) { -// keyFrames.addAll(new KeyFrame(Duration.millis(300), new KeyValue(xProperty, x, Interpolator.EASE_OUT))); -// } -// if (!yEqual) { -// keyFrames.addAll(new KeyFrame(Duration.millis(300), new KeyValue(yProperty, y, Interpolator.EASE_OUT))); -// } -// -// // x/y can change, keep running the animation until it's stable -// animationTimeline.setOnFinished(event -> animateToTarget(GrowlPopup.this.newX, GrowlPopup.this.newY)); -// animationTimeline.playFromStart(); -// } -// } - } - - private - Timeline createHideTimeline(final Duration startDelay) { - Timeline timeline = new Timeline(new KeyFrame(Duration.millis(500), new KeyValue(frame.getOpacityProperty(), 0.0F))); - timeline.setDelay(startDelay); - timeline.setOnFinished(e -> { - close(); - removePopupFromMap(); - }); - - return timeline; - } - - // only called on the JavaFX app thread - private - void addPopupToMap() { - popups.add(this); - doAnimation(true); - } - - // only called on the JavaFX app thread - private - void removePopupFromMap() { - popups.remove(this); - - if (!popups.isEmpty()) { - doAnimation(false); - } - } - - // only called on the JavaFX app thread - private static - void doAnimation(boolean shouldFadeIn) { - parallelTransition.stop(); - parallelTransition.getChildren() - .clear(); - - - // the logic for this, is that the first popup in place, doesn't move. EVERY other popup after it will be moved - // this behavior trickles down to the remaining popups, until all popups have been assigned new locations - - final int length = popups.size(); - final GrowlPopup[] copies = popups.toArray(new GrowlPopup[length]); - - for (int i = 0; i < length; i++) { - final GrowlPopup popup = copies[i]; - final boolean isShowFromTop = isShowFromTop(popup.position); - - final Dimension2D size = popup.getSize(); - final double x = popup.newX; - final double y = popup.newY; - final double width = size.getWidth(); - final double height = size.getHeight(); - - if (isShowFromTop) { - for (int j = i+1; j < length; j++) { - final GrowlPopup copy = copies[j]; - - final Dimension2D size1 = copy.getSize(); - final double x1 = copy.newX; - final double y1 = copy.newY; - final double width1 = size1.getWidth(); - final double height1 = size1.getHeight(); - - if (intersectRect(x, y, width, height, x1, y1, width1, height1)) { - copy.newY = y + height + 10; - } - } - - popup.animateToTarget(shouldFadeIn, popup.newX, popup.newY); - } - -// -// // first one is always as base location with padding -// if (i == 0) { -// newY = 30 + _popup.startY; -// } -// else { -// // we add a little bit of padding, so they are not on top of eachother -// newY += popupHeight + 10; -// } -// } -// else { -// if (i == size - 1) { -//// newY = changedPopup.getTargetY() - popupHeight; -// } -// else { -// newY -= popupHeight; -// } -// } -// -// if (newY < 0) { -// System.err.println("closing"); -// _popup.close(); -// continue; -// } - -// popup.animateToTarget(popup.anchorX, newY); - } - - if (!parallelTransition.getChildren().isEmpty()) { -// parallelTransition.play(); - } - } - - static boolean intersectRect(double x1, double y1, double w1, double h1, double x2, double y2, double w2, double h2) { - return intersectRange(x1, x1+w1, x2, x2+w2) && intersectRange(y1, y1+h1, y2, y2+h2); - } - static boolean intersectRange(double ax1, double ax2, double bx1, double bx2) { - return Math.max(ax1, bx1) <= Math.min(ax2, bx2); - } - - private static - boolean isShowFromTop(final Pos p) { - switch (p) { - case TOP_LEFT: - case TOP_CENTER: - case TOP_RIGHT: - return true; - default: - return false; - } - } -} diff --git a/Dorkbox-Util/src/dorkbox/util/javafx/GrowlPopupViaSwing.java b/Dorkbox-Util/src/dorkbox/util/javafx/GrowlPopupViaSwing.java deleted file mode 100644 index cd4c4ab..0000000 --- a/Dorkbox-Util/src/dorkbox/util/javafx/GrowlPopupViaSwing.java +++ /dev/null @@ -1,70 +0,0 @@ -package dorkbox.util.javafx; - -import dorkbox.util.SwingUtil; - -import java.awt.*; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * - */ -public -class GrowlPopupViaSwing extends StageViaSwing { - - private static - AtomicInteger ID = new AtomicInteger(0); - - @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") - static - GrowlPopupViaSwing create(final Image icon, final String title) { - final GrowlPopupViaSwing[] returnVal = new GrowlPopupViaSwing[1]; - - // this MUST happen on the EDT! - SwingUtil.invokeAndWait(() -> { - synchronized (returnVal) { - returnVal[0] = new GrowlPopupViaSwing(icon, title, ID.getAndIncrement()); - } - }); - - synchronized (returnVal) { - return returnVal[0]; - } - } - - private final int id; - - - - GrowlPopupViaSwing(final Image icon, final String title, final int ID) { - super(); - - this.id = ID; - - frame.setAlwaysOnTop(true); - frame.setResizable(false); - frame.setIconImage(icon); - frame.setTitle(title); - } - - @Override - public - boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - final GrowlPopupViaSwing that = (GrowlPopupViaSwing) o; - - return id == that.id; - - } - - @Override - public - int hashCode() { - return id; - } -}