View Javadoc
1   /*
2    * Tethys: GUI Utilities
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.tethys.javafx.field;
18  
19  import io.github.tonywasher.joceanus.oceanus.event.OceanusEvent;
20  import javafx.geometry.Insets;
21  import javafx.geometry.Side;
22  import javafx.scene.Node;
23  import javafx.scene.control.Button;
24  import io.github.tonywasher.joceanus.tethys.api.base.TethysUIEvent;
25  import io.github.tonywasher.joceanus.tethys.api.button.TethysUIScrollButtonManager;
26  import io.github.tonywasher.joceanus.tethys.api.field.TethysUIDataEditField.TethysUIScrollButtonField;
27  import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollMenu;
28  import io.github.tonywasher.joceanus.tethys.core.factory.TethysUICoreFactory;
29  import io.github.tonywasher.joceanus.tethys.javafx.base.TethysUIFXNode;
30  import io.github.tonywasher.joceanus.tethys.javafx.button.TethysUIFXScrollButtonManager;
31  import io.github.tonywasher.joceanus.tethys.javafx.menu.TethysUIFXScrollMenu;
32  
33  import java.util.function.Consumer;
34  
35  /**
36   * ScrollButtonField class.
37   *
38   * @param <T> the data type
39   */
40  public final class TethysUIFXScrollButtonField<T>
41          extends TethysUIFXDataTextField<T>
42          implements TethysUIScrollButtonField<T> {
43      /**
44       * The scroll manager.
45       */
46      private final TethysUIFXScrollButtonManager<T> theManager;
47  
48      /**
49       * The configurator.
50       */
51      private Consumer<TethysUIScrollMenu<T>> theConfigurator;
52  
53      /**
54       * The button.
55       */
56      private final Button theButton;
57  
58      /**
59       * Are we editing a cell?
60       */
61      private boolean isCellEditing;
62  
63      /**
64       * Constructor.
65       *
66       * @param pFactory the GUI factory
67       * @param pClazz   the value class
68       */
69      TethysUIFXScrollButtonField(final TethysUICoreFactory<?> pFactory,
70                                  final Class<T> pClazz) {
71          this(pFactory, pFactory.buttonFactory().newScrollButton(pClazz));
72      }
73  
74      /**
75       * Constructor.
76       *
77       * @param pFactory the GUI factory
78       * @param pManager the manager
79       */
80      private TethysUIFXScrollButtonField(final TethysUICoreFactory<?> pFactory,
81                                          final TethysUIScrollButtonManager<T> pManager) {
82          /* Initialise underlying class */
83          super(pFactory, TethysUIFXNode.getNode(pManager));
84  
85          /* Store the manager and button */
86          theManager = (TethysUIFXScrollButtonManager<T>) pManager;
87          theButton = getEditControl();
88  
89          /* Set padding */
90          getLabel().setPadding(new Insets(PADDING, PADDING, PADDING, PADDING));
91  
92          /* Set listener on manager */
93          pManager.getEventRegistrar().addEventListener(this::handleEvent);
94  
95          /* Set configurator */
96          theConfigurator = p -> {
97          };
98      }
99  
100     @Override
101     public T getCastValue(final Object pValue) {
102         return theManager.getValueClass().cast(pValue);
103     }
104 
105     /**
106      * handle Scroll Button event.
107      *
108      * @param pEvent the even
109      */
110     private void handleEvent(final OceanusEvent<TethysUIEvent> pEvent) {
111         switch (pEvent.getEventId()) {
112             case NEWVALUE:
113                 setValue(theManager.getValue());
114                 fireEvent(TethysUIEvent.NEWVALUE, pEvent.getDetails());
115                 break;
116             case EDITFOCUSLOST:
117                 haltCellEditing();
118                 break;
119             default:
120                 break;
121         }
122     }
123 
124     @Override
125     public void setMenuConfigurator(final Consumer<TethysUIScrollMenu<T>> pConfigurator) {
126         theConfigurator = pConfigurator;
127         theManager.setMenuConfigurator(theConfigurator);
128     }
129 
130     @Override
131     protected Button getEditControl() {
132         return (Button) super.getEditControl();
133     }
134 
135     @Override
136     public void setValue(final T pValue) {
137         /* Store the value */
138         super.setValue(pValue);
139 
140         /* Declare value to the manager */
141         theManager.setValue(pValue);
142         getLabel().setText(theButton.getText());
143     }
144 
145     @Override
146     public void startCellEditing(final Node pCell) {
147         isCellEditing = true;
148         final TethysUIFXScrollMenu<T> myMenu = theManager.getMenu();
149         theConfigurator.accept(myMenu);
150         if (!myMenu.isEmpty()) {
151             myMenu.showMenuAtPosition(pCell, Side.BOTTOM);
152         } else {
153             haltCellEditing();
154         }
155     }
156 
157     /**
158      * haltCellEditing.
159      */
160     private void haltCellEditing() {
161         if (isCellEditing) {
162             fireEvent(TethysUIEvent.EDITFOCUSLOST, this);
163         }
164         isCellEditing = false;
165     }
166 }
167