This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/master by this push:
     new 8875bcd1d3 CAUSEWAY-3685: Tree Rendering: allow for nodes to be marked 
(as selected)
8875bcd1d3 is described below

commit 8875bcd1d3ec2e581216712423184d8aa186301f
Author: Andi Huber <[email protected]>
AuthorDate: Tue Jan 30 15:29:02 2024 +0100

    CAUSEWAY-3685: Tree Rendering: allow for nodes to be marked (as
    selected)
---
 .../causeway/applib/graph/tree/TreeNode.java       | 39 ++++++++++++++++++++++
 .../causeway/applib/graph/tree/TreeState.java      |  1 +
 .../applib/graph/tree/TreeState_Default.java       |  9 +++++
 .../tree/CausewayToWicketTreeAdapter.java          | 11 +++---
 .../ui/components/tree/_TreeExpansionModel.java    | 37 ++++++++++----------
 .../ui/components/tree/_TreeModelTreeAdapter.java  |  6 ++--
 .../ui/components/tree/_TreeNodeMemento.java       |  4 +--
 .../tree/themes/bootstrap/wkt-tree-theme.css       |  4 +++
 8 files changed, 84 insertions(+), 27 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeNode.java 
b/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeNode.java
index 60037fde2c..899215ca3d 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeNode.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeNode.java
@@ -188,6 +188,45 @@ public class TreeNode<T> implements Vertex<T> {
         _NullSafe.stream(treePaths).forEach(expandedPaths::remove);
     }
 
+    // -- SELECTION
+
+    /**
+     * Clears all selection markers.
+     * @see #select(TreePath...)  
+     */
+    @Programmatic
+    public void clearSelection() {
+        getTreeState().getSelectedNodePaths().clear();
+    }
+
+    /**
+     * Whether node that corresponds to given {@link TreePath} has a selection 
markers.
+     * @see #select(TreePath...)
+     */
+    @Programmatic
+    public boolean isSelected(final TreePath treePath) {
+        final Set<TreePath> selectedPaths = 
getTreeState().getSelectedNodePaths();
+        return selectedPaths.contains(treePath);
+    }
+
+    /**
+     * Select nodes by their corresponding {@link TreePath}, that is, activate 
their selection marker.
+     * <p>
+     * With the <i>Wicket Viewer</i> corresponds to expressing CSS class 
{@code tree-node-selected} 
+     * on the rendered tree node, which has default bg-color {@code 
lightgrey}. Color can be customized
+     * by setting CSS var {@code--tree-node-selected-bg-color}
+     * <pre>
+     * .tree-theme-bootstrap .tree-node-selected {
+     *     background-color: var(--tree-node-selected-bg-color, lightgrey);
+     * }
+     * </pre>  
+     */
+    @Programmatic
+    public void select(final TreePath ... treePaths) {
+        final Set<TreePath> selectedPaths = 
getTreeState().getSelectedNodePaths();
+        _NullSafe.stream(treePaths).forEach(selectedPaths::add);
+    }
+
     // -- CONSTRUCTION
 
     /**
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeState.java 
b/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeState.java
index a296b83fad..d1dba0c6b6 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeState.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeState.java
@@ -31,5 +31,6 @@ public interface TreeState extends Serializable {
     }
 
     public Set<TreePath> getExpandedNodePaths();
+    public Set<TreePath> getSelectedNodePaths();
 
 }
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeState_Default.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeState_Default.java
index 908e4f5d1a..e44c458ba4 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeState_Default.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/graph/tree/TreeState_Default.java
@@ -21,14 +21,23 @@ package org.apache.causeway.applib.graph.tree;
 import java.util.HashSet;
 import java.util.Set;
 
+import lombok.ToString;
+
+@ToString
 class TreeState_Default implements TreeState {
     private static final long serialVersionUID = 7971539034663543462L;
 
     private final Set<TreePath> expandedNodes = new HashSet<>();
+    private final Set<TreePath> selectedNodes = new HashSet<>();
 
     @Override
     public Set<TreePath> getExpandedNodePaths() {
         return expandedNodes;
     }
 
+    @Override
+    public Set<TreePath> getSelectedNodePaths() {
+        return selectedNodes;
+    }
+
 }
diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/CausewayToWicketTreeAdapter.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/CausewayToWicketTreeAdapter.java
index d55b106792..81e826eb79 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/CausewayToWicketTreeAdapter.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/CausewayToWicketTreeAdapter.java
@@ -38,6 +38,7 @@ import 
org.apache.causeway.core.metamodel.object.ManagedObjects;
 import org.apache.causeway.viewer.wicket.model.models.ScalarModel;
 import org.apache.causeway.viewer.wicket.model.models.ValueModel;
 import 
org.apache.causeway.viewer.wicket.ui.components.entity.icontitle.EntityIconAndTitlePanel;
+import org.apache.causeway.viewer.wicket.ui.util.Wkt;
 
 import lombok.val;
 
@@ -91,8 +92,9 @@ class CausewayToWicketTreeAdapter {
                     wrappingTreeAdapter.mementify(treeNode.getValue(), 
treeNode.getPositionAsPath()),
                     wrappingTreeAdapter);
 
-            val treeExpansionModel = _TreeExpansionModel.of(
-                    treeNode.getTreeState().getExpandedNodePaths());
+            val treeState = treeNode.getTreeState();
+
+            val treeExpansionModel = _TreeExpansionModel.of(treeState);
 
             return new DomainObjectTree(id,
                     treeModelTreeProvider,
@@ -114,6 +116,9 @@ class CausewayToWicketTreeAdapter {
             final _TreeNodeMemento treeModel = node.getObject();
             final Component entityIconAndTitle = new EntityIconAndTitlePanel(
                     id, treeModel.asObjectAdapterModel());
+            if(treeExpansionModel().isSelected(treeModel.getTreePath())) {
+                Wkt.cssAppend(entityIconAndTitle, "tree-node-selected");
+            }
             return entityIconAndTitle;
         }
 
@@ -161,9 +166,7 @@ class CausewayToWicketTreeAdapter {
             };
 
             node.setOutputMarkupId(true);
-
             return node;
-
         }
 
         /**
diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeExpansionModel.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeExpansionModel.java
index 1dff504104..ac47e6cf85 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeExpansionModel.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeExpansionModel.java
@@ -24,6 +24,7 @@ import java.util.stream.Collectors;
 import org.apache.wicket.model.IModel;
 
 import org.apache.causeway.applib.graph.tree.TreePath;
+import org.apache.causeway.applib.graph.tree.TreeState;
 
 /**
  * Wicket's model for collapse/expand state
@@ -32,8 +33,18 @@ class _TreeExpansionModel implements 
IModel<Set<_TreeNodeMemento>> {
     private static final long serialVersionUID = 648152234030889164L;
 
     public static _TreeExpansionModel of(
-            final Set<TreePath> expandedTreePaths) {
-        return new _TreeExpansionModel( expandedTreePaths);
+            final TreeState treeState) {
+        return new _TreeExpansionModel(treeState);
+    }
+
+    private final TreeState treeState;
+    private final Set<_TreeNodeMemento> expandedNodes;
+    private _TreeExpansionModel(
+            final TreeState treeState) {
+        this.treeState = treeState;
+        this.expandedNodes = treeState.getExpandedNodePaths().stream()
+                .map(tPath->new _TreeNodeMemento(tPath))
+                .collect(Collectors.toSet());
     }
 
     /**
@@ -41,7 +52,7 @@ class _TreeExpansionModel implements 
IModel<Set<_TreeNodeMemento>> {
      * @param t
      */
     public void onExpand(final _TreeNodeMemento t) {
-        expandedTreePaths.add(t.getTreePath());
+        treeState.getExpandedNodePaths().add(t.getTreePath());
     }
 
     /**
@@ -49,23 +60,15 @@ class _TreeExpansionModel implements 
IModel<Set<_TreeNodeMemento>> {
      * @param t
      */
     public void onCollapse(final _TreeNodeMemento t) {
-        expandedTreePaths.remove(t.getTreePath());
+        treeState.getExpandedNodePaths().remove(t.getTreePath());
     }
 
     public boolean contains(final TreePath treePath) {
-        return expandedTreePaths.contains(treePath);
+        return treeState.getExpandedNodePaths().contains(treePath);
     }
 
-    private final Set<TreePath> expandedTreePaths;
-    private final Set<_TreeNodeMemento> expandedNodes;
-
-    private _TreeExpansionModel(
-            final Set<TreePath> expandedTreePaths) {
-
-        this.expandedTreePaths = expandedTreePaths;
-        this.expandedNodes = expandedTreePaths.stream()
-                .map(tPath->new _TreeNodeMemento(tPath))
-                .collect(Collectors.toSet());
+    public boolean isSelected(final TreePath treePath){
+        return treeState.getSelectedNodePaths().contains(treePath);
     }
 
     @Override
@@ -75,9 +78,7 @@ class _TreeExpansionModel implements 
IModel<Set<_TreeNodeMemento>> {
 
     @Override
     public String toString() {
-        return "{" + expandedTreePaths.stream()
-        .map(TreePath::toString)
-        .collect(Collectors.joining(", ")) + "}";
+        return treeState.toString();
     }
 
 }
\ No newline at end of file
diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeModelTreeAdapter.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeModelTreeAdapter.java
index fb54dea425..f4bb56e55c 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeModelTreeAdapter.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeModelTreeAdapter.java
@@ -94,10 +94,10 @@ implements
                 .map(newPojoToTreeModelMapper(treeModel));
     }
 
-    _TreeNodeMemento mementify(final @NonNull Object pojo, final TreePath 
treePath) {
+    _TreeNodeMemento mementify(final @NonNull Object pojo, final @NonNull 
TreePath treePath) {
         return new _TreeNodeMemento(
-                ManagedObject.adaptSingular(getSpecificationLoader(), 
pojo).getBookmark().orElseThrow(),
-                treePath);
+                treePath,
+                ManagedObject.adaptSingular(getSpecificationLoader(), 
pojo).getBookmark().orElseThrow());
     }
     private @Nullable Object demementify(final _TreeNodeMemento model) {
         Objects.requireNonNull(model);
diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeNodeMemento.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeNodeMemento.java
index ffa0c80d19..c9d10ab8dd 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeNodeMemento.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/_TreeNodeMemento.java
@@ -43,13 +43,13 @@ class _TreeNodeMemento implements Serializable {
     @Getter private final TreePath treePath;
     private final int hashCode;
 
-    public _TreeNodeMemento(final TreePath treePath) {
+    public _TreeNodeMemento(final @NonNull TreePath treePath) {
         this.bookmark = null;
         this.treePath = treePath;
         this.hashCode = Objects.hash(0, treePath.hashCode());
     }
 
-    public _TreeNodeMemento(final @NonNull Bookmark bookmark, final @NonNull 
TreePath treePath) {
+    public _TreeNodeMemento(final @NonNull TreePath treePath, final @NonNull 
Bookmark bookmark) {
         this.bookmark = bookmark;
         this.treePath = treePath;
         this.hashCode = Objects.hash(bookmark.hashCode(), treePath.hashCode());
diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/themes/bootstrap/wkt-tree-theme.css
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/themes/bootstrap/wkt-tree-theme.css
index 78aef757a7..d5b561070b 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/themes/bootstrap/wkt-tree-theme.css
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/tree/themes/bootstrap/wkt-tree-theme.css
@@ -81,6 +81,10 @@
   margin-left: 18px;
 }
 
+.tree-theme-bootstrap .tree-node-selected {
+  background-color: var(--tree-node-selected-bg-color, lightgrey);
+}
+
 /* tabletree */
 
 .tree-theme-bootstrap table {

Reply via email to