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.core.button;
18  
19  import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
20  import io.github.tonywasher.joceanus.oceanus.date.OceanusDateConfig;
21  import io.github.tonywasher.joceanus.oceanus.date.OceanusDateFormatter;
22  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventManager;
23  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
24  import io.github.tonywasher.joceanus.tethys.api.base.TethysUIArrowIconId;
25  import io.github.tonywasher.joceanus.tethys.api.base.TethysUIEvent;
26  import io.github.tonywasher.joceanus.tethys.api.base.TethysUINode;
27  import io.github.tonywasher.joceanus.tethys.api.button.TethysUIButton;
28  import io.github.tonywasher.joceanus.tethys.api.button.TethysUIDateButtonManager;
29  import io.github.tonywasher.joceanus.tethys.core.base.TethysUICoreComponent;
30  import io.github.tonywasher.joceanus.tethys.core.factory.TethysUICoreFactory;
31  
32  import java.util.Objects;
33  import java.util.function.Consumer;
34  
35  /**
36   * DateButton Manager.
37   * <p>
38   * The EventProvider fires the following events.
39   * <ul>
40   *   <li>TethysUIEvent.NEWVALUE is fired when a new date value is selected.
41   *   <li>TethysUIEvent.EDITFOCUSLOST is fired when the dialog is cancelled without a value being selected.
42   * </ul>
43   */
44  public abstract class TethysUICoreDateButtonManager
45          extends TethysUICoreComponent
46          implements TethysUIDateButtonManager {
47      /**
48       * The Event Manager.
49       */
50      private final OceanusEventManager<TethysUIEvent> theEventManager;
51  
52      /**
53       * The button.
54       */
55      private final TethysUIButton theButton;
56  
57      /**
58       * The date formatter.
59       */
60      private final OceanusDateFormatter theFormatter;
61  
62      /**
63       * The Configuration.
64       */
65      private final OceanusDateConfig theConfig;
66  
67      /**
68       * The DateConfigurator.
69       */
70      private Consumer<OceanusDateConfig> theDateConfigurator = p -> {
71      };
72  
73      /**
74       * The Value.
75       */
76      private OceanusDate theValue;
77  
78      /**
79       * Is the menu showing?
80       */
81      private boolean menuShowing;
82  
83      /**
84       * Constructor.
85       *
86       * @param pFactory the GUI Factory
87       */
88      protected TethysUICoreDateButtonManager(final TethysUICoreFactory<?> pFactory) {
89          /* Create configuration */
90          theFormatter = pFactory.getDataFormatter().getDateFormatter();
91          theConfig = new OceanusDateConfig(theFormatter);
92  
93          /* Create resources */
94          theEventManager = new OceanusEventManager<>();
95          theButton = pFactory.buttonFactory().newButton();
96  
97          /* Note that the button should be Text and Icon and set down Icon */
98          theButton.setTextAndIcon();
99          theButton.setIcon(TethysUIArrowIconId.DOWN);
100 
101         /* Add listener for button */
102         theButton.getEventRegistrar().addEventListener(e -> showDialog());
103 
104         /* Add listener for locale changes */
105         theFormatter.getEventRegistrar().addEventListener(e -> {
106             theConfig.setLocale(theFormatter.getLocale());
107             setButtonText();
108         });
109     }
110 
111     @Override
112     public Integer getId() {
113         return theButton.getId();
114     }
115 
116     @Override
117     public TethysUINode getNode() {
118         return theButton.getNode();
119     }
120 
121     /**
122      * Obtain button.
123      *
124      * @return the button
125      */
126     protected TethysUIButton getButton() {
127         return theButton;
128     }
129 
130     @Override
131     public OceanusDateConfig getConfig() {
132         return theConfig;
133     }
134 
135     @Override
136     public void setEnabled(final boolean pEnabled) {
137         theButton.setEnabled(pEnabled);
138     }
139 
140     @Override
141     public void setVisible(final boolean pVisible) {
142         theButton.setVisible(pVisible);
143     }
144 
145     @Override
146     public OceanusEventRegistrar<TethysUIEvent> getEventRegistrar() {
147         return theEventManager.getEventRegistrar();
148     }
149 
150     /**
151      * show the dialog.
152      */
153     protected abstract void showDialog();
154 
155     @Override
156     public OceanusDate getSelectedDate() {
157         return theValue;
158     }
159 
160     @Override
161     public OceanusDate getEarliestDate() {
162         return theConfig.getEarliestDate();
163     }
164 
165     @Override
166     public OceanusDate getLatestDate() {
167         return theConfig.getLatestDate();
168     }
169 
170     @Override
171     public void setSelectedDate(final OceanusDate pDate) {
172         theValue = pDate;
173         theConfig.setSelectedDate(pDate);
174         setButtonText();
175     }
176 
177     /**
178      * Set button text.
179      */
180     private void setButtonText() {
181         theButton.setText(theFormatter.formatDate(theValue));
182     }
183 
184     @Override
185     public String getText() {
186         return theFormatter.formatDate(theValue);
187     }
188 
189     @Override
190     public void setEarliestDate(final OceanusDate pDate) {
191         theConfig.setEarliestDate(pDate);
192     }
193 
194     @Override
195     public void setLatestDate(final OceanusDate pDate) {
196         theConfig.setLatestDate(pDate);
197     }
198 
199     @Override
200     public boolean allowNullDateSelection() {
201         return theConfig.allowNullDateSelection();
202     }
203 
204     @Override
205     public void setAllowNullDateSelection(final boolean pAllowNullDateSelection) {
206         theConfig.setAllowNullDateSelection(pAllowNullDateSelection);
207     }
208 
209     @Override
210     public void setShowNarrowDays(final boolean pShowNarrowDays) {
211         theConfig.setShowNarrowDays(pShowNarrowDays);
212     }
213 
214     @Override
215     public void setDateConfigurator(final Consumer<OceanusDateConfig> pConfigurator) {
216         theDateConfigurator = pConfigurator;
217     }
218 
219     /**
220      * handleDialogRequest.
221      */
222     protected void handleDialogRequest() {
223         theDateConfigurator.accept(theConfig);
224         menuShowing = true;
225     }
226 
227     /**
228      * handleNewValue.
229      */
230     protected void handleNewValue() {
231         final OceanusDate myNewValue = theConfig.getSelectedDate();
232         if (valueChanged(myNewValue)) {
233             theValue = myNewValue;
234             theEventManager.fireEvent(TethysUIEvent.NEWVALUE, myNewValue);
235             setButtonText();
236         } else if (menuShowing) {
237             theEventManager.fireEvent(TethysUIEvent.EDITFOCUSLOST, theConfig);
238         }
239         menuShowing = false;
240     }
241 
242     /**
243      * has value changed?
244      *
245      * @param pNew the new value
246      * @return true/false
247      */
248     private boolean valueChanged(final OceanusDate pNew) {
249         return !Objects.equals(theValue, pNew);
250     }
251 }