PanelGroupControl.java

  1. /*
  2.  * *************************************************************************************************************************************************************
  3.  *
  4.  * SteelBlue: DCI User Interfaces
  5.  * http://tidalwave.it/projects/steelblue
  6.  *
  7.  * Copyright (C) 2015 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
  8.  *
  9.  * *************************************************************************************************************************************************************
  10.  *
  11.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
  12.  * You may obtain a copy of the License at
  13.  *
  14.  *     http://www.apache.org/licenses/LICENSE-2.0
  15.  *
  16.  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  17.  * CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License.
  18.  *
  19.  * *************************************************************************************************************************************************************
  20.  *
  21.  * git clone https://bitbucket.org/tidalwave/steelblue-src
  22.  * git clone https://github.com/tidalwave-it/steelblue-src
  23.  *
  24.  * *************************************************************************************************************************************************************
  25.  */
  26. package it.tidalwave.ui.core;

  27. import jakarta.annotation.Nonnull;
  28. import java.util.ArrayList;
  29. import java.util.HashMap;
  30. import java.util.List;
  31. import java.util.Map;
  32. import org.apiguardian.api.API;
  33. import lombok.Getter;
  34. import lombok.RequiredArgsConstructor;
  35. import lombok.ToString;
  36. import static org.apiguardian.api.API.Status.EXPERIMENTAL;
  37. import static lombok.AccessLevel.PRIVATE;

  38. /***************************************************************************************************************************************************************
  39.  *
  40.  * This service looks up {@link PanelGroupProvider}s that describe portions of the User Interface and places them in the desired region of the main window.
  41.  * Calling the method {@link #setup(Configuration)} with the proper configuration, the desired panel groups can be bound to existing UI controls. The runtime
  42.  * will scan for instances of {@link PanelGroupProvider} that declare and instantiate panels to be associated to each group.
  43.  * Calling the method {@link #show(Object)} one of possibly many panels in the same group is brought to visibility. If the system includes a
  44.  * message bus implementing {@link it.tidalwave.messagebus.MessageBus}, it is also possible to pick the shown panel by publishing the event
  45.  * {@link it.tidalwave.ui.core.message.PanelShowRequest}; the event {@link it.tidalwave.ui.core.message.PanelShownNotification} will be published back to
  46.  * confirm the operation.
  47.  *
  48.  * @param   <T> the concrete type of the top container (depending on the UI technology)
  49.  * @since       2.0-ALPHA-3
  50.  * @see         PanelGroupProvider
  51.  * @author      Fabrizio Giudici
  52.  *
  53.  **************************************************************************************************************************************************************/
  54. @API(status = EXPERIMENTAL)
  55. public interface PanelGroupControl<T>
  56.   {
  57.     /***********************************************************************************************************************************************************
  58.      * The group in the main window.
  59.      **********************************************************************************************************************************************************/
  60.     public static interface Group {}

  61.     /***********************************************************************************************************************************************************
  62.      * Standard groups.
  63.      **********************************************************************************************************************************************************/
  64.     public enum DefaultGroups implements Group
  65.       {
  66.         LEFT, RIGHT, CENTER, BOTTOM
  67.       }

  68.     /***********************************************************************************************************************************************************
  69.      * A bag of configuration settings for {@code PanelGroupProvider}.
  70.      **********************************************************************************************************************************************************/
  71.     @RequiredArgsConstructor(access = PRIVATE) @Getter @ToString
  72.     public static class Configuration<T>
  73.       {
  74.         @Nonnull
  75.         private final Map<Group, T> topContainersByGroup;

  76.         @Nonnull
  77.         private final Map<Group, List<Options>> groupOptions;

  78.         @Nonnull
  79.         private final List<Options> options;

  80.         /*******************************************************************************************************************************************************
  81.          * Specifies the configuration for a group.
  82.          * @see       Options
  83.          * @param     group           the group
  84.          * @param     topContainer    the concrete UI container that will be associated to the group
  85.          * @param     groupOptions    {@link Options} for this group
  86.          * @return                    a copy of itself in chaining invocation fashion
  87.          ******************************************************************************************************************************************************/
  88.         @Nonnull
  89.         public Configuration<T> withGroup (@Nonnull final Group group, @Nonnull final T topContainer, @Nonnull final Options ... groupOptions)
  90.           {
  91.             final var tcbs = new HashMap<>(topContainersByGroup);
  92.             final var so = new HashMap<>(this.groupOptions);
  93.             tcbs.put(group, topContainer);
  94.             so.computeIfAbsent(group, s -> new ArrayList<>()).addAll(List.of(groupOptions));
  95.             return new Configuration<>(tcbs, so, this.options);
  96.           }

  97.         /*******************************************************************************************************************************************************
  98.          * Specifies global configuration {@link Options} that are applied to all groups.
  99.          * @see       Options
  100.          * @param     options         the options
  101.          * @return                    a copy of itself in chaining invocation fashion
  102.          ******************************************************************************************************************************************************/
  103.         @Nonnull
  104.         public final Configuration<T> withOptions (@Nonnull final Options ... options)
  105.           {
  106.             return new Configuration<>(topContainersByGroup, groupOptions, List.of(options));
  107.           }
  108.       }

  109.     /***********************************************************************************************************************************************************
  110.      * Options for the {@link #setup(Configuration)} method.
  111.      * @see   Configuration#withGroup(Group, Object, Options...)
  112.      * @see   Configuration#withOptions(Options...)
  113.      **********************************************************************************************************************************************************/
  114.     public enum Options
  115.       {
  116.         /** Use a wrapper container even when there is a single element in a group. */
  117.         ALWAYS_WRAP,
  118.         /** Use an Accordion wrapper. */
  119.         USE_ACCORDION,
  120.         /** Disable animation when expanding/collapsing the Accordion. */
  121.         DISABLE_ACCORDION_ANIMATION
  122.       }

  123.     /***********************************************************************************************************************************************************
  124.      * Sets up panel groups according to the given {@link Configuration}.
  125.      * @param   configuration   the configuration
  126.      **********************************************************************************************************************************************************/
  127.     public void setup (@Nonnull final Configuration<T> configuration);

  128.     /***********************************************************************************************************************************************************
  129.      * Sets the shown object in a group.
  130.      * @param   object    the object to show
  131.      **********************************************************************************************************************************************************/
  132.     public void show (@Nonnull Object object);

  133.     /***********************************************************************************************************************************************************
  134.      * {@return an empty {@link Configuration}}.
  135.      **********************************************************************************************************************************************************/
  136.     @Nonnull
  137.     public default Configuration<T> config()
  138.       {
  139.         return new Configuration<>(Map.of(), Map.of(), List.of());
  140.       }
  141.   }