altoslib: Add user-selectable filter width for data smoothing
[fw/altos] / altosuilib / AltosUIEnable.java
1 /*
2  * Copyright © 2013 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 package org.altusmetrum.altosuilib_12;
20
21 import java.awt.*;
22 import java.awt.event.*;
23 import javax.swing.*;
24 import javax.swing.event.*;
25 import java.io.*;
26 import java.util.concurrent.*;
27 import java.util.*;
28 import org.altusmetrum.altoslib_12.*;
29
30 import org.jfree.ui.*;
31 import org.jfree.chart.*;
32 import org.jfree.chart.plot.*;
33 import org.jfree.chart.axis.*;
34 import org.jfree.chart.renderer.*;
35 import org.jfree.chart.renderer.xy.*;
36 import org.jfree.chart.labels.*;
37 import org.jfree.data.xy.*;
38 import org.jfree.data.*;
39
40 public class AltosUIEnable extends Container implements ChangeListener {
41
42         Insets          il, ir;
43         int             y;
44         int             x;
45         JCheckBox       imperial_units;
46         JLabel          speed_filter_label;
47         JSlider         speed_filter;
48         JLabel          accel_filter_label;
49         JSlider         accel_filter;
50         AltosFilterListener     filter_listener;
51
52         static final int max_rows = 14;
53
54         public void units_changed(boolean imperial_units) {
55                 if (this.imperial_units != null) {
56                         this.imperial_units.setSelected(imperial_units);
57                 }
58         }
59
60         class GraphElement implements ActionListener {
61                 AltosUIGrapher  grapher;
62                 JCheckBox       enable;
63                 String          name;
64
65                 public void actionPerformed(ActionEvent ae) {
66                         grapher.set_enable(enable.isSelected());
67                 }
68
69                 GraphElement (String name, AltosUIGrapher grapher, boolean enabled) {
70                         this.name = name;
71                         this.grapher = grapher;
72                         enable = new JCheckBox(name, enabled);
73                         grapher.set_enable(enabled);
74                         enable.addActionListener(this);
75                 }
76         }
77
78         LinkedList<GraphElement> elements = new LinkedList<GraphElement>();
79
80         public void add(String name, AltosUIGrapher grapher, boolean enabled) {
81
82                 GraphElement    e = new GraphElement(name, grapher, enabled);
83                 GridBagConstraints c = new GridBagConstraints();
84
85                 elements.add(e);
86
87                 /* Add element */
88                 c = new GridBagConstraints();
89                 c.gridx = x; c.gridy = y;
90                 c.fill = GridBagConstraints.HORIZONTAL;
91                 c.anchor = GridBagConstraints.CENTER;
92                 c.insets = ir;
93                 add(e.enable, c);
94
95                 /* Next row */
96                 y++;
97                 if (y == max_rows) {
98                         x++;
99                         y = 0;
100                 }
101         }
102
103         public void stateChanged(ChangeEvent e) {
104                 JSlider filter = (JSlider) e.getSource();
105                 if (!filter.getValueIsAdjusting()) {
106                         double  speed_value = (int) speed_filter.getValue() / 1000.0;
107                         double  accel_value = (int) accel_filter.getValue() / 1000.0;
108                         if (filter_listener != null) {
109                                 filter_listener.filter_changed(speed_value, accel_value);
110                         }
111                 }
112         }
113
114         public void add_units() {
115                 /* Imperial units setting */
116
117                 /* Add label */
118                 imperial_units = new JCheckBox("Imperial Units", AltosUIPreferences.imperial_units());
119                 imperial_units.addActionListener(new ActionListener() {
120                                 public void actionPerformed(ActionEvent e) {
121                                         JCheckBox item = (JCheckBox) e.getSource();
122                                         boolean enabled = item.isSelected();
123                                         AltosUIPreferences.set_imperial_units(enabled);
124                                 }
125                         });
126                 imperial_units.setToolTipText("Use Imperial units instead of metric");
127                 GridBagConstraints c = new GridBagConstraints();
128                 c.gridx = 0; c.gridy = 1000;
129                 c.fill = GridBagConstraints.NONE;
130                 c.anchor = GridBagConstraints.LINE_START;
131                 c.insets = il;
132                 add(imperial_units, c);
133
134                 speed_filter_label = new JLabel("Speed Filter(ms)");
135                 c = new GridBagConstraints();
136                 c.gridx = 0; c.gridy = 1001;
137                 c.fill = GridBagConstraints.NONE;
138                 c.anchor = GridBagConstraints.LINE_START;
139                 c.insets = il;
140                 add(speed_filter_label, c);
141
142                 speed_filter = new JSlider(JSlider.HORIZONTAL, 0, 10000, (int) (filter_listener.speed_filter() * 1000.0));
143                 Hashtable<Integer,JLabel> label_table = new Hashtable<Integer,JLabel>();
144                 for (int i = 0; i <= 10000; i += 5000) {
145                         label_table.put(new Integer(i), new JLabel(String.format("%d", i)));
146                 }
147                 speed_filter.setPaintTicks(true);
148                 speed_filter.setMajorTickSpacing(1000);
149                 speed_filter.setMinorTickSpacing(250);
150                 speed_filter.setLabelTable(label_table);
151                 speed_filter.setPaintTrack(false);
152                 speed_filter.setSnapToTicks(true);
153                 speed_filter.setPaintLabels(true);
154                 speed_filter.addChangeListener(this);
155
156                 c = new GridBagConstraints();
157                 c.gridx = 1; c.gridy = 1001;
158                 c.gridwidth = 1000; c.gridheight = 1;
159                 c.fill = GridBagConstraints.BOTH;
160                 c.anchor = GridBagConstraints.LINE_START;
161                 c.insets = il;
162                 add(speed_filter, c);
163
164                 accel_filter_label = new JLabel("Acceleration Filter(ms)");
165                 c = new GridBagConstraints();
166                 c.gridx = 0; c.gridy = 1002;
167                 c.fill = GridBagConstraints.NONE;
168                 c.anchor = GridBagConstraints.LINE_START;
169                 c.insets = il;
170                 add(accel_filter_label, c);
171
172                 accel_filter = new JSlider(JSlider.HORIZONTAL, 0, 10000, (int) (filter_listener.accel_filter() * 1000.0));
173                 accel_filter.setPaintTicks(true);
174                 accel_filter.setMajorTickSpacing(1000);
175                 accel_filter.setMinorTickSpacing(250);
176                 accel_filter.setLabelTable(label_table);
177                 accel_filter.setPaintTrack(false);
178                 accel_filter.setSnapToTicks(true);
179                 accel_filter.setPaintLabels(true);
180                 accel_filter.addChangeListener(this);
181
182                 c = new GridBagConstraints();
183                 c.gridx = 1; c.gridy = 1002;
184                 c.gridwidth = 1000; c.gridheight = 1;
185                 c.fill = GridBagConstraints.BOTH;
186                 c.anchor = GridBagConstraints.LINE_START;
187                 c.insets = il;
188                 add(accel_filter, c);
189         }
190
191         public AltosUIEnable(AltosFilterListener filter_listener) {
192                 this.filter_listener = filter_listener;
193                 il = new Insets(4,4,4,4);
194                 ir = new Insets(4,4,4,4);
195                 x = 0;
196                 y = 0;
197                 setLayout(new GridBagLayout());
198                 add_units();
199         }
200 }