From c1f9a76e1ed0ea7a9181bb8b5117224dcd8389a1 Mon Sep 17 00:00:00 2001 From: mkpaz Date: Mon, 29 May 2023 20:58:51 +0400 Subject: [PATCH] Add Notification control --- .../java/atlantafx/base/controls/Message.java | 5 +- .../atlantafx/base/controls/MessageSkin.java | 4 +- .../atlantafx/base/controls/Notification.java | 168 +++++++++++++ .../base/controls/NotificationSkin.java | 176 ++++++++++++++ .../atlantafx/base/controls/TileSkin.java | 2 +- .../atlantafx/base/controls/TileSkinBase.java | 16 +- .../atlantafx/sampler/layout/MainModel.java | 5 +- .../java/atlantafx/sampler/layout/Nav.java | 2 + .../page/components/NotificationPage.java | 227 ++++++++++++++++++ .../atlantafx/sampler/images/info_32.png | Bin 0 -> 1104 bytes .../atlantafx/sampler/images/warning_32.png | Bin 0 -> 1969 bytes styles/src/components/_index.scss | 1 + styles/src/components/_message.scss | 10 +- styles/src/components/_modal-pane.scss | 7 +- styles/src/components/_notification.scss | 159 ++++++++++++ styles/src/nord-dark.scss | 12 + styles/src/nord-light.scss | 12 + 17 files changed, 782 insertions(+), 24 deletions(-) create mode 100644 base/src/main/java/atlantafx/base/controls/Notification.java create mode 100644 base/src/main/java/atlantafx/base/controls/NotificationSkin.java create mode 100644 sampler/src/main/java/atlantafx/sampler/page/components/NotificationPage.java create mode 100644 sampler/src/main/resources/atlantafx/sampler/images/info_32.png create mode 100644 sampler/src/main/resources/atlantafx/sampler/images/warning_32.png create mode 100644 styles/src/components/_notification.scss diff --git a/base/src/main/java/atlantafx/base/controls/Message.java b/base/src/main/java/atlantafx/base/controls/Message.java index 4af7c12..d5f3cdd 100644 --- a/base/src/main/java/atlantafx/base/controls/Message.java +++ b/base/src/main/java/atlantafx/base/controls/Message.java @@ -72,10 +72,7 @@ public class Message extends TileBase { } /** - * The property representing the user specified close handler. Note that - * if you have also specified the ModalPane instance or CSS selector, this - * handler will be executed after the default close handler. Therefore, you - * can use it to perform arbitrary actions on dialog close. + * The property representing the user specified close handler. */ protected final ObjectProperty> onClose = new SimpleObjectProperty<>(this, "onClose"); diff --git a/base/src/main/java/atlantafx/base/controls/MessageSkin.java b/base/src/main/java/atlantafx/base/controls/MessageSkin.java index 186f47d..c3c05c7 100644 --- a/base/src/main/java/atlantafx/base/controls/MessageSkin.java +++ b/base/src/main/java/atlantafx/base/controls/MessageSkin.java @@ -27,7 +27,7 @@ public class MessageSkin extends TileSkinBase { o -> pseudoClassStateChanged(Styles.STATE_INTERACTIVE, getSkinnable().getActionHandler() != null) ); - root.setOnMouseClicked(e -> { + container.setOnMouseClicked(e -> { if (getSkinnable().getActionHandler() != null) { getSkinnable().getActionHandler().run(); } @@ -65,7 +65,7 @@ public class MessageSkin extends TileSkinBase { layoutInArea(closeButton, w - lb.getWidth() - 5, 5, lb.getWidth(), lb.getHeight(), -1, HPos.RIGHT, VPos.TOP); } - layoutInArea(root, x, y, w, h, -1, HPos.CENTER, VPos.CENTER); + layoutInArea(container, x, y, w, h, -1, HPos.CENTER, VPos.CENTER); } @Override diff --git a/base/src/main/java/atlantafx/base/controls/Notification.java b/base/src/main/java/atlantafx/base/controls/Notification.java new file mode 100644 index 0000000..0f6dd61 --- /dev/null +++ b/base/src/main/java/atlantafx/base/controls/Notification.java @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: MIT */ + +package atlantafx.base.controls; + +import javafx.beans.NamedArg; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.Event; +import javafx.event.EventHandler; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.Control; +import javafx.scene.control.MenuItem; +import javafx.scene.control.Skin; +import javafx.scene.layout.Region; +import org.jetbrains.annotations.Nullable; + +/** + * The Notification control is intended for displaying alerts and messages + * to users as pop-ups. It's customizable with different colors and icons, + * can contain a graphic or image, along with the message and additional actions + * for users to take. The purpose of this control is to immediately notify users + * of significant events and provide them with quick access to related actions without + * interrupting their workflow. + */ +public class Notification extends Control { + + public Notification() { + this(null, null); + } + + public Notification(@Nullable @NamedArg("message") String message) { + this(message, null); + } + + public Notification(@Nullable @NamedArg("message") String message, + @Nullable @NamedArg("graphic") Node graphic) { + super(); + + setMessage(message); + setGraphic(graphic); + + // set reasonable default width + setPrefWidth(400); + setMaxWidth(Region.USE_PREF_SIZE); + + getStyleClass().add("notification"); + } + + @Override + protected Skin createDefaultSkin() { + return new NotificationSkin(this); + } + + /////////////////////////////////////////////////////////////////////////// + // Properties // + /////////////////////////////////////////////////////////////////////////// + + /** + * Represents an optional graphical component that can be displayed alongside + * the notification message. + */ + private final ObjectProperty graphic = new SimpleObjectProperty<>(this, "graphic"); + + public Node getGraphic() { + return graphic.get(); + } + + public ObjectProperty graphicProperty() { + return graphic; + } + + public void setGraphic(Node graphic) { + this.graphic.set(graphic); + } + + /** + * Stores a short text message that will be displayed to users when the + * notification appears. This property doesn't support the formatted text. + */ + private final StringProperty message = new SimpleStringProperty(this, "message"); + + public String getMessage() { + return message.get(); + } + + public StringProperty messageProperty() { + return message; + } + + public void setMessage(String message) { + this.message.set(message); + } + + /** + * Specifies the primary actions associated with this notification. + * + *

This property is used to store one or more action buttons that will + * be displayed at the bottom of the notification when it appears. + */ + private final ReadOnlyObjectWrapper> primaryActions = + new ReadOnlyObjectWrapper<>(this, "primaryActions", FXCollections.observableArrayList()); + + public ObservableList