View Javadoc
1   /*
2    * Metis: Java Data Framework
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.metis.help;
18  
19  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20  import io.github.tonywasher.joceanus.oceanus.event.OceanusEvent;
21  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventManager;
22  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
23  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar.OceanusEventProvider;
24  import io.github.tonywasher.joceanus.tethys.api.base.TethysUIEvent;
25  import io.github.tonywasher.joceanus.tethys.api.control.TethysUIHTMLManager;
26  import io.github.tonywasher.joceanus.tethys.api.control.TethysUIHTMLManager.TethysUIStyleSheetId;
27  import io.github.tonywasher.joceanus.tethys.api.control.TethysUISplitTreeManager;
28  import io.github.tonywasher.joceanus.tethys.api.control.TethysUITreeManager;
29  import io.github.tonywasher.joceanus.tethys.api.control.TethysUITreeManager.TethysUITreeItem;
30  import io.github.tonywasher.joceanus.tethys.api.dialog.TethysUIChildDialog;
31  import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
32  import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIBorderPaneManager;
33  
34  import java.util.List;
35  
36  /**
37   * Help Manager class, responsible for displaying the help.
38   */
39  public class MetisHelpWindow
40          implements OceanusEventProvider<TethysUIEvent> {
41      /**
42       * The Height of the window.
43       */
44      protected static final int WINDOW_WIDTH = 900;
45  
46      /**
47       * The Height of the window.
48       */
49      protected static final int WINDOW_HEIGHT = 600;
50  
51      /**
52       * The Factory.
53       */
54      private final TethysUIFactory<?> theFactory;
55  
56      /**
57       * The Event Manager.
58       */
59      private final OceanusEventManager<TethysUIEvent> theEventManager;
60  
61      /**
62       * The split tree.
63       */
64      private final TethysUISplitTreeManager<MetisHelpEntry> theSplitTree;
65  
66      /**
67       * The tree manager.
68       */
69      private final TethysUITreeManager<MetisHelpEntry> theTree;
70  
71      /**
72       * The help dialog.
73       */
74      private TethysUIChildDialog theDialog;
75  
76      /**
77       * The HTML manager.
78       */
79      private final TethysUIHTMLManager theHtml;
80  
81      /**
82       * Constructor.
83       *
84       * @param pFactory the GUI factory
85       */
86      public MetisHelpWindow(final TethysUIFactory<?> pFactory) {
87          /* Store parameters */
88          theFactory = pFactory;
89  
90          /* Create the event manager */
91          theEventManager = new OceanusEventManager<>();
92  
93          /* Create the splitTree manager and obtain details */
94          theSplitTree = pFactory.controlFactory().newSplitTreeManager();
95          theTree = theSplitTree.getTreeManager();
96          theHtml = theSplitTree.getHTMLManager();
97  
98          /* Listen to the TreeManager */
99          theSplitTree.getEventRegistrar().addEventListener(this::handleSplitTreeAction);
100     }
101 
102     @Override
103     public OceanusEventRegistrar<TethysUIEvent> getEventRegistrar() {
104         return theEventManager.getEventRegistrar();
105     }
106 
107     /**
108      * Obtain the SplitTree Manager.
109      *
110      * @return the tree manager
111      */
112     public TethysUISplitTreeManager<MetisHelpEntry> getSplitTreeManager() {
113         return theSplitTree;
114     }
115 
116     /**
117      * Obtain the Tree Manager.
118      *
119      * @return the tree manager
120      */
121     public TethysUITreeManager<MetisHelpEntry> getTreeManager() {
122         return theTree;
123     }
124 
125     /**
126      * Obtain the HTML Manager.
127      *
128      * @return the HTML manager
129      */
130     public TethysUIHTMLManager getHTMLManager() {
131         return theHtml;
132     }
133 
134     /**
135      * Fire event.
136      *
137      * @param pEventId the eventId
138      * @param pValue   the relevant value
139      */
140     protected void fireEvent(final TethysUIEvent pEventId,
141                              final Object pValue) {
142         theEventManager.fireEvent(pEventId, pValue);
143     }
144 
145     /**
146      * show the dialog.
147      */
148     public void showDialog() {
149         /* If the dialog does not exist */
150         if (theDialog == null) {
151             /* Create a new dialog */
152             theDialog = theFactory.dialogFactory().newChildDialog();
153             theDialog.setTitle(MetisHelpResource.TITLE.getValue());
154 
155             /* Create the help panel */
156             final TethysUIBorderPaneManager myPanel = theFactory.paneFactory().newBorderPane();
157             myPanel.setCentre(theSplitTree);
158             myPanel.setPreferredWidth(WINDOW_WIDTH);
159             myPanel.setPreferredHeight(WINDOW_HEIGHT);
160             theDialog.setContent(myPanel);
161 
162             /* Set listener */
163             theDialog.getEventRegistrar().addEventListener(TethysUIEvent.WINDOWCLOSED, e -> {
164                 theTree.setVisible(false);
165                 fireEvent(TethysUIEvent.WINDOWCLOSED, null);
166             });
167         }
168 
169         /* If the dialog is not showing */
170         if (!theDialog.isShowing()) {
171             /* Make sure that the dialog is showing */
172             theTree.setVisible(true);
173             theDialog.showDialog();
174         }
175     }
176 
177     /**
178      * Hide the dialog.
179      */
180     public void hideDialog() {
181         /* If the dialog exists */
182         if (theDialog != null
183                 && theDialog.isShowing()) {
184             /* Make sure that the dialog is hidden */
185             theDialog.hideDialog();
186         }
187     }
188 
189     /**
190      * CloseWindow on parent termination.
191      */
192     public void closeWindow() {
193         hideDialog();
194         if (theDialog != null) {
195             theDialog.closeDialog();
196         }
197     }
198 
199     /**
200      * Set the help module.
201      *
202      * @param pModule the helpModule
203      * @throws OceanusException on error
204      */
205     public void setModule(final MetisHelpModule pModule) throws OceanusException {
206         /* Access the Help entries and list */
207         final List<MetisHelpEntry> myEntries = pModule.getHelpEntries();
208 
209         /* Declare CSS */
210         final TethysUIStyleSheetId myCSS = pModule.getCSS();
211         if (myCSS != null) {
212             theHtml.setCSSContent(myCSS);
213         }
214 
215         /* Create the tree */
216         createTree(pModule.getTitle(), myEntries);
217     }
218 
219     /**
220      * Handle the split tree action event.
221      *
222      * @param pEvent the event
223      */
224     protected void handleSplitTreeAction(final OceanusEvent<TethysUIEvent> pEvent) {
225         switch (pEvent.getEventId()) {
226             case NEWVALUE:
227                 handleNewTreeItem(pEvent.getDetails(MetisHelpEntry.class));
228                 break;
229             case BUILDPAGE:
230             default:
231                 break;
232         }
233     }
234 
235     /**
236      * Handle the new tree item.
237      *
238      * @param pEntry the new entry
239      */
240     private void handleNewTreeItem(final MetisHelpEntry pEntry) {
241         if (pEntry != null) {
242             final String myHtml = pEntry.getHtml();
243             if (myHtml != null) {
244                 theHtml.setHTMLContent(myHtml, pEntry.getName());
245             }
246         }
247     }
248 
249     /**
250      * Construct a top level Tree Node from a set of help entries.
251      *
252      * @param pTitle   the title for the tree
253      * @param pEntries the help entries
254      * @return the Tree node
255      */
256     private TethysUITreeItem<MetisHelpEntry> createTree(final String pTitle,
257                                                         final List<MetisHelpEntry> pEntries) {
258         /* Obtain the root node */
259         final TethysUITreeItem<MetisHelpEntry> myRoot = theTree.getRoot();
260         theTree.setRootName(pTitle);
261         theTree.setRootVisible();
262 
263         /* Clear existing children */
264         myRoot.removeChildren();
265 
266         /* Add the entries into the node */
267         addHelpEntries(myRoot, pEntries);
268 
269         /* Return the root */
270         return myRoot;
271     }
272 
273     /**
274      * Add array of Help entries.
275      *
276      * @param pParent  the parent to add to
277      * @param pEntries the entries to add
278      */
279     private void addHelpEntries(final TethysUITreeItem<MetisHelpEntry> pParent,
280                                 final List<MetisHelpEntry> pEntries) {
281         /* Loop through the entries */
282         for (MetisHelpEntry myEntry : pEntries) {
283             /* Create the entry */
284             final TethysUITreeItem<MetisHelpEntry> myItem = theTree.addChildItem(pParent, myEntry.getName(), myEntry);
285 
286             /* If we have children */
287             final List<MetisHelpEntry> myChildren = myEntry.getChildren();
288             if (myChildren != null) {
289                 /* Add the children into the tree */
290                 addHelpEntries(myItem, myChildren);
291             }
292         }
293     }
294 }