diff options
Diffstat (limited to 'altosuilib')
24 files changed, 2076 insertions, 0 deletions
diff --git a/altosuilib/.gitignore b/altosuilib/.gitignore new file mode 100644 index 00000000..4ad8a77a --- /dev/null +++ b/altosuilib/.gitignore @@ -0,0 +1,4 @@ +AltosUIVersion.java +bin +classaltosuilib.stamp +altosuilib*.jar diff --git a/altosuilib/AltosDevice.java b/altosuilib/AltosDevice.java new file mode 100644 index 00000000..2461df1b --- /dev/null +++ b/altosuilib/AltosDevice.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import libaltosJNI.*; + +public interface AltosDevice { + public abstract String toString(); + public abstract String toShortString(); + public abstract int getSerial(); + public abstract String getPath(); + public abstract boolean matchProduct(int product); + public abstract String getErrorString(); + public SWIGTYPE_p_altos_file open(); +} diff --git a/altosuilib/AltosDeviceDialog.java b/altosuilib/AltosDeviceDialog.java new file mode 100644 index 00000000..73bc0b2f --- /dev/null +++ b/altosuilib/AltosDeviceDialog.java @@ -0,0 +1,160 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +public abstract class AltosDeviceDialog extends AltosUIDialog implements ActionListener { + + private AltosDevice value; + private JList list; + private JButton cancel_button; + private JButton select_button; + public Frame frame; + public int product; + public JPanel buttonPane; + + public AltosDevice getValue() { + return value; + } + + public abstract AltosDevice[] devices(); + + public void update_devices() { + AltosDevice[] devices = devices(); + list.setListData(devices); + select_button.setEnabled(devices.length > 0); + } + + public void add_bluetooth() { } + + public AltosDeviceDialog (Frame in_frame, Component location, int in_product) { + super(in_frame, "Device Selection", true); + + product = in_product; + frame = in_frame; + value = null; + + AltosDevice[] devices = devices(); + + cancel_button = new JButton("Cancel"); + cancel_button.setActionCommand("cancel"); + cancel_button.addActionListener(this); + + select_button = new JButton("Select"); + select_button.setActionCommand("select"); + select_button.addActionListener(this); + if (devices.length == 0) + select_button.setEnabled(false); + getRootPane().setDefaultButton(select_button); + + list = new JList(devices) { + //Subclass JList to workaround bug 4832765, which can cause the + //scroll pane to not let the user easily scroll up to the beginning + //of the list. An alternative would be to set the unitIncrement + //of the JScrollBar to a fixed value. You wouldn't get the nice + //aligned scrolling, but it should work. + public int getScrollableUnitIncrement(Rectangle visibleRect, + int orientation, + int direction) { + int row; + if (orientation == SwingConstants.VERTICAL && + direction < 0 && (row = getFirstVisibleIndex()) != -1) { + Rectangle r = getCellBounds(row, row); + if ((r.y == visibleRect.y) && (row != 0)) { + Point loc = r.getLocation(); + loc.y--; + int prevIndex = locationToIndex(loc); + Rectangle prevR = getCellBounds(prevIndex, prevIndex); + + if (prevR == null || prevR.y >= r.y) { + return 0; + } + return prevR.height; + } + } + return super.getScrollableUnitIncrement( + visibleRect, orientation, direction); + } + }; + + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + list.setLayoutOrientation(JList.HORIZONTAL_WRAP); + list.setVisibleRowCount(-1); + list.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + select_button.doClick(); //emulate button click + } + } + }); + JScrollPane listScroller = new JScrollPane(list); + listScroller.setPreferredSize(new Dimension(400, 80)); + listScroller.setAlignmentX(LEFT_ALIGNMENT); + + //Create a container so that we can add a title around + //the scroll pane. Can't add a title directly to the + //scroll pane because its background would be white. + //Lay out the label and scroll pane from top to bottom. + JPanel listPane = new JPanel(); + listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS)); + + JLabel label = new JLabel("Select Device"); + label.setLabelFor(list); + listPane.add(label); + listPane.add(Box.createRigidArea(new Dimension(0,5))); + listPane.add(listScroller); + listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); + + //Lay out the buttons from left to right. + buttonPane = new JPanel(); + buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS)); + buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); + buttonPane.add(Box.createHorizontalGlue()); + buttonPane.add(cancel_button); + buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); + + add_bluetooth(); + + buttonPane.add(select_button); + + //Put everything together, using the content pane's BorderLayout. + Container contentPane = getContentPane(); + contentPane.add(listPane, BorderLayout.CENTER); + contentPane.add(buttonPane, BorderLayout.PAGE_END); + + //Initialize values. + if (devices != null && devices.length != 0) + list.setSelectedValue(devices[0], true); + pack(); + setLocationRelativeTo(location); + } + + //Handle clicks on the Set and Cancel buttons. + public void actionPerformed(ActionEvent e) { + if ("select".equals(e.getActionCommand())) { + value = (AltosDevice)(list.getSelectedValue()); + setVisible(false); + } + if ("cancel".equals(e.getActionCommand())) + setVisible(false); + } + +} diff --git a/altosuilib/AltosFontListener.java b/altosuilib/AltosFontListener.java new file mode 100644 index 00000000..da903352 --- /dev/null +++ b/altosuilib/AltosFontListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +public interface AltosFontListener { + void font_size_changed(int font_size); +} diff --git a/altosuilib/AltosPositionListener.java b/altosuilib/AltosPositionListener.java new file mode 100644 index 00000000..e75d2de5 --- /dev/null +++ b/altosuilib/AltosPositionListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +public interface AltosPositionListener { + public void position_changed(int position); +} diff --git a/altosuilib/AltosUIAxis.java b/altosuilib/AltosUIAxis.java new file mode 100644 index 00000000..867b0384 --- /dev/null +++ b/altosuilib/AltosUIAxis.java @@ -0,0 +1,94 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +import org.jfree.ui.*; +import org.jfree.chart.*; +import org.jfree.chart.plot.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.renderer.*; +import org.jfree.chart.renderer.xy.*; +import org.jfree.chart.labels.*; +import org.jfree.data.xy.*; +import org.jfree.data.*; + +public class AltosUIAxis extends NumberAxis { + String label; + AltosUnits units; + Color color; + int ref; + int visible; + int index; + + public final static int axis_integer = 1; + public final static int axis_include_zero = 2; + + public final static int axis_default = axis_include_zero; + + public void set_units() { + setLabel(String.format("%s (%s)", label, units.show_units())); + } + + public void set_enable(boolean enable) { + if (enable) { + visible++; + if (visible > ref) + System.out.printf("too many visible\n"); + } else { + visible--; + if (visible < 0) + System.out.printf("too few visible\n"); + } + setVisible(visible > 0); + if (enable) + autoAdjustRange(); + } + + public void ref(boolean enable) { + ++ref; + if (enable) { + ++visible; + setVisible(visible > 0); + } + } + + public AltosUIAxis(String label, AltosUnits units, Color color, int index, int flags) { + this.label = label; + this.units = units; + this.index = index; + this.visible = 0; + this.ref = 0; + setLabelPaint(color); + setTickLabelPaint(color); + setVisible(false); + if ((flags & axis_integer) != 0) + setStandardTickUnits(NumberAxis.createIntegerTickUnits()); + setAutoRangeIncludesZero((flags & axis_include_zero) != 0); + } + + public AltosUIAxis(String label, AltosUnits units, Color color, int index) { + this(label, units, color, index, axis_default); + } +} diff --git a/altosuilib/AltosUIConfigure.java b/altosuilib/AltosUIConfigure.java new file mode 100644 index 00000000..9e72e403 --- /dev/null +++ b/altosuilib/AltosUIConfigure.java @@ -0,0 +1,273 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.awt.*; +import java.awt.event.*; +import java.beans.*; +import javax.swing.*; +import javax.swing.event.*; + +class DelegatingRenderer implements ListCellRenderer { + + // ... + public static void install(JComboBox comboBox) { + DelegatingRenderer renderer = new DelegatingRenderer(comboBox); + renderer.initialise(); + comboBox.setRenderer(renderer); + } + + // ... + private final JComboBox comboBox; + + // ... + private ListCellRenderer delegate; + + // ... + private DelegatingRenderer(JComboBox comboBox) { + this.comboBox = comboBox; + } + + // ... + private void initialise() { + delegate = new JComboBox().getRenderer(); + comboBox.addPropertyChangeListener("UI", new PropertyChangeListener() { + + public void propertyChange(PropertyChangeEvent evt) { + delegate = new JComboBox().getRenderer(); + } + }); + } + + // ... + public Component getListCellRendererComponent(JList list, + Object value, int index, boolean isSelected, boolean cellHasFocus) { + + return delegate.getListCellRendererComponent(list, + ((UIManager.LookAndFeelInfo) value).getName(), + index, isSelected, cellHasFocus); + } +} + +public class AltosUIConfigure + extends AltosUIDialog +{ + public JFrame owner; + public Container pane; + + public int row; + + final static String[] font_size_names = { "Small", "Medium", "Large" }; + + public GridBagConstraints constraints (int x, int width, int fill) { + GridBagConstraints c = new GridBagConstraints(); + Insets insets = new Insets(4, 4, 4, 4); + + c.insets = insets; + c.fill = fill; + if (width == 3) + c.anchor = GridBagConstraints.CENTER; + else if (x == 2) + c.anchor = GridBagConstraints.EAST; + else + c.anchor = GridBagConstraints.WEST; + c.gridx = x; + c.gridwidth = width; + c.gridy = row; + return c; + } + + public GridBagConstraints constraints(int x, int width) { + return constraints(x, width, GridBagConstraints.NONE); + } + + public void add_voice() { + } + + public void add_log_dir() { + /* Log directory settings */ + pane.add(new JLabel("Log Directory"), constraints(0, 1)); + + final JButton configure_log = new JButton(AltosUIPreferences.logdir().getPath()); + configure_log.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + AltosUIPreferences.ConfigureLog(); + configure_log.setText(AltosUIPreferences.logdir().getPath()); + } + }); + pane.add(configure_log, constraints(1, 2)); + configure_log.setToolTipText("Which directory flight logs are stored in"); + row++; + } + + public void add_callsign() { + } + + public void add_units() { + /* Imperial units setting */ + pane.add(new JLabel("Imperial Units"), constraints(0, 1)); + + JRadioButton imperial_units = new JRadioButton("Enable", AltosUIPreferences.imperial_units()); + imperial_units.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JRadioButton item = (JRadioButton) e.getSource(); + boolean enabled = item.isSelected(); + AltosUIPreferences.set_imperial_units(enabled); + } + }); + imperial_units.setToolTipText("Use Imperial units instead of metric"); + pane.add(imperial_units, constraints(1, 2)); + row++; + } + + public void add_font_size() { + /* Font size setting */ + pane.add(new JLabel("Font size"), constraints(0, 1)); + + final JComboBox font_size_value = new JComboBox(font_size_names); + int font_size = AltosUIPreferences.font_size(); + font_size_value.setSelectedIndex(font_size - AltosUILib.font_size_small); + font_size_value.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int size = font_size_value.getSelectedIndex() + AltosUILib.font_size_small; + + AltosUIPreferences.set_font_size(size); + } + }); + pane.add(font_size_value, constraints(1, 2, GridBagConstraints.BOTH)); + font_size_value.setToolTipText("Font size used in telemetry window"); + row++; + } + + public void add_look_and_feel() { + /* Look & Feel setting */ + pane.add(new JLabel("Look & feel"), constraints(0, 1)); + + /* + class LookAndFeelRenderer extends BasicComboBoxRenderer implements ListCellRenderer { + + public LookAndFeelRenderer() { + super(); + } + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) + { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + setText(((UIManager.LookAndFeelInfo) value).getName()); + return this; + } + } + */ + + final UIManager.LookAndFeelInfo[] look_and_feels = UIManager.getInstalledLookAndFeels(); + + final JComboBox look_and_feel_value = new JComboBox(look_and_feels); + + DelegatingRenderer.install(look_and_feel_value); + + String look_and_feel = AltosUIPreferences.look_and_feel(); + for (int i = 0; i < look_and_feels.length; i++) + if (look_and_feel.equals(look_and_feels[i].getClassName())) + look_and_feel_value.setSelectedIndex(i); + + look_and_feel_value.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int id = look_and_feel_value.getSelectedIndex(); + + AltosUIPreferences.set_look_and_feel(look_and_feels[id].getClassName()); + } + }); + pane.add(look_and_feel_value, constraints(1, 2, GridBagConstraints.BOTH)); + look_and_feel_value.setToolTipText("Look&feel used for new windows"); + row++; + } + + public void add_position () { + } + + public void add_serial_debug() { + /* Serial debug setting */ + pane.add(new JLabel("Serial Debug"), constraints(0, 1)); + + JRadioButton serial_debug = new JRadioButton("Enable", AltosUIPreferences.serial_debug()); + serial_debug.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JRadioButton item = (JRadioButton) e.getSource(); + boolean enabled = item.isSelected(); + AltosUIPreferences.set_serial_debug(enabled); + } + }); + serial_debug.setToolTipText("Enable/Disable USB I/O getting sent to the console"); + pane.add(serial_debug, constraints(1,2)); + row++; + } + + public void add_bluetooth() { + } + + public void add_frequencies() { + } + + public AltosUIConfigure(JFrame in_owner) { + super(in_owner, "Configure AltosUI", false); + + owner = in_owner; + pane = getContentPane(); + pane.setLayout(new GridBagLayout()); + + row = 0; + + /* Nice label at the top */ + pane.add(new JLabel ("Configure AltOS UI"), + constraints(0, 3)); + row++; + + pane.add(new JLabel (String.format("AltOS version %s", AltosUIVersion.version)), + constraints(0, 3)); + row++; + + add_voice(); + add_log_dir(); + add_callsign(); + add_units(); + add_serial_debug(); + add_font_size(); + add_look_and_feel(); + add_position(); + add_bluetooth(); + add_frequencies(); + + /* And a close button at the bottom */ + JButton close = new JButton("Close"); + close.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + }); + pane.add(close, constraints(0, 3)); + + pack(); + setLocationRelativeTo(owner); + setVisible(true); + } +} diff --git a/altosuilib/AltosUIDataMissing.java b/altosuilib/AltosUIDataMissing.java new file mode 100644 index 00000000..c7b01859 --- /dev/null +++ b/altosuilib/AltosUIDataMissing.java @@ -0,0 +1,25 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +public class AltosUIDataMissing extends Exception { + public int id; + public AltosUIDataMissing(int id) { + this.id = id; + } +}
\ No newline at end of file diff --git a/altosuilib/AltosUIDataPoint.java b/altosuilib/AltosUIDataPoint.java new file mode 100644 index 00000000..d3020410 --- /dev/null +++ b/altosuilib/AltosUIDataPoint.java @@ -0,0 +1,25 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +public interface AltosUIDataPoint { + public abstract double x() throws AltosUIDataMissing; + public abstract double y(int index) throws AltosUIDataMissing; + public abstract int id(int index) throws AltosUIDataMissing; + public abstract String id_name(int index) throws AltosUIDataMissing; +} diff --git a/altosuilib/AltosUIDataSet.java b/altosuilib/AltosUIDataSet.java new file mode 100644 index 00000000..6f23ef9a --- /dev/null +++ b/altosuilib/AltosUIDataSet.java @@ -0,0 +1,23 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +public interface AltosUIDataSet { + public abstract String name(); + public abstract Iterable<AltosUIDataPoint> dataPoints(); +} diff --git a/altosuilib/AltosUIDialog.java b/altosuilib/AltosUIDialog.java new file mode 100644 index 00000000..e1e699a7 --- /dev/null +++ b/altosuilib/AltosUIDialog.java @@ -0,0 +1,59 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +class AltosUIDialogListener extends WindowAdapter { + public void windowClosing (WindowEvent e) { + AltosUIPreferences.unregister_ui_listener((AltosUIDialog) e.getWindow()); + } +} + +public class AltosUIDialog extends JDialog implements AltosUIListener { + + public void ui_changed(String look_and_feel) { + SwingUtilities.updateComponentTreeUI(this); + this.pack(); + } + + public AltosUIDialog() { + AltosUIPreferences.register_ui_listener(this); + addWindowListener(new AltosUIDialogListener()); + } + + public AltosUIDialog(Frame frame, String label, boolean modal) { + super(frame, label, modal); + AltosUIPreferences.register_ui_listener(this); + addWindowListener(new AltosUIDialogListener()); + } + + public AltosUIDialog(Dialog dialog, String label, boolean modal) { + super(dialog, label, modal); + AltosUIPreferences.register_ui_listener(this); + addWindowListener(new AltosUIDialogListener()); + } + + public AltosUIDialog(Frame frame, boolean modal) { + super(frame, modal); + AltosUIPreferences.register_ui_listener(this); + addWindowListener(new AltosUIDialogListener()); + } +} diff --git a/altosuilib/AltosUIEnable.java b/altosuilib/AltosUIEnable.java new file mode 100644 index 00000000..55486dea --- /dev/null +++ b/altosuilib/AltosUIEnable.java @@ -0,0 +1,121 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.altoslib_1.*; + +import org.jfree.ui.*; +import org.jfree.chart.*; +import org.jfree.chart.plot.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.renderer.*; +import org.jfree.chart.renderer.xy.*; +import org.jfree.chart.labels.*; +import org.jfree.data.xy.*; +import org.jfree.data.*; + +public class AltosUIEnable extends Container { + + Insets il, ir; + int y; + + class GraphElement implements ActionListener { + AltosUIGrapher grapher; + JLabel label; + JRadioButton enable; + String name; + + public void actionPerformed(ActionEvent ae) { + grapher.set_enable(enable.isSelected()); + } + + GraphElement (String name, AltosUIGrapher grapher, boolean enabled) { + this.name = name; + this.grapher = grapher; + label = new JLabel(name); + enable = new JRadioButton("Enable", enabled); + grapher.set_enable(enabled); + enable.addActionListener(this); + } + } + + public void add(String name, AltosUIGrapher grapher, boolean enabled) { + + GraphElement e = new GraphElement(name, grapher, enabled); + + /* Add label */ + GridBagConstraints c = new GridBagConstraints(); + c.gridx = 0; c.gridy = y; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + add(e.label, c); + + /* Add radio button */ + c = new GridBagConstraints(); + c.gridx = 1; c.gridy = y; + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.CENTER; + c.insets = ir; + add(e.enable, c); + + /* Next row */ + y++; + } + + public void add_units() { + /* Imperial units setting */ + /* Add label */ + GridBagConstraints c = new GridBagConstraints(); + c.gridx = 0; c.gridy = 1000; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + add(new JLabel("Imperial Units"), c); + + JRadioButton imperial_units = new JRadioButton("Enable", AltosUIPreferences.imperial_units()); + imperial_units.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JRadioButton item = (JRadioButton) e.getSource(); + boolean enabled = item.isSelected(); + AltosUIPreferences.set_imperial_units(enabled); + } + }); + imperial_units.setToolTipText("Use Imperial units instead of metric"); + c = new GridBagConstraints(); + c.gridx = 1; c.gridy = 1000; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.LINE_START; + c.insets = il; + add(imperial_units, c); + } + + public AltosUIEnable() { + il = new Insets(4,4,4,4); + ir = new Insets(4,4,4,4); + y = 0; + setLayout(new GridBagLayout()); + add_units(); + } +} diff --git a/altosuilib/AltosUIFrame.java b/altosuilib/AltosUIFrame.java new file mode 100644 index 00000000..3fc99910 --- /dev/null +++ b/altosuilib/AltosUIFrame.java @@ -0,0 +1,173 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.util.*; + +class AltosUIFrameListener extends WindowAdapter { + public void windowClosing (WindowEvent e) { + AltosUIPreferences.unregister_ui_listener((AltosUIFrame) e.getWindow()); + } +} + +public class AltosUIFrame extends JFrame implements AltosUIListener, AltosPositionListener { + + public void ui_changed(String look_and_feel) { + SwingUtilities.updateComponentTreeUI(this); + this.pack(); + } + + static String[] altos_icon_names = { + "/altus-metrum-16.png", + "/altus-metrum-32.png", + "/altus-metrum-48.png", + "/altus-metrum-64.png", + "/altus-metrum-128.png", + "/altus-metrum-256.png" + }; + + static public String[] icon_names; + + static public void set_icon_names(String[] new_icon_names) { icon_names = new_icon_names; } + + public String[] icon_names() { + if (icon_names == null) + set_icon_names(altos_icon_names); + return icon_names; + } + + public void set_icon() { + ArrayList<Image> icons = new ArrayList<Image>(); + String[] icon_names = icon_names(); + + for (int i = 0; i < icon_names.length; i++) { + java.net.URL imgURL = AltosUIFrame.class.getResource(icon_names[i]); + if (imgURL != null) + icons.add(new ImageIcon(imgURL).getImage()); + } + setIconImages(icons); + } + + private boolean location_by_platform = true; + + public void setLocationByPlatform(boolean lbp) { + location_by_platform = lbp; + super.setLocationByPlatform(lbp); + } + + public void setSize() { + /* Smash sizes around so that the window comes up in the right shape */ + Insets i = getInsets(); + Dimension ps = rootPane.getPreferredSize(); + ps.width += i.left + i.right; + ps.height += i.top + i.bottom; + setPreferredSize(ps); + setSize(ps); + } + + public void setPosition (int position) { + Insets i = getInsets(); + Dimension ps = getSize(); + + /* Stick the window in the desired location on the screen */ + setLocationByPlatform(false); + GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + Rectangle r = gc.getBounds(); + + /* compute X position */ + int x = 0; + int y = 0; + switch (position) { + case AltosUILib.position_top_left: + case AltosUILib.position_left: + case AltosUILib.position_bottom_left: + x = 0; + break; + case AltosUILib.position_top: + case AltosUILib.position_center: + case AltosUILib.position_bottom: + x = (r.width - ps.width) / 2; + break; + case AltosUILib.position_top_right: + case AltosUILib.position_right: + case AltosUILib.position_bottom_right: + x = r.width - ps.width + i.right; + break; + } + + /* compute Y position */ + switch (position) { + case AltosUILib.position_top_left: + case AltosUILib.position_top: + case AltosUILib.position_top_right: + y = 0; + break; + case AltosUILib.position_left: + case AltosUILib.position_center: + case AltosUILib.position_right: + y = (r.height - ps.height) / 2; + break; + case AltosUILib.position_bottom_left: + case AltosUILib.position_bottom: + case AltosUILib.position_bottom_right: + y = r.height - ps.height + i.bottom; + break; + } + setLocation(x, y); + } + + int position; + + public void position_changed(int position) { + this.position = position; + if (!location_by_platform) + setPosition(position); + } + + public void setVisible (boolean visible) { + if (visible) + setLocationByPlatform(location_by_platform); + super.setVisible(visible); + if (visible) { + setSize(); + if (!location_by_platform) + setPosition(position); + } + } + + void init() { + AltosUIPreferences.register_ui_listener(this); + AltosUIPreferences.register_position_listener(this); + position = AltosUIPreferences.position(); + addWindowListener(new AltosUIFrameListener()); + set_icon(); + } + + public AltosUIFrame() { + init(); + } + + public AltosUIFrame(String name) { + super(name); + init(); + } +} diff --git a/altosuilib/AltosUIGraph.java b/altosuilib/AltosUIGraph.java new file mode 100644 index 00000000..5f3a2eef --- /dev/null +++ b/altosuilib/AltosUIGraph.java @@ -0,0 +1,161 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +import org.jfree.ui.*; +import org.jfree.chart.*; +import org.jfree.chart.plot.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.renderer.*; +import org.jfree.chart.renderer.xy.*; +import org.jfree.chart.labels.*; +import org.jfree.data.xy.*; +import org.jfree.data.*; + +public class AltosUIGraph implements AltosUnitsListener { + + XYPlot plot; + JFreeChart chart; + public ChartPanel panel; + NumberAxis xAxis; + AltosUIEnable enable; + ArrayList<AltosUIGrapher> graphers; + AltosUIDataSet dataSet; + int axis_index; + int series_index; + + static final private Color gridline_color = new Color(0, 0, 0); + static final private Color border_color = new Color(255, 255, 255); + static final private Color background_color = new Color(255, 255, 255); + + public JPanel panel() { + return panel; + } + + public AltosUIAxis newAxis(String label, AltosUnits units, Color color, int flags) { + AltosUIAxis axis = new AltosUIAxis(label, units, color, axis_index++, flags); + plot.setRangeAxis(axis.index, axis); + return axis; + } + + public AltosUIAxis newAxis(String label, AltosUnits units, Color color) { + return newAxis(label, units, color, AltosUIAxis.axis_default); + } + + public void addSeries(String label, int fetch, AltosUnits units, Color color, + boolean enabled, AltosUIAxis axis) { + AltosUISeries series = new AltosUISeries(label, fetch, units, color, enabled, axis); + XYSeriesCollection dataset = new XYSeriesCollection(series); + + series.renderer.setPlot(plot); + plot.setDataset(series_index, dataset); + plot.setRenderer(series_index, series.renderer); + plot.mapDatasetToRangeAxis(series_index, axis.index); + if (enable != null) + enable.add(label, series, enabled); + this.graphers.add(series); + series_index++; + } + + public void addSeries(String label, int fetch, AltosUnits units, Color color) { + addSeries(label, fetch, units, color, true, newAxis(label, units, color)); + } + + public void addMarker(String label, int fetch, Color color) { + AltosUIMarker marker = new AltosUIMarker(fetch, color, plot); + if (enable != null) + enable.add(label, marker, true); + this.graphers.add(marker); + } + + public void resetData() { + for (AltosUIGrapher g : graphers) { + g.clear(); + g.setNotify(false); + } + if (dataSet != null) { + for (AltosUIDataPoint dataPoint : dataSet.dataPoints()) + for (AltosUIGrapher g : graphers) + g.add(dataPoint); + } + for (AltosUIGrapher g : graphers) { + g.setNotify(true); + g.fireSeriesChanged(); + } + } + + public void units_changed(boolean imperial_units) { + for (AltosUIGrapher g : graphers) + g.set_units(); + resetData(); + } + + public void setName (String name) { + chart.setTitle(name); + } + + public void setDataSet (AltosUIDataSet dataSet) { + this.dataSet = dataSet; + resetData(); + if (dataSet != null) + setName(dataSet.name()); + } + + public AltosUIGraph(AltosUIEnable enable) { + + this.enable = enable; + this.graphers = new ArrayList<AltosUIGrapher>(); + this.series_index = 0; + this.axis_index = 0; + + xAxis = new NumberAxis("Time (s)"); + + xAxis.setAutoRangeIncludesZero(true); + + plot = new XYPlot(); + plot.setDomainAxis(xAxis); + plot.setOrientation(PlotOrientation.VERTICAL); + plot.setDomainPannable(true); + plot.setRangePannable(true); + + chart = new JFreeChart("Flight", JFreeChart.DEFAULT_TITLE_FONT, + plot, true); + + ChartUtilities.applyCurrentTheme(chart); + + plot.setDomainGridlinePaint(gridline_color); + plot.setRangeGridlinePaint(gridline_color); + plot.setBackgroundPaint(background_color); + plot.setBackgroundAlpha((float) 1); + + chart.setBackgroundPaint(background_color); + chart.setBorderPaint(border_color); + panel = new ChartPanel(chart); + panel.setMouseWheelEnabled(true); + panel.setPreferredSize(new java.awt.Dimension(800, 500)); + + AltosPreferences.register_units_listener(this); + } +}
\ No newline at end of file diff --git a/altosuilib/AltosUIGrapher.java b/altosuilib/AltosUIGrapher.java new file mode 100644 index 00000000..8f0ce801 --- /dev/null +++ b/altosuilib/AltosUIGrapher.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +import org.jfree.ui.*; +import org.jfree.chart.*; +import org.jfree.chart.plot.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.renderer.*; +import org.jfree.chart.renderer.xy.*; +import org.jfree.chart.labels.*; +import org.jfree.data.xy.*; +import org.jfree.data.*; + +interface AltosUIGrapher { + + public abstract void set_units(); + + public abstract void clear(); + + public abstract void add(AltosUIDataPoint dataPoint); + + public abstract void set_enable(boolean enable); + + public abstract void setNotify(boolean notify); + + public abstract void fireSeriesChanged(); +} diff --git a/altosuilib/AltosUILib.java b/altosuilib/AltosUILib.java new file mode 100644 index 00000000..1b121405 --- /dev/null +++ b/altosuilib/AltosUILib.java @@ -0,0 +1,103 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.awt.*; +import libaltosJNI.*; + +import org.altusmetrum.altoslib_1.*; + +public class AltosUILib extends AltosLib { + + public static final int tab_elt_pad = 5; + + public static Font label_font; + public static Font value_font; + public static Font status_font; + public static Font table_label_font; + public static Font table_value_font; + + final public static int font_size_small = 1; + final public static int font_size_medium = 2; + final public static int font_size_large = 3; + + final public static int position_top_left = 0; + final public static int position_top = 1; + final public static int position_top_right = 2; + final public static int position_left = 3; + final public static int position_center = 4; + final public static int position_right = 5; + final public static int position_bottom_left = 6; + final public static int position_bottom = 7; + final public static int position_bottom_right = 8; + + public static void set_fonts(int size) { + int brief_size; + int table_size; + int status_size; + + switch (size) { + case font_size_small: + brief_size = 16; + status_size = 18; + table_size = 11; + break; + default: + case font_size_medium: + brief_size = 22; + status_size = 24; + table_size = 14; + break; + case font_size_large: + brief_size = 26; + status_size = 30; + table_size = 17; + break; + } + label_font = new Font("Dialog", Font.PLAIN, brief_size); + value_font = new Font("Monospaced", Font.PLAIN, brief_size); + status_font = new Font("SansSerif", Font.BOLD, status_size); + table_label_font = new Font("SansSerif", Font.PLAIN, table_size); + table_value_font = new Font("Monospaced", Font.PLAIN, table_size); + } + + static public final int text_width = 20; + + static public boolean initialized = false; + static public boolean loaded_library = false; + + public static boolean load_library() { + if (!initialized) { + try { + System.loadLibrary("altos"); + libaltos.altos_init(); + loaded_library = true; + } catch (UnsatisfiedLinkError e) { + try { + System.loadLibrary("altos64"); + libaltos.altos_init(); + loaded_library = true; + } catch (UnsatisfiedLinkError e2) { + loaded_library = false; + } + } + initialized = true; + } + return loaded_library; + } +} diff --git a/altosuilib/AltosUIListener.java b/altosuilib/AltosUIListener.java new file mode 100644 index 00000000..450dc0bf --- /dev/null +++ b/altosuilib/AltosUIListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +public interface AltosUIListener { + public void ui_changed(String look_and_feel); +} diff --git a/altosuilib/AltosUIMarker.java b/altosuilib/AltosUIMarker.java new file mode 100644 index 00000000..0949be6f --- /dev/null +++ b/altosuilib/AltosUIMarker.java @@ -0,0 +1,112 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +import org.jfree.ui.*; +import org.jfree.chart.*; +import org.jfree.chart.plot.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.renderer.*; +import org.jfree.chart.renderer.xy.*; +import org.jfree.chart.labels.*; +import org.jfree.data.xy.*; +import org.jfree.data.*; + +public class AltosUIMarker implements AltosUIGrapher { + ArrayList<ValueMarker> markers; + int last_id; + XYPlot plot; + boolean enabled; + int fetch; + Color color; + + private void remove_markers() { + for (ValueMarker marker : markers) + plot.removeDomainMarker(marker); + } + + private void add_markers() { + for (ValueMarker marker : markers) + plot.addDomainMarker(marker); + } + + public void set_units() { + } + + public void set_enable(boolean enable) { + if (enabled == enable) + return; + if (enable) + add_markers(); + else + remove_markers(); + enabled = enable; + } + + public void clear() { + if (enabled) + remove_markers(); + markers = new ArrayList<ValueMarker>(); + } + + public void add(AltosUIDataPoint dataPoint) { + try { + int id = dataPoint.id(fetch); + if (id < 0) + return; + if (id == last_id) + return; + ValueMarker marker = new ValueMarker(dataPoint.x()); + marker.setLabel(dataPoint.id_name(fetch)); + marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT); + marker.setLabelTextAnchor(TextAnchor.TOP_LEFT); + marker.setPaint(color); + if (enabled) + plot.addDomainMarker(marker); + markers.add(marker); + last_id = id; + } catch (AltosUIDataMissing m) { + } + } + + public AltosUIMarker (int fetch, Color color, XYPlot plot, boolean enable) { + markers = new ArrayList<ValueMarker>(); + last_id = -1; + this.fetch = fetch; + this.color = color; + this.plot = plot; + this.enabled = enable; + } + + public void setNotify(boolean notify) { + } + + public void fireSeriesChanged() { + } + + public AltosUIMarker (int fetch, Color color, XYPlot plot) { + this(fetch, color, plot, true); + } +}
\ No newline at end of file diff --git a/altosuilib/AltosUIPreferences.java b/altosuilib/AltosUIPreferences.java new file mode 100644 index 00000000..49321bce --- /dev/null +++ b/altosuilib/AltosUIPreferences.java @@ -0,0 +1,218 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.io.*; +import java.util.*; +import java.awt.Component; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +public class AltosUIPreferences extends AltosPreferences { + + /* font size preferences name */ + final static String fontSizePreference = "FONT-SIZE"; + + /* Look&Feel preference name */ + final static String lookAndFeelPreference = "LOOK-AND-FEEL"; + + /* Window position preference name */ + final static String positionPreference = "POSITION"; + + /* UI Component to pop dialogs up */ + static Component component; + + static LinkedList<AltosFontListener> font_listeners; + + static int font_size = AltosUILib.font_size_medium; + + static LinkedList<AltosUIListener> ui_listeners; + + static String look_and_feel = null; + + /* Serial debug */ + public static boolean serial_debug; + + static LinkedList<AltosPositionListener> position_listeners; + + public static int position = AltosUILib.position_top_left; + + public static void init() { + AltosPreferences.init(new AltosUIPreferencesBackend()); + + font_listeners = new LinkedList<AltosFontListener>(); + + font_size = backend.getInt(fontSizePreference, AltosUILib.font_size_medium); + AltosUILib.set_fonts(font_size); + look_and_feel = backend.getString(lookAndFeelPreference, UIManager.getSystemLookAndFeelClassName()); + + ui_listeners = new LinkedList<AltosUIListener>(); + serial_debug = backend.getBoolean(serialDebugPreference, false); + + AltosLink.set_debug(serial_debug); + + position = backend.getInt(positionPreference, AltosUILib.position_top_left); + position_listeners = new LinkedList<AltosPositionListener>(); + } + + static { init(); } + + public static void set_component(Component in_component) { + component = in_component; + } + + private static boolean check_dir(File dir) { + if (!dir.exists()) { + if (!dir.mkdirs()) { + JOptionPane.showMessageDialog(component, + dir.getName(), + "Cannot create directory", + JOptionPane.ERROR_MESSAGE); + return false; + } + } else if (!dir.isDirectory()) { + JOptionPane.showMessageDialog(component, + dir.getName(), + "Is not a directory", + JOptionPane.ERROR_MESSAGE); + return false; + } + return true; + } + + /* Configure the log directory. This is where all telemetry and eeprom files + * will be written to, and where replay will look for telemetry files + */ + public static void ConfigureLog() { + JFileChooser logdir_chooser = new JFileChooser(logdir.getParentFile()); + + logdir_chooser.setDialogTitle("Configure Data Logging Directory"); + logdir_chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + + if (logdir_chooser.showDialog(component, "Select Directory") == JFileChooser.APPROVE_OPTION) { + File dir = logdir_chooser.getSelectedFile(); + if (check_dir(dir)) + set_logdir(dir); + } + } + public static int font_size() { + synchronized (backend) { + return font_size; + } + } + + static void set_fonts() { + } + + public static void set_font_size(int new_font_size) { + synchronized (backend) { + font_size = new_font_size; + backend.putInt(fontSizePreference, font_size); + flush_preferences(); + AltosUILib.set_fonts(font_size); + for (AltosFontListener l : font_listeners) + l.font_size_changed(font_size); + } + } + + public static void register_font_listener(AltosFontListener l) { + synchronized (backend) { + font_listeners.add(l); + } + } + + public static void unregister_font_listener(AltosFontListener l) { + synchronized (backend) { + font_listeners.remove(l); + } + } + + public static void set_look_and_feel(String new_look_and_feel) { + try { + UIManager.setLookAndFeel(new_look_and_feel); + } catch (Exception e) { + } + synchronized(backend) { + look_and_feel = new_look_and_feel; + backend.putString(lookAndFeelPreference, look_and_feel); + flush_preferences(); + for (AltosUIListener l : ui_listeners) + l.ui_changed(look_and_feel); + } + } + + public static String look_and_feel() { + synchronized (backend) { + return look_and_feel; + } + } + + public static void register_ui_listener(AltosUIListener l) { + synchronized(backend) { + ui_listeners.add(l); + } + } + + public static void unregister_ui_listener(AltosUIListener l) { + synchronized (backend) { + ui_listeners.remove(l); + } + } + public static void set_serial_debug(boolean new_serial_debug) { + AltosLink.set_debug(new_serial_debug); + synchronized (backend) { + serial_debug = new_serial_debug; + backend.putBoolean(serialDebugPreference, serial_debug); + flush_preferences(); + } + } + + public static boolean serial_debug() { + synchronized (backend) { + return serial_debug; + } + } + + public static void register_position_listener(AltosPositionListener l) { + synchronized(backend) { + position_listeners.add(l); + } + } + + public static void unregister_position_listener(AltosPositionListener l) { + synchronized (backend) { + position_listeners.remove(l); + } + } + + public static void set_position(int new_position) { + synchronized (backend) { + position = new_position; + backend.putInt(positionPreference, position); + flush_preferences(); + for (AltosPositionListener l : position_listeners) + l.position_changed(position); + } + } + + public static int position() { + synchronized (backend) { + return position; + } + } +} diff --git a/altosuilib/AltosUIPreferencesBackend.java b/altosuilib/AltosUIPreferencesBackend.java new file mode 100644 index 00000000..8a5386c3 --- /dev/null +++ b/altosuilib/AltosUIPreferencesBackend.java @@ -0,0 +1,101 @@ +/* + * Copyright © 2012 Mike Beattie <mike@ethernal.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.io.File; +import java.util.prefs.*; +import org.altusmetrum.altoslib_1.*; +import javax.swing.filechooser.FileSystemView; + +public class AltosUIPreferencesBackend implements AltosPreferencesBackend { + + private Preferences _preferences = null; + + public AltosUIPreferencesBackend() { + _preferences = Preferences.userRoot().node("/org/altusmetrum/altosui"); + } + + public AltosUIPreferencesBackend(Preferences in_preferences) { + _preferences = in_preferences; + } + + public String getString(String key, String def) { + return _preferences.get(key, def); + } + public void putString(String key, String value) { + _preferences.put(key, value); + } + + public int getInt(String key, int def) { + return _preferences.getInt(key, def); + } + public void putInt(String key, int value) { + _preferences.putInt(key, value); + } + + public double getDouble(String key, double def) { + return _preferences.getDouble(key, def); + } + public void putDouble(String key, double value) { + _preferences.putDouble(key, value); + } + + public boolean getBoolean(String key, boolean def) { + return _preferences.getBoolean(key, def); + } + public void putBoolean(String key, boolean value) { + _preferences.putBoolean(key, value); + } + + public boolean nodeExists(String key) { + try { + return _preferences.nodeExists(key); + } catch (BackingStoreException be) { + return false; + } + } + + public AltosPreferencesBackend node(String key) { + return new AltosUIPreferencesBackend(_preferences.node(key)); + } + + public String[] keys() { + try { + return _preferences.keys(); + } catch (BackingStoreException be) { + return null; + } + } + + public void remove(String key) { + _preferences.remove(key); + } + + public void flush() { + try { + _preferences.flush(); + } catch (BackingStoreException ee) { + System.err.printf("Cannot save preferences\n"); + } + } + + public File homeDirectory() { + /* Use the file system view default directory */ + return FileSystemView.getFileSystemView().getDefaultDirectory(); + } +} diff --git a/altosuilib/AltosUISeries.java b/altosuilib/AltosUISeries.java new file mode 100644 index 00000000..ac09a3cc --- /dev/null +++ b/altosuilib/AltosUISeries.java @@ -0,0 +1,91 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.altoslib_1.*; + +import org.jfree.ui.*; +import org.jfree.chart.*; +import org.jfree.chart.plot.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.renderer.*; +import org.jfree.chart.renderer.xy.*; +import org.jfree.chart.labels.*; +import org.jfree.data.xy.*; +import org.jfree.data.*; + +public class AltosUISeries extends XYSeries implements AltosUIGrapher { + AltosUIAxis axis; + String label; + AltosUnits units; + Color color; + XYItemRenderer renderer; + int fetch; + boolean enable; + + public void set_units() { + axis.set_units(); + StandardXYToolTipGenerator ttg; + + String example = units.graph_format(4); + + ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", + units.show_units()), + new java.text.DecimalFormat(example), + new java.text.DecimalFormat(example)); + renderer.setBaseToolTipGenerator(ttg); + } + + public void set_enable(boolean enable) { + if (this.enable != enable) { + this.enable = enable; + renderer.setSeriesVisible(0, enable); + axis.set_enable(enable); + } + } + + public void add(AltosUIDataPoint dataPoint) { + try { + super.add(dataPoint.x(), units.value(dataPoint.y(fetch))); + } catch (AltosUIDataMissing dm) { + } + } + + public AltosUISeries (String label, int fetch, AltosUnits units, Color color, + boolean enable, AltosUIAxis axis) { + super(label); + this.label = label; + this.fetch = fetch; + this.units = units; + this.color = color; + this.enable = enable; + this.axis = axis; + + axis.ref(this.enable); + + renderer = new XYLineAndShapeRenderer(true, false); + renderer.setSeriesPaint(0, color); + renderer.setSeriesVisible(0, enable); + set_units(); + } +} diff --git a/altosuilib/AltosUIVersion.java.in b/altosuilib/AltosUIVersion.java.in new file mode 100644 index 00000000..169cca1b --- /dev/null +++ b/altosuilib/AltosUIVersion.java.in @@ -0,0 +1,22 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +public class AltosUIVersion { + public final static String version = "@VERSION@"; +} diff --git a/altosuilib/AltosUSBDevice.java b/altosuilib/AltosUSBDevice.java new file mode 100644 index 00000000..a06b6869 --- /dev/null +++ b/altosuilib/AltosUSBDevice.java @@ -0,0 +1,113 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_1; + +import java.util.*; +import libaltosJNI.*; + +public class AltosUSBDevice extends altos_device implements AltosDevice { + + public String toString() { + String name = getName(); + if (name == null) + name = "Altus Metrum"; + return String.format("%-20.20s %4d %s", + name, getSerial(), getPath()); + } + + public String toShortString() { + String name = getName(); + if (name == null) + name = "Altus Metrum"; + return String.format("%s %d %s", + name, getSerial(), getPath()); + + } + + public String getErrorString() { + altos_error error = new altos_error(); + + libaltos.altos_get_last_error(error); + return String.format("%s (%d)", error.getString(), error.getCode()); + } + + public SWIGTYPE_p_altos_file open() { + return libaltos.altos_open(this); + } + + public boolean isAltusMetrum() { + if (getVendor() != AltosUILib.vendor_altusmetrum) + return false; + if (getProduct() < AltosUILib.product_altusmetrum_min) + return false; + if (getProduct() > AltosUILib.product_altusmetrum_max) + return false; + return true; + } + + public boolean matchProduct(int want_product) { + + if (!isAltusMetrum()) + return false; + + if (want_product == AltosUILib.product_any) + return true; + + if (want_product == AltosUILib.product_basestation) + return matchProduct(AltosUILib.product_teledongle) || + matchProduct(AltosUILib.product_teleterra) || + matchProduct(AltosUILib.product_telebt) || + matchProduct(AltosUILib.product_megadongle); + + if (want_product == AltosUILib.product_altimeter) + return matchProduct(AltosUILib.product_telemetrum) || + matchProduct(AltosUILib.product_telemega) || + matchProduct(AltosUILib.product_telegps); + + int have_product = getProduct(); + + if (have_product == AltosUILib.product_altusmetrum) /* old devices match any request */ + return true; + + if (want_product == have_product) + return true; + + return false; + } + + static public java.util.List<AltosDevice> list(int product) { + if (!AltosUILib.load_library()) + return null; + + SWIGTYPE_p_altos_list list = libaltos.altos_list_start(); + + ArrayList<AltosDevice> device_list = new ArrayList<AltosDevice>(); + if (list != null) { + for (;;) { + AltosUSBDevice device = new AltosUSBDevice(); + if (libaltos.altos_list_next(list, device) == 0) + break; + if (device.matchProduct(product)) + device_list.add(device); + } + libaltos.altos_list_finish(list); + } + + return device_list; + } +} diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am new file mode 100644 index 00000000..0cd2aaea --- /dev/null +++ b/altosuilib/Makefile.am @@ -0,0 +1,52 @@ +AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation + +JAVAROOT=bin + +CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH="$(JAVAROOT):../altoslib/*:../libaltos:/usr/share/java/*" + +SRC=. + +altosuilibdir = $(datadir)/java + +altosuilib_JAVA = \ + AltosDevice.java \ + AltosDeviceDialog.java \ + AltosFontListener.java \ + AltosPositionListener.java \ + AltosUIConfigure.java \ + AltosUIAxis.java \ + AltosUIDataMissing.java \ + AltosUIDataPoint.java \ + AltosUIDataSet.java \ + AltosUIGraph.java \ + AltosUIGrapher.java \ + AltosUIDialog.java \ + AltosUIEnable.java \ + AltosUIFrame.java \ + AltosUILib.java \ + AltosUIListener.java \ + AltosUIMarker.java \ + AltosUIPreferencesBackend.java \ + AltosUIPreferences.java \ + AltosUISeries.java \ + AltosUIVersion.java \ + AltosUSBDevice.java + +JAR=altosuilib_$(ALTOSUILIB_VERSION).jar + +all-local: $(JAR) + +clean-local: + -rm -rf $(JAVAROOT) $(JAR) + +install-altosuilibJAVA: $(JAR) + @$(NORMAL_INSTALL) + test -z "$(altosuilibdir)" || $(MKDIR_P) "$(DESTDIR)$(altosuilibdir)" + echo " $(INSTALL_DATA)" "$(JAR)" "'$(DESTDIR)$(altosuilibdir)/$(JAR)"; \ + $(INSTALL_DATA) "$(JAR)" "$(DESTDIR)$(altosuilibdir)" + +$(JAVAROOT): + mkdir -p $(JAVAROOT) + +$(JAR): classaltosuilib.stamp + jar cf $@ -C $(JAVAROOT) . |
