From 0674035183e78a2f3fe45bc9c12037e3be620a36 Mon Sep 17 00:00:00 2001 From: kske Date: Sat, 18 Jul 2020 11:50:49 +0200 Subject: [PATCH] Reworked list cell framework to be more extensible --- .../envoy/client/ui/controller/ChatScene.java | 6 +- .../client/ui/listcell/AbstractListCell.java | 48 +++ .../client/ui/listcell/GenericListCell.java | 36 ++ .../client/ui/listcell/ListCellFactory.java | 34 +- .../client/ui/listcell/MessageListCell.java | 31 ++ client/src/main/resources/css/base.css | 18 +- client/src/main/resources/css/dark.css | 4 - client/src/main/resources/fxml/ChatScene.fxml | 388 ++++++++++-------- 8 files changed, 361 insertions(+), 204 deletions(-) create mode 100644 client/src/main/java/envoy/client/ui/listcell/AbstractListCell.java create mode 100644 client/src/main/java/envoy/client/ui/listcell/GenericListCell.java create mode 100644 client/src/main/java/envoy/client/ui/listcell/MessageListCell.java diff --git a/client/src/main/java/envoy/client/ui/controller/ChatScene.java b/client/src/main/java/envoy/client/ui/controller/ChatScene.java index 385fd3f..afc56a8 100644 --- a/client/src/main/java/envoy/client/ui/controller/ChatScene.java +++ b/client/src/main/java/envoy/client/ui/controller/ChatScene.java @@ -35,9 +35,7 @@ import envoy.client.event.MessageCreationEvent; import envoy.client.net.Client; import envoy.client.net.WriteProxy; import envoy.client.ui.*; -import envoy.client.ui.listcell.ChatControl; -import envoy.client.ui.listcell.ListCellFactory; -import envoy.client.ui.listcell.MessageControl; +import envoy.client.ui.listcell.*; import envoy.data.*; import envoy.data.Attachment.AttachmentType; import envoy.event.*; @@ -139,7 +137,7 @@ public final class ChatScene implements Restorable { @FXML private void initialize() { // Initialize message and user rendering - messageList.setCellFactory(new ListCellFactory<>(MessageControl::new)); + messageList.setCellFactory(MessageListCell::new); chatList.setCellFactory(new ListCellFactory<>(ChatControl::new)); settingsButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("settings", DEFAULT_ICON_SIZE))); diff --git a/client/src/main/java/envoy/client/ui/listcell/AbstractListCell.java b/client/src/main/java/envoy/client/ui/listcell/AbstractListCell.java new file mode 100644 index 0000000..e294b15 --- /dev/null +++ b/client/src/main/java/envoy/client/ui/listcell/AbstractListCell.java @@ -0,0 +1,48 @@ +package envoy.client.ui.listcell; + +import javafx.scene.Node; +import javafx.scene.control.ContentDisplay; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; + +/** + * Provides a convenience frame for list cell creation. + *

+ * Project: envoy-client
+ * File: AbstractListCell.java
+ * Created: 18.07.2020
+ * + * @author Kai S. K. Engelbart + * @param the type of element displayed by the list cell + * @param the type of node as which the list element will be displayed + * @since Envoy Client v0.1-beta + */ +public abstract class AbstractListCell extends ListCell { + + protected ListView listView; + + /** + * @param listView the list view inside of which the cell will be displayed + * @since Envoy Client v0.1-beta + */ + public AbstractListCell(ListView listView) { + this.listView = listView; + setContentDisplay(ContentDisplay.GRAPHIC_ONLY); + getStyleClass().add("listElement"); + } + + @Override + protected final void updateItem(T item, boolean empty) { + super.updateItem(item, empty); + setGraphic(empty || item == null ? null : renderItem(item)); + } + + /** + * Converts a list item to a node. This can have side effects on the list cell. + * + * @param item the item to render + * @return a node representing the item + * @since Envoy Client v0.1-beta + */ + protected abstract U renderItem(T item); +} diff --git a/client/src/main/java/envoy/client/ui/listcell/GenericListCell.java b/client/src/main/java/envoy/client/ui/listcell/GenericListCell.java new file mode 100644 index 0000000..ad2b364 --- /dev/null +++ b/client/src/main/java/envoy/client/ui/listcell/GenericListCell.java @@ -0,0 +1,36 @@ +package envoy.client.ui.listcell; + +import java.util.function.Function; + +import javafx.scene.Node; +import javafx.scene.control.ListView; + +/** + * A generic list cell rendering an item using a provided render function. + *

+ * Project: envoy-client
+ * File: GenericListCell.java
+ * Created: 18.07.2020
+ * + * @author Kai S. K. Engelbart + * @param the type of element displayed by the list cell + * @param the type of node as which the list element will be displayed + * @since Envoy Client v0.2-beta + */ +public final class GenericListCell extends AbstractListCell { + + private Function renderer; + + /** + * @param listView the list view inside of which the cell will be displayed + * @param renderer a function converting a list item to a node + * @since Envoy Client v0.1-beta + */ + public GenericListCell(ListView listView, Function renderer) { + super(listView); + this.renderer = renderer; + } + + @Override + protected U renderItem(T item) { return renderer.apply(item); } +} diff --git a/client/src/main/java/envoy/client/ui/listcell/ListCellFactory.java b/client/src/main/java/envoy/client/ui/listcell/ListCellFactory.java index db7483f..018a0ba 100644 --- a/client/src/main/java/envoy/client/ui/listcell/ListCellFactory.java +++ b/client/src/main/java/envoy/client/ui/listcell/ListCellFactory.java @@ -17,41 +17,19 @@ import javafx.util.Callback; * * @author Kai S. K. Engelbart * @param the type of object to display + * @param the type of node displayed * @since Envoy Client v0.1-beta */ -public final class ListCellFactory implements Callback, ListCell> { +public final class ListCellFactory implements Callback, ListCell> { - private final class GenericListCell extends ListCell { - - private ListView listView; - - private GenericListCell(ListView listView) { - this.listView = listView; - getStyleClass().add("listElement"); - } - - @Override - protected void updateItem(T item, boolean empty) { - super.updateItem(item, empty); - if (empty || item == null) { - setText(null); - setGraphic(null); - } else { - final var control = converter.apply(item); - prefWidthProperty().bind(listView.widthProperty().subtract(40)); - setGraphic(control); - } - } - } - - private final Function converter; + private final Function renderer; /** - * @param converter a function converting the type to display into a node + * @param renderer a function converting the type to display into a node * @since Envoy Client v0.1-beta */ - public ListCellFactory(Function converter) { this.converter = converter; } + public ListCellFactory(Function renderer) { this.renderer = renderer; } @Override - public ListCell call(ListView listView) { return new GenericListCell(listView); } + public ListCell call(ListView listView) { return new GenericListCell<>(listView, renderer); } } diff --git a/client/src/main/java/envoy/client/ui/listcell/MessageListCell.java b/client/src/main/java/envoy/client/ui/listcell/MessageListCell.java new file mode 100644 index 0000000..71c2ae2 --- /dev/null +++ b/client/src/main/java/envoy/client/ui/listcell/MessageListCell.java @@ -0,0 +1,31 @@ +package envoy.client.ui.listcell; + +import javafx.scene.control.ListView; + +import envoy.data.Message; + +/** + * A list cell containing messages represented as message controls. + *

+ * Project: envoy-client
+ * File: MessageListCell.java
+ * Created: 18.07.2020
+ * + * @author Kai S. K. Engelbart + * @since Envoy Client v0.1-beta + */ +public final class MessageListCell extends AbstractListCell { + + /** + * @param listView the list view inside of which the cell will be displayed + * @since Envoy Client v0.1-beta + */ + public MessageListCell(ListView listView) { super(listView); } + + @Override + protected MessageControl renderItem(Message message) { + final var control = new MessageControl(message); + prefWidthProperty().bind(listView.widthProperty().multiply(0.6)); + return control; + } +} diff --git a/client/src/main/resources/css/base.css b/client/src/main/resources/css/base.css index 3549824..66e9f8b 100644 --- a/client/src/main/resources/css/base.css +++ b/client/src/main/resources/css/base.css @@ -9,11 +9,11 @@ } #messageEnterContainer { - -fx-background-radius: 5em; + -fx-background-radius: 5.0em; } #roundButton { - -fx-background-radius: 5em; + -fx-background-radius: 5.0em; } .text-area { @@ -88,7 +88,7 @@ } #loginButton { - -fx-background-radius: 1em; + -fx-background-radius: 1.0em; } #registerSwitch { @@ -99,7 +99,7 @@ #loginInputField { -fx-background-color: transparent; -fx-border: solid; - -fx-border-width: 0 0 1 0; + -fx-border-width: 0.0 0.0 1.0 0.0; } @@ -129,5 +129,13 @@ } #profilePic { - -fx-radius: 1em; + -fx-radius: 1.0em; } + +.listElement { + -fx-background-color: transparent; +} + +.listElement { + -fx-background-color: transparent; +} \ No newline at end of file diff --git a/client/src/main/resources/css/dark.css b/client/src/main/resources/css/dark.css index 1202fe4..21beed5 100644 --- a/client/src/main/resources/css/dark.css +++ b/client/src/main/resources/css/dark.css @@ -50,10 +50,6 @@ -fx-background-color: #303030; } -.listElement { - -fx-background-color: transparent; -} - #messageEnterContainer { -fx-background-color: #363636; } diff --git a/client/src/main/resources/fxml/ChatScene.fxml b/client/src/main/resources/fxml/ChatScene.fxml index 5f6d226..0fc9428 100644 --- a/client/src/main/resources/fxml/ChatScene.fxml +++ b/client/src/main/resources/fxml/ChatScene.fxml @@ -18,19 +18,33 @@ - + - - + + - - - - + + + + - + @@ -40,143 +54,184 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -184,33 +239,40 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + +