Motor chooser search field and new edit motor config dialog
[debian/openrocket] / src / net / sf / openrocket / gui / dialogs / PreferencesDialog.java
1 package net.sf.openrocket.gui.dialogs;
2
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.awt.event.WindowAdapter;
6 import java.awt.event.WindowEvent;
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import javax.swing.AbstractListModel;
11 import javax.swing.ComboBoxModel;
12 import javax.swing.JButton;
13 import javax.swing.JComboBox;
14 import javax.swing.JDialog;
15 import javax.swing.JFrame;
16 import javax.swing.JLabel;
17 import javax.swing.JPanel;
18 import javax.swing.JTabbedPane;
19
20 import net.miginfocom.swing.MigLayout;
21 import net.sf.openrocket.gui.components.ResizeLabel;
22 import net.sf.openrocket.unit.Unit;
23 import net.sf.openrocket.unit.UnitGroup;
24 import net.sf.openrocket.util.GUIUtil;
25 import net.sf.openrocket.util.Prefs;
26
27 public class PreferencesDialog extends JDialog {
28         
29         private final List<DefaultUnitSelector> unitSelectors = new ArrayList<DefaultUnitSelector>();
30
31         private PreferencesDialog() {
32                 super((JFrame)null, "Preferences", true);
33                 
34                 JPanel panel = new JPanel(new MigLayout("fill, gap unrel","[grow]","[grow][]"));
35                                 
36                 JTabbedPane tabbedPane = new JTabbedPane();
37                 panel.add(tabbedPane,"grow, wrap");
38                 
39
40                 tabbedPane.addTab("Units", null, unitsPane(), "Default units");
41                 tabbedPane.addTab("Confirmation", null, confirmationPane(), "Confirmation dialog settings");
42                 
43                 
44                 
45                 JButton close = new JButton("Close");
46                 close.addActionListener(new ActionListener() {
47                         @Override
48                         public void actionPerformed(ActionEvent arg0) {
49                                 PreferencesDialog.this.setVisible(false);
50                                 PreferencesDialog.this.dispose();
51                         }
52                 });
53                 panel.add(close,"span, right, tag close");
54                 
55                 this.setContentPane(panel);
56                 pack();
57                 setAlwaysOnTop(true);
58                 this.setLocationRelativeTo(null);
59                 
60                 this.addWindowListener(new WindowAdapter() {
61                         @Override
62                         public void windowClosed(WindowEvent e) {
63                                 Prefs.storeDefaultUnits();
64                         }
65                 });
66
67                 GUIUtil.setDefaultButton(close);
68                 GUIUtil.installEscapeCloseOperation(this);
69         }
70         
71         
72         private JPanel confirmationPane() {
73                 JPanel panel = new JPanel(new MigLayout("fill"));
74                 
75                 panel.add(new JLabel("Position to insert new body components:"));
76                 panel.add(new JComboBox(new PrefChoiseSelector(Prefs.BODY_COMPONENT_INSERT_POSITION_KEY,
77                                 "Always ask", "Insert in middle", "Add to end")), "wrap para, sg combos");
78                 
79                 panel.add(new JLabel("Confirm deletion of simulations:"));
80                 panel.add(new JComboBox(new PrefBooleanSelector(Prefs.CONFIRM_DELETE_SIMULATION,
81                                 "Delete", "Confirm", true)), "wrap para, sg combos");
82                 
83                 return panel;
84         }
85         
86         private JPanel unitsPane() {
87                 JPanel panel = new JPanel(new MigLayout("", "[][]40lp[][]"));
88                 JComboBox combo;
89                 
90                 panel.add(new JLabel("Select your preferred units:"), "span, wrap paragraph");
91                 
92 /*
93                 public static final UnitGroup UNITS_LENGTH;
94                 public static final UnitGroup UNITS_MOTOR_DIMENSIONS;
95                 public static final UnitGroup UNITS_DISTANCE;
96                 
97                 public static final UnitGroup UNITS_VELOCITY;
98                 public static final UnitGroup UNITS_ACCELERATION;
99                 public static final UnitGroup UNITS_MASS;
100                 public static final UnitGroup UNITS_FORCE;
101                 public static final UnitGroup UNITS_IMPULSE;
102
103                 public static final UnitGroup UNITS_STABILITY;
104                 public static final UnitGroup UNITS_FLIGHT_TIME;
105                 public static final UnitGroup UNITS_ROLL;
106                 
107                 public static final UnitGroup UNITS_AREA;
108                 public static final UnitGroup UNITS_DENSITY_LINE;
109                 public static final UnitGroup UNITS_DENSITY_SURFACE;
110                 public static final UnitGroup UNITS_DENSITY_BULK;
111                 public static final UnitGroup UNITS_ROUGHNESS;
112                 
113                 public static final UnitGroup UNITS_TEMPERATURE;
114                 public static final UnitGroup UNITS_PRESSURE;
115                 public static final UnitGroup UNITS_ANGLE;
116 */
117                 
118                 panel.add(new JLabel("Rocket dimensions:"));
119                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_LENGTH));
120                 panel.add(combo, "sizegroup boxes");
121                 
122                 panel.add(new JLabel("Line density:"));
123                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_LINE));
124                 panel.add(combo, "sizegroup boxes, wrap");
125                 
126                 
127                 
128                 panel.add(new JLabel("Motor dimensions:"));
129                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MOTOR_DIMENSIONS));
130                 panel.add(combo, "sizegroup boxes");
131                 
132                 panel.add(new JLabel("Surface density:"));
133                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_SURFACE));
134                 panel.add(combo, "sizegroup boxes, wrap");
135                 
136
137                 
138                 panel.add(new JLabel("Distance:"));
139                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DISTANCE));
140                 panel.add(combo, "sizegroup boxes");
141                 
142                 panel.add(new JLabel("Bulk density::"));
143                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_BULK));
144                 panel.add(combo, "sizegroup boxes, wrap");
145                 
146
147                 
148                 panel.add(new JLabel("Velocity:"));
149                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_VELOCITY));
150                 panel.add(combo, "sizegroup boxes");
151
152                 panel.add(new JLabel("Surface roughness:"));
153                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROUGHNESS));
154                 panel.add(combo, "sizegroup boxes, wrap");
155                 
156                 
157                 
158                 panel.add(new JLabel("Acceleration:"));
159                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ACCELERATION));
160                 panel.add(combo, "sizegroup boxes");
161
162                 panel.add(new JLabel("Area:"));
163                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_AREA));
164                 panel.add(combo, "sizegroup boxes, wrap");
165                 
166                 
167
168                 panel.add(new JLabel("Mass:"));
169                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MASS));
170                 panel.add(combo, "sizegroup boxes");
171                 
172                 panel.add(new JLabel("Angle:"));
173                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ANGLE));
174                 panel.add(combo, "sizegroup boxes, wrap");
175                 
176
177                 
178                 panel.add(new JLabel("Force:"));
179                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_FORCE));
180                 panel.add(combo, "sizegroup boxes");
181                 
182                 panel.add(new JLabel("Roll rate:"));
183                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROLL));
184                 panel.add(combo, "sizegroup boxes, wrap");
185                 
186
187                 
188                 panel.add(new JLabel("Total impulse:"));
189                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_IMPULSE));
190                 panel.add(combo, "sizegroup boxes");
191                 
192                 panel.add(new JLabel("Temperature:"));
193                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_TEMPERATURE));
194                 panel.add(combo, "sizegroup boxes, wrap");
195                 
196
197                 
198                 panel.add(new JLabel("Stability:"));
199                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_STABILITY));
200                 panel.add(combo, "sizegroup boxes");
201
202                 panel.add(new JLabel("Pressure:"));
203                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_PRESSURE));
204                 panel.add(combo, "sizegroup boxes, wrap para");
205                 
206                 
207                 
208                 JButton button = new JButton("Default metric");
209                 button.addActionListener(new ActionListener() {
210                         @Override
211                         public void actionPerformed(ActionEvent e) {
212                                 UnitGroup.setDefaultMetricUnits();
213                                 for (DefaultUnitSelector s: unitSelectors)
214                                         s.fireChange();
215                         }
216                 });
217                 panel.add(button, "spanx, split 2, grow");
218                 
219                 button = new JButton("Default imperial");
220                 button.addActionListener(new ActionListener() {
221                         @Override
222                         public void actionPerformed(ActionEvent e) {
223                                 UnitGroup.setDefaultImperialUnits();
224                                 for (DefaultUnitSelector s: unitSelectors)
225                                         s.fireChange();
226                         }
227                 });
228                 panel.add(button, "grow, wrap para");
229                 
230                 
231                 panel.add(new ResizeLabel("The effects will take place the next time you open a window.",-2),
232                                 "spanx, wrap");
233                 
234
235                 return panel;
236         }
237         
238         
239         
240         
241         private class DefaultUnitSelector extends AbstractListModel implements ComboBoxModel {
242                 
243                 private final UnitGroup group;
244                 public DefaultUnitSelector(UnitGroup group) {
245                         this.group = group;
246                         unitSelectors.add(this);
247                 }
248                 
249                 @Override
250                 public Object getSelectedItem() {
251                         return group.getDefaultUnit();
252                 }
253                 @Override
254                 public void setSelectedItem(Object item) {
255                         if (!(item instanceof Unit)) {
256                                 throw new IllegalArgumentException("Illegal argument "+item);
257                         }
258                         group.setDefaultUnit(group.getUnitIndex((Unit)item));
259                 }
260                 @Override
261                 public Object getElementAt(int index) {
262                         return group.getUnit(index);
263                 }
264                 @Override
265                 public int getSize() {
266                         return group.getUnitCount();
267                 }
268                 
269                 
270                 public void fireChange() {
271                         this.fireContentsChanged(this, 0, this.getSize());
272                 }
273         }
274         
275
276         
277         private class PrefChoiseSelector extends AbstractListModel implements ComboBoxModel {
278                 private final String preference;
279                 private final String[] descriptions;
280                 
281                 public PrefChoiseSelector(String preference, String ... descriptions) {
282                         this.preference = preference;
283                         this.descriptions = descriptions;
284                 }
285                 
286                 @Override
287                 public Object getSelectedItem() {
288                         return descriptions[Prefs.getChoise(preference, descriptions.length, 0)];
289                 }
290                 
291                 @Override
292                 public void setSelectedItem(Object item) {
293                         if (!(item instanceof String)) {
294                                 throw new IllegalArgumentException("Illegal argument "+item);
295                         }
296                         int index;
297                         for (index = 0; index < descriptions.length; index++) {
298                                 if (((String)item).equalsIgnoreCase(descriptions[index]))
299                                         break;
300                         }
301                         if (index >= descriptions.length) {
302                                 throw new IllegalArgumentException("Illegal argument "+item);
303                         }
304                         
305                         Prefs.putChoise(preference, index);
306                 }
307                 
308                 @Override
309                 public Object getElementAt(int index) {
310                         return descriptions[index];
311                 }
312                 @Override
313                 public int getSize() {
314                         return descriptions.length;
315                 }
316         }
317         
318
319         private class PrefBooleanSelector extends AbstractListModel implements ComboBoxModel {
320                 private final String preference;
321                 private final String trueDesc, falseDesc;
322                 private final boolean def;
323                 
324                 public PrefBooleanSelector(String preference, String falseDescription, 
325                                 String trueDescription, boolean defaultState) {
326                         this.preference = preference;
327                         this.trueDesc = trueDescription;
328                         this.falseDesc = falseDescription;
329                         this.def = defaultState;
330                 }
331                 
332                 @Override
333                 public Object getSelectedItem() {
334                         if (Prefs.NODE.getBoolean(preference, def)) {
335                                 return trueDesc;
336                         } else {
337                                 return falseDesc;
338                         }
339                 }
340                 
341                 @Override
342                 public void setSelectedItem(Object item) {
343                         if (!(item instanceof String)) {
344                                 throw new IllegalArgumentException("Illegal argument "+item);
345                         }
346                         
347                         if (trueDesc.equals(item)) {
348                                 Prefs.NODE.putBoolean(preference, true);
349                         } else if (falseDesc.equals(item)) {
350                                 Prefs.NODE.putBoolean(preference, false);
351                         } else {
352                                 throw new IllegalArgumentException("Illegal argument "+item);
353                         }
354                 }
355                 
356                 @Override
357                 public Object getElementAt(int index) {
358                         switch (index) {
359                         case 0:
360                                 return def ? trueDesc : falseDesc;
361
362                         case 1:
363                                 return def ? falseDesc: trueDesc;
364                                 
365                         default:
366                                 throw new IndexOutOfBoundsException("Boolean asked for index="+index);
367                         }
368                 }
369                 @Override
370                 public int getSize() {
371                         return 2;
372                 }
373         }
374         
375         
376         
377         ////////  Singleton implementation  ////////
378         
379         private static PreferencesDialog dialog = null;
380         
381         public static void showPreferences() {
382                 if (dialog != null) {
383                         dialog.dispose();
384                 }
385                 dialog = new PreferencesDialog();
386                 dialog.setVisible(true);
387         }
388         
389         
390 }