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