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

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 9a8e54808b754ed609d5645c05c977f947db6cab
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sun Nov 28 16:30:51 2021 +0100

    Simplify the GUI on the left side:
    - Replace the split pane on the left side by an accordion.
    - Reduce the number of titled pane in the accordion for other controls.
---
 .../apache/sis/gui/coverage/CoverageControls.java  | 42 ++++++--------
 .../org/apache/sis/gui/coverage/GridControls.java  | 18 ++----
 .../apache/sis/gui/dataset/ResourceExplorer.java   | 67 ++++++++++------------
 .../org/apache/sis/util/resources/Vocabulary.java  | 10 ++++
 .../sis/util/resources/Vocabulary.properties       |  2 +
 .../sis/util/resources/Vocabulary_fr.properties    |  2 +
 6 files changed, 67 insertions(+), 74 deletions(-)

diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
index 49cff1b..c63933e 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
@@ -99,40 +99,35 @@ final class CoverageControls extends ViewAndControls {
          * "Display" section with the following controls:
          *    - Current CRS
          *    - Interpolation
+         *    - Color stretching
+         *    - Colors for each category
          */
         final VBox displayPane;
         {   // Block for making variables locale to this scope.
             final Label crsControl = new Label();
-            final Label crsHeader  = labelOfGroup(vocabulary, 
Vocabulary.Keys.ReferenceSystem, crsControl, true);
             crsControl.setPadding(CONTENT_MARGIN);
             crsControl.setTooltip(new 
Tooltip(resources.getString(Resources.Keys.SelectCrsByContextMenu)));
             menu.selectedReferenceSystem().ifPresent((text) -> 
crsControl.textProperty().bind(text));
             /*
              * Creates a "Values" sub-section with the following controls:
              *   - Interpolation
+             *   - Color stretching
              */
             final GridPane valuesControl = Styles.createControlGrid(0,
-                label(vocabulary, Vocabulary.Keys.Interpolation, 
InterpolationConverter.button(view)));
-            final Label valuesHeader = labelOfGroup(vocabulary, 
Vocabulary.Keys.Values, valuesControl, false);
+                label(vocabulary, Vocabulary.Keys.Interpolation, 
InterpolationConverter.button(view)),
+                label(vocabulary, Vocabulary.Keys.Stretching, 
Stretching.createButton((p,o,n) -> view.setStyling(n))));
             /*
-             * All sections put together.
+             * Creates a "Categories" section with the category table.
              */
-            displayPane = new VBox(crsHeader, crsControl, valuesHeader, 
valuesControl);
-        }
-        /*
-         * "Colors" section with the following controls:
-         *    - Colors for each category
-         *    - Color stretching
-         */
-        final VBox colorsPane;
-        {   // Block for making variables locale to this scope.
             final CoverageStyling styling = new CoverageStyling(view);
             categoryTable = styling.createCategoryTable(vocabulary);
-            final GridPane gp = Styles.createControlGrid(0,
-                label(vocabulary, Vocabulary.Keys.Stretching, 
Stretching.createButton((p,o,n) -> view.setStyling(n))));
-
-            colorsPane = new VBox(
-                    labelOfGroup(vocabulary, Vocabulary.Keys.Categories, 
categoryTable, true), categoryTable, gp);
+            /*
+             * All sections put together.
+             */
+            displayPane = new VBox(
+                    labelOfGroup(vocabulary, Vocabulary.Keys.ReferenceSystem, 
crsControl,    true),  crsControl,
+                    labelOfGroup(vocabulary, Vocabulary.Keys.Values,          
valuesControl, false), valuesControl,
+                    labelOfGroup(vocabulary, Vocabulary.Keys.Categories,      
categoryTable, false), categoryTable);
         }
         /*
          * "Isolines" section with the following controls:
@@ -149,11 +144,10 @@ final class CoverageControls extends ViewAndControls {
          * Put all sections together and have the first one expanded by 
default.
          * The "Properties" section will be built by `PropertyPaneCreator` 
only if requested.
          */
-        final TitledPane p1 = new 
TitledPane(vocabulary.getString(Vocabulary.Keys.SpatialRepresentation), 
displayPane);
-        final TitledPane p2 = new 
TitledPane(vocabulary.getString(Vocabulary.Keys.Colors), colorsPane);
-        final TitledPane p3 = new 
TitledPane(vocabulary.getString(Vocabulary.Keys.Isolines), isolinesPane);
-        final TitledPane p4 = new 
TitledPane(vocabulary.getString(Vocabulary.Keys.Properties), null);
-        controls = new Accordion(p1, p2, p3, p4);
+        final TitledPane p1 = new 
TitledPane(vocabulary.getString(Vocabulary.Keys.Display),  displayPane);
+        final TitledPane p2 = new 
TitledPane(vocabulary.getString(Vocabulary.Keys.Isolines), isolinesPane);
+        final TitledPane p3 = new 
TitledPane(vocabulary.getString(Vocabulary.Keys.Properties), null);
+        controls = new Accordion(p1, p2, p3);
         controls.setExpandedPane(p1);
         /*
          * Set listeners: changes on `CoverageCanvas` properties are 
propagated to the corresponding
@@ -162,7 +156,7 @@ final class CoverageControls extends ViewAndControls {
          */
         view.resourceProperty.addListener((p,o,n) -> onPropertySet(n, null));
         view.coverageProperty.addListener((p,o,n) -> onPropertySet(null, n));
-        p4.expandedProperty().addListener(new PropertyPaneCreator(view, p4));
+        p3.expandedProperty().addListener(new PropertyPaneCreator(view, p3));
     }
 
     /**
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridControls.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridControls.java
index b986725..0c6c628 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridControls.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridControls.java
@@ -20,7 +20,6 @@ import javafx.beans.property.DoubleProperty;
 import javafx.collections.ObservableList;
 import javafx.scene.control.Accordion;
 import javafx.scene.control.Control;
-import javafx.scene.control.Label;
 import javafx.scene.control.Slider;
 import javafx.scene.control.TableView;
 import javafx.scene.control.TitledPane;
@@ -72,17 +71,9 @@ final class GridControls extends ViewAndControls {
         sampleDimensions = new 
BandRangeTable(view.cellFormat).create(vocabulary);
         BandSelectionListener.bind(view.bandProperty, 
sampleDimensions.getSelectionModel());
         /*
-         * "Coverage" section with the following controls:
+         * "Display" section with the following controls:
          *    - Coverage domain as a list of CRS dimensions with two of them 
selected (TODO).
          *    - Coverage range as a list of sample dimensions with at least 
one selected.
-         */
-        final VBox coveragePane;
-        {   // Block for making variables locale to this scope.
-            final Label label = labelOfGroup(vocabulary, 
Vocabulary.Keys.SampleDimensions, sampleDimensions, true);
-            coveragePane = new VBox(label, sampleDimensions);
-        }
-        /*
-         * "Display" section with the following controls:
          *    - Number format as a localized pattern.
          *    - Cell width as a slider.
          */
@@ -94,14 +85,15 @@ final class GridControls extends ViewAndControls {
                 label(vocabulary, Vocabulary.Keys.Format, 
view.cellFormat.createEditor()));
 
             Styles.setAllRowToSameHeight(gp);
-            displayPane = new VBox(labelOfGroup(vocabulary, 
Vocabulary.Keys.Cells, gp, true), gp);
+            displayPane = new VBox(
+                    labelOfGroup(vocabulary, Vocabulary.Keys.SampleDimensions, 
sampleDimensions, true), sampleDimensions,
+                    labelOfGroup(vocabulary, Vocabulary.Keys.Cells, gp, 
false), gp);
         }
         /*
          * Put all sections together and have the first one expanded by 
default.
          */
         controls = new Accordion(
-            new TitledPane(vocabulary.getString(Vocabulary.Keys.Coverage), 
coveragePane),
-            new TitledPane(vocabulary.getString(Vocabulary.Keys.Display),  
displayPane)
+            new TitledPane(vocabulary.getString(Vocabulary.Keys.Display), 
displayPane)
             // TODO: more controls to be added in a future version.
         );
         controls.setExpandedPane(controls.getPanes().get(0));
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceExplorer.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceExplorer.java
index a6b9fbc..91668cd 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceExplorer.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceExplorer.java
@@ -27,13 +27,13 @@ import javafx.collections.ListChangeListener;
 import javafx.collections.ObservableList;
 import javafx.event.EventHandler;
 import javafx.concurrent.Task;
-import javafx.geometry.Orientation;
-import javafx.scene.Node;
 import javafx.scene.layout.Region;
+import javafx.scene.control.Accordion;
 import javafx.scene.control.ContextMenu;
 import javafx.scene.control.SplitPane;
 import javafx.scene.control.Tab;
 import javafx.scene.control.TabPane;
+import javafx.scene.control.TitledPane;
 import javafx.scene.control.TreeItem;
 import org.apache.sis.storage.Resource;
 import org.apache.sis.storage.Aggregate;
@@ -112,11 +112,12 @@ public class ResourceExplorer extends WindowManager {
     private FeatureTable features;
 
     /**
-     * Controls for the image or tabular data. This is a vertical split pane.
-     * The upper part contains the {@link #resources} tree and the lower part
-     * contains the resource-dependent controls.
+     * Controls for the image or tabular data. The first titled pane on top 
contains the
+     * {@link #resources} tree and all other panes below are 
resource-dependent controls.
+     *
+     * @see #updateControls(Region)
      */
-    private final SplitPane controls;
+    private final Accordion controls;
 
     /**
      * The control that put everything together.
@@ -149,23 +150,22 @@ public class ResourceExplorer extends WindowManager {
     private final BooleanBinding metadataShown;
 
     /**
-     * Last divider position as a fraction between 0 and 1, or {@code NaN} if 
undefined.
-     * This is used for keeping the position constant when adding and removing 
controls.
-     */
-    private double dividerPosition;
-
-    /**
      * Creates a new panel for exploring resources.
      */
     public ResourceExplorer() {
         /*
          * Build the resource explorer. Must be first because `localized()` 
depends on it.
+         * Then build the controls on the left side, which will initially 
contain only the
+         * resource explorer. The various tabs will be next (on the right 
side).
          */
         resources = new ResourceTree();
         
resources.getSelectionModel().getSelectedItems().addListener(this::onResourceSelected);
         resources.setPrefWidth(400);
         selectedResource = new ReadOnlyObjectWrapper<>(this, 
"selectedResource");
         final Vocabulary vocabulary = 
Vocabulary.getResources(resources.locale);
+        final TitledPane resourcesPane = new 
TitledPane(vocabulary.getString(Vocabulary.Keys.Resources), resources);
+        controls = new Accordion(resourcesPane);
+        controls.setExpandedPane(resourcesPane);
         /*
          * "Summary" tab showing a summary of resource metadata.
          */
@@ -206,11 +206,8 @@ public class ResourceExplorer extends WindowManager {
         final TabPane tabs = new TabPane(summaryTab, viewTab, tableTab, 
metadataTab, nativeMetadataTab, loggingTab);
         tabs.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
         tabs.setTabDragPolicy(TabPane.TabDragPolicy.REORDER);
-        controls = new SplitPane(resources);
-        controls.setOrientation(Orientation.VERTICAL);
         content = new SplitPane(controls, tabs);
         content.setDividerPosition(0, 0.2);
-        dividerPosition = Double.NaN;
         SplitPane.setResizableWithParent(resources, Boolean.FALSE);
         SplitPane.setResizableWithParent(tabs, Boolean.TRUE);
         /*
@@ -222,6 +219,8 @@ public class ResourceExplorer extends WindowManager {
         dataShown.addListener((p,o,n) -> {
             if (Boolean.FALSE.equals(o) && Boolean.TRUE.equals(n)) {
                 updateDataTabWithDefault(getSelectedResource());
+            } else {
+                updateDataTab(null);
             }
         });
         metadataShown = 
summaryTab.selectedProperty().or(metadataTab.selectedProperty());
@@ -474,31 +473,25 @@ public class ResourceExplorer extends WindowManager {
         if (table    != null) tableTab.setContent(table);
         final boolean isEmpty = (image == null & table == null);
         setNewWindowDisabled(isEmpty);
-        updateControls(controlPanel);
-        return !isEmpty | (resource == null);
-    }
-
-    /**
-     * Adds or removes controls for the given view.
-     * This method is invoked when the visible tab changed.
-     *
-     * @param  controlPanel  the controls for the currently selected tab, or 
{@code null} if none.
-     */
-    private void updateControls(final Region controlPanel) {
-        final ObservableList<Node> items = controls.getItems();
-        if (items.size() >= 2) {
-            if (controlPanel != null) {
-                items.set(1, controlPanel);
+        /*
+         * Adds or removes controls for the selected view.
+         */
+        final ObservableList<TitledPane> items = controls.getPanes();
+        final int size = items.size();
+        items.remove(1, size);
+        if (controlPanel != null) {
+            if (controlPanel instanceof Accordion) {
+                /*
+                 * It is okay to use the same controls in another JavaFX node 
because the `controlPanel` will
+                 * never be shown (we will only show its components). The 
children are in only one scene graph.
+                 */
+                items.addAll(((Accordion) controlPanel).getPanes());
             } else {
-                dividerPosition = controls.getDividerPositions()[0];
-                items.remove(1);
-            }
-        } else if (controlPanel != null) {
-            items.add(controlPanel);
-            if (dividerPosition >= 0) {
-                controls.setDividerPosition(0, dividerPosition);
+                items.add(new TitledPane(Vocabulary.getResources(getLocale())
+                        .getString(Vocabulary.Keys.Controls), controlPanel));
             }
         }
+        return !isEmpty | (resource == null);
     }
 
     /**
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java 
b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
index a3fa6f8..79228c2 100644
--- 
a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
+++ 
b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
@@ -255,6 +255,11 @@ public final class Vocabulary extends 
IndexedResourceBundle {
         public static final short Container = 33;
 
         /**
+         * Controls
+         */
+        public static final short Controls = 262;
+
+        /**
          * Conversion
          */
         public static final short Conversion = 34;
@@ -1070,6 +1075,11 @@ public final class Vocabulary extends 
IndexedResourceBundle {
         public static final short ResourceIdentification = 173;
 
         /**
+         * Resources
+         */
+        public static final short Resources = 263;
+
+        /**
          * Result
          */
         public static final short Result = 174;
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
 
b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
index 23535c1..12e78be 100644
--- 
a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
+++ 
b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
@@ -49,6 +49,7 @@ Color                   = Color
 Colors                  = Colors
 ColorIndex              = Color index
 Commands                = Commands
+Controls                = Controls
 Configuration           = Configuration
 Constants               = Constants
 ConstantPressureSurface = Constant pressure surface
@@ -217,6 +218,7 @@ RemoteConfiguration     = Remote configuration
 RepresentativeValue     = Representative value
 Resolution              = Resolution
 ResourceIdentification  = Resource identification
+Resources               = Resources
 Result                  = Result
 Retry                   = Retry
 Root                    = Root
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
 
b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
index 873cf3d..14c5138 100644
--- 
a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
+++ 
b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
@@ -56,6 +56,7 @@ Color                   = Couleur
 Colors                  = Couleurs
 ColorIndex              = Indice de couleur
 Commands                = Commandes
+Controls                = Contr\u00f4les
 Configuration           = Configuration
 Constants               = Constantes
 ConstantPressureSurface = Surface \u00e0 pression constante
@@ -224,6 +225,7 @@ RemoteConfiguration     = Configuration distante
 RepresentativeValue     = Valeur repr\u00e9sentative
 Resolution              = R\u00e9solution
 ResourceIdentification  = Identification de la ressource
+Resources               = Ressources
 Result                  = R\u00e9sultat
 Retry                   = R\u00e9essayer
 Root                    = Racine

Reply via email to