diff options
| -rw-r--r-- | altoslib/AltosConfigData.java | 17 | ||||
| -rw-r--r-- | altoslib/AltosPyro.java | 293 | ||||
| -rw-r--r-- | altoslib/Makefile.am | 3 | ||||
| -rw-r--r-- | altosui/AltosConfig.java | 32 | ||||
| -rw-r--r-- | altosui/AltosConfigPyroUI.java | 288 | ||||
| -rw-r--r-- | altosui/AltosConfigUI.java | 68 | ||||
| -rw-r--r-- | altosui/AltosDialog.java | 6 | ||||
| -rw-r--r-- | altosui/Makefile.am | 1 | 
8 files changed, 697 insertions, 11 deletions
| diff --git a/altoslib/AltosConfigData.java b/altoslib/AltosConfigData.java index a962b105..45a88783 100644 --- a/altoslib/AltosConfigData.java +++ b/altoslib/AltosConfigData.java @@ -50,6 +50,8 @@ public class AltosConfigData implements Iterable<String> {  	public int	storage_size;  	public int	storage_erase_unit; +	public AltosPyro[]	pyros; +  	public static String get_string(String line, String label) throws  ParseException {  		if (line.startsWith(label)) {  			String	quoted = line.substring(label.length()).trim(); @@ -135,6 +137,10 @@ public class AltosConfigData implements Iterable<String> {  		radio_frequency = 0;  		stored_flight = 0;  		serial = -1; +		pyros = null; + +		int npyro = 0; +		int pyro = 0;  		for (;;) {  			String line = link.get_reply();  			if (line == null) @@ -142,6 +148,16 @@ public class AltosConfigData implements Iterable<String> {  			if (line.contains("Syntax error"))  				continue;  			lines.add(line); +			if (pyro < npyro - 1) { +				if (pyros == null) +					pyros = new AltosPyro[npyro]; +				try { +					pyros[pyro] = new AltosPyro(pyro, line); +				} catch (ParseException e) { +				} +				++pyro; +				continue; +			}  			try { serial = get_int(line, "serial-number"); } catch (Exception e) {}  			try { log_format = get_int(line, "log-format"); } catch (Exception e) {}  			try { main_deploy = get_int(line, "Main deploy:"); } catch (Exception e) {} @@ -173,6 +189,7 @@ public class AltosConfigData implements Iterable<String> {  			try { get_int(line, "flight"); stored_flight++; }  catch (Exception e) {}  			try { storage_size = get_int(line, "Storage size:"); } catch (Exception e) {}  			try { storage_erase_unit = get_int(line, "Storage erase unit"); } catch (Exception e) {} +			try { npyro = get_int(line, "Pyro-count:"); pyro = 0; } catch (Exception e) {}  			/* signals the end of the version info */  			if (line.startsWith("software-version")) diff --git a/altoslib/AltosPyro.java b/altoslib/AltosPyro.java new file mode 100644 index 00000000..14051169 --- /dev/null +++ b/altoslib/AltosPyro.java @@ -0,0 +1,293 @@ +/* + * 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.AltosLib; + +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +public class AltosPyro { +	public static final int pyro_none			= 0x00000000; + +	public static final int pyro_accel_less			= 0x00000001; +	public static final int pyro_accel_greater		= 0x00000002; +	public static final String pyro_accel_less_string	= "a<"; +	public static final String pyro_accel_greater_string	= "a>"; +	public static final String pyro_accel_less_name		= "Acceleration less than (m/s²)"; +	public static final String pyro_accel_greater_name	= "Acceleration greater than (m/s²)"; +	public static final double pyro_accel_scale		= 16.0; + +	public static final int pyro_speed_less			= 0x00000004; +	public static final int pyro_speed_greater		= 0x00000008; +	public static final String pyro_speed_less_string	= "s<"; +	public static final String pyro_speed_greater_string	= "s>"; +	public static final String pyro_speed_less_name		= "Speed less than (m/s)"; +	public static final String pyro_speed_greater_name	= "Speed greater than (m/s)"; +	public static final double pyro_speed_scale		= 16.0; + +	public static final int pyro_height_less		= 0x00000010; +	public static final int pyro_height_greater		= 0x00000020; +	public static final String pyro_height_less_string	= "h<"; +	public static final String pyro_height_greater_string	= "h>"; +	public static final String pyro_height_less_name	= "Height less than (m)"; +	public static final String pyro_height_greater_name	= "Height greater than (m)"; +	public static final double pyro_height_scale		= 1.0; + +	public static final int pyro_orient_less		= 0x00000040; +	public static final int pyro_orient_greater		= 0x00000080; +	public static final String pyro_orient_less_string	= "o<"; +	public static final String pyro_orient_greater_string	= "o>"; +	public static final String pyro_orient_less_name	= "Angle from vertical less than (degrees)"; +	public static final String pyro_orient_greater_name	= "Angle from vertical greater than (degrees)"; +	public static final double pyro_orient_scale		= 1.0; + +	public static final int pyro_time_less			= 0x00000100; +	public static final int pyro_time_greater		= 0x00000200; +	public static final String pyro_time_less_string	= "t<"; +	public static final String pyro_time_greater_string	= "t>"; +	public static final String pyro_time_less_name		= "Time since boost less than (s)"; +	public static final String pyro_time_greater_name	= "Time since boost greater than (s)"; +	public static final double pyro_time_scale		= 100.0; + +	public static final int pyro_ascending			= 0x00000400; +	public static final int pyro_descending			= 0x00000800; +	public static final String pyro_ascending_string	= "A"; +	public static final String pyro_descending_string	= "D"; +	public static final String pyro_ascending_name		= "Ascending"; +	public static final String pyro_descending_name		= "Descending"; + +	public static final int pyro_after_motor		= 0x00001000; +	public static final String pyro_after_motor_string	= "m"; +	public static final String pyro_after_motor_name	= "After motor number"; +	public static final double pyro_after_motor_scale	= 1.0; + +	public static final int pyro_delay			= 0x00002000; +	public static final String pyro_delay_string		= "d"; +	public static final String pyro_delay_name		= "Delay after other conditions (s)"; +	public static final double pyro_delay_scale		= 100.0; + +	public static final int pyro_state_less			= 0x00004000; +	public static final int pyro_state_greater_or_equal  	= 0x00008000; +	public static final String pyro_state_less_string	= "f<"; +	public static final String pyro_state_greater_or_equal_string	= "f>="; +	public static final String pyro_state_less_name		= "Flight state before"; +	public static final String pyro_state_greater_or_equal_name	= "Flight state after"; +	public static final double pyro_state_scale		= 1.0; + +	public static final int	pyro_all			= 0x0000ffff; + +	public static final int pyro_no_value			= (pyro_ascending | +								   pyro_descending); + +	public static final int pyro_state_value		= pyro_state_less | pyro_state_greater_or_equal; + +	private static HashMap<String,Integer> string_to_pyro = new HashMap<String,Integer>(); + +	private static HashMap<Integer,String> pyro_to_string = new HashMap<Integer,String>(); + +	private static HashMap<Integer,String> pyro_to_name = new HashMap<Integer,String>(); + +	private static HashMap<Integer,Double> pyro_to_scale = new HashMap<Integer,Double>(); +	 +	private static void insert_map(int flag, String string, String name, double scale) { +		string_to_pyro.put(string, flag); +		pyro_to_string.put(flag, string); +		pyro_to_name.put(flag, name); +		pyro_to_scale.put(flag, scale); +	} +	 +	public static int string_to_pyro(String name) { +		if (string_to_pyro.containsKey(name)) +			return string_to_pyro.get(name); +		return pyro_none; +	} + +	public static String pyro_to_string(int flag) { +		if (pyro_to_string.containsKey(flag)) +			return pyro_to_string.get(flag); +		return null; +	} + +	public static String pyro_to_name(int flag) { +		if (pyro_to_name.containsKey(flag)) +			return pyro_to_name.get(flag); +		return null; +	} + +	public static double pyro_to_scale(int flag) { +		if (pyro_to_scale.containsKey(flag)) +			return pyro_to_scale.get(flag); +		return 1.0; +	} + +	private static void initialize_maps() { +		insert_map(pyro_accel_less, pyro_accel_less_string, pyro_accel_less_name, pyro_accel_scale); +		insert_map(pyro_accel_greater, pyro_accel_greater_string, pyro_accel_greater_name, pyro_accel_scale); + +		insert_map(pyro_speed_less, pyro_speed_less_string, pyro_speed_less_name, pyro_speed_scale); +		insert_map(pyro_speed_greater, pyro_speed_greater_string, pyro_speed_greater_name, pyro_speed_scale); + +		insert_map(pyro_height_less, pyro_height_less_string, pyro_height_less_name, pyro_height_scale); +		insert_map(pyro_height_greater, pyro_height_greater_string, pyro_height_greater_name, pyro_height_scale); + +		insert_map(pyro_orient_less, pyro_orient_less_string, pyro_orient_less_name, pyro_orient_scale); +		insert_map(pyro_orient_greater, pyro_orient_greater_string, pyro_orient_greater_name, pyro_orient_scale); + +		insert_map(pyro_time_less, pyro_time_less_string, pyro_time_less_name, pyro_time_scale); +		insert_map(pyro_time_greater, pyro_time_greater_string, pyro_time_greater_name, pyro_time_scale); + +		insert_map(pyro_ascending, pyro_ascending_string, pyro_ascending_name, 1.0); +		insert_map(pyro_descending, pyro_descending_string, pyro_descending_name, 1.0); + +		insert_map(pyro_after_motor, pyro_after_motor_string, pyro_after_motor_name, 1.0); +		insert_map(pyro_delay, pyro_delay_string, pyro_delay_name, pyro_delay_scale); +		 +		insert_map(pyro_state_less, pyro_state_less_string, pyro_state_less_name, 1.0); +		insert_map(pyro_state_greater_or_equal, pyro_state_greater_or_equal_string, pyro_state_greater_or_equal_name, 1.0); +	} + +	{ +		initialize_maps(); +	} + +	public int	channel; +	public int	flags; +	public int	accel_less, accel_greater; +	public int	speed_less, speed_greater; +	public int	height_less, height_greater; +	public int	orient_less, orient_greater; +	public int	time_less, time_greater; +	public int	delay; +	public int	state_less, state_greater_or_equal; +	public int	motor; + +	public AltosPyro(int in_channel) { +		channel = in_channel; +		flags = 0; +	} + +	private boolean set_ivalue(int flag, int value) { +		switch (flag) { +		case pyro_accel_less:			accel_less = value; break; +		case pyro_accel_greater:		accel_greater = value; break; +		case pyro_speed_less:			speed_less = value; break; +		case pyro_speed_greater:		speed_greater = value; break; +		case pyro_height_less:			height_less = value; break; +		case pyro_height_greater:		height_greater = value; break; +		case pyro_orient_less:			orient_less = value; break; +		case pyro_orient_greater:		orient_greater = value; break; +		case pyro_time_less:			time_less = value; break; +		case pyro_time_greater:			time_greater = value; break; +		case pyro_after_motor:			motor = value; break; +		case pyro_delay:			delay = value; break; +		case pyro_state_less:			state_less = value; break; +		case pyro_state_greater_or_equal:	state_greater_or_equal = value; break; +		default: +			return false; +		} +		return true; +	} + +	public boolean set_value(int flag, double dvalue) { +		return set_ivalue(flag, (int) (dvalue * pyro_to_scale(flag))); +	} + +	private int get_ivalue (int flag) { +		int	value; + +		switch (flag) { +		case pyro_accel_less:			value = accel_less; break; +		case pyro_accel_greater:		value = accel_greater; break; +		case pyro_speed_less:			value = speed_less; break; +		case pyro_speed_greater:		value = speed_greater; break; +		case pyro_height_less:			value = height_less; break; +		case pyro_height_greater:		value = height_greater; break; +		case pyro_orient_less:			value = orient_less; break; +		case pyro_orient_greater:		value = orient_greater; break; +		case pyro_time_less:			value = time_less; break; +		case pyro_time_greater:			value = time_greater; break; +		case pyro_after_motor:			value = motor; break; +		case pyro_delay:			value = delay; break; +		case pyro_state_less:			value = state_less; break; +		case pyro_state_greater_or_equal:	value = state_greater_or_equal; break; +		default:				value = 0; break; +		} +		return value; +	} + +	public double get_value(int flag) { +		return get_ivalue(flag) / pyro_to_scale(flag); +	} + +	public AltosPyro(int in_channel, String line) throws ParseException { +		String[] tokens = line.split("\\s+"); + +		channel = in_channel; +		flags = 0; + +		int i = 0; +		if (tokens[i].equals("Pyro")) +			i += 2; + +		for (; i < tokens.length; i++) { + +			if (tokens[i].equals("<disabled>")) +				break; + +			int	flag = string_to_pyro(tokens[i]); +			if (flag == pyro_none) +				throw new ParseException(String.format("Invalid pyro token \"%s\"", +								       tokens[i]), i); +			flags |= flag; + +			if ((flag & pyro_no_value) == 0) { +				int	value = 0; +				++i; +				try { +					value = AltosLib.fromdec(tokens[i]); +				} catch (NumberFormatException n) { +					throw new ParseException(String.format("Invalid pyro value \"%s\"", +									       tokens[i]), i); +				} +				if (!set_ivalue(flag, value)) +					throw new ParseException(String.format("Internal parser error \"%s\" \"%s\"", +									       tokens[i-1], tokens[i]), i-1); +			} +		} +	} + +	public String toString() { +		String	ret = String.format("%d", channel); + +		for (int flag = 1; flag <= flags; flag <<= 1) { +			if ((flags & flag) != 0) { +				String	add; +				if ((flag & pyro_no_value) == 0) { +					add = String.format(" %s %d", +							    pyro_to_string.get(flag), +							    get_ivalue(flag)); +				} else { +					add = String.format(" %s", +							    pyro_to_string.get(flag)); +				} +				ret = ret.concat(add); +			} +		} +		return ret; +	} +} diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index f04c10c6..2579a650 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -75,7 +75,8 @@ AltosLib_JAVA = \  	$(SRC)/AltosDistance.java \  	$(SRC)/AltosHeight.java \  	$(SRC)/AltosSpeed.java \ -	$(SRC)/AltosAccel.java +	$(SRC)/AltosAccel.java \ +	$(SRC)/AltosPyro.java  JAR=AltosLib.jar diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index 44e5a3fa..be9ab8bf 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -22,6 +22,7 @@ import javax.swing.*;  import java.io.*;  import java.util.concurrent.*;  import org.altusmetrum.AltosLib.*; +import java.text.*;  public class AltosConfig implements ActionListener { @@ -78,6 +79,8 @@ public class AltosConfig implements ActionListener {  	string_ref	version;  	string_ref	product;  	string_ref	callsign; +	int_ref		npyro; +	AltosPyro[]	pyros;  	AltosConfigUI	config_ui;  	boolean		serial_started;  	boolean		made_visible; @@ -162,6 +165,8 @@ public class AltosConfig implements ActionListener {  		config_ui.set_ignite_mode(ignite_mode.get());  		config_ui.set_pad_orientation(pad_orientation.get());  		config_ui.set_callsign(callsign.get()); +		config_ui.set_pyros(pyros); +		config_ui.set_has_pyro(npyro.get() > 0);  		config_ui.set_clean();  		if (!made_visible) {  			made_visible = true; @@ -169,6 +174,8 @@ public class AltosConfig implements ActionListener {  		}  	} +	int	pyro; +  	void process_line(String line) {  		if (line == null) {  			abort(); @@ -179,6 +186,18 @@ public class AltosConfig implements ActionListener {  				update_ui();  			return;  		} +		if (pyro < npyro.get()) { +			if (pyros == null) +				pyros = new AltosPyro[npyro.get()]; + +			try { +				pyros[pyro] = new AltosPyro(pyro, line); +			} catch (ParseException e) { +				System.out.printf ("pyro parse failed %s\n", line); +			} +			++pyro; +			return; +		}  		get_int(line, "serial-number", serial);  		get_int(line, "log-format", log_format);  		get_int(line, "Main deploy:", main_deploy); @@ -200,6 +219,7 @@ public class AltosConfig implements ActionListener {  		get_string(line, "Callsign:", callsign);  		get_string(line,"software-version", version);  		get_string(line,"product", product); +		get_int(line, "Pyro-count:", npyro);  	}  	final static int	serial_mode_read = 0; @@ -243,6 +263,8 @@ public class AltosConfig implements ActionListener {  			callsign.set("N0CALL");  			version.set("unknown");  			product.set("unknown"); +			pyro = 0; +			npyro.set(0);  		}  		void get_data() { @@ -304,6 +326,12 @@ public class AltosConfig implements ActionListener {  					serial_line.printf("c i %d\n", ignite_mode.get());  				if (pad_orientation.get() >= 0)  					serial_line.printf("c o %d\n", pad_orientation.get()); +				if (pyros.length > 0) { +					for (int p = 0; p < pyros.length; p++) { +						serial_line.printf("c P %s\n", +								   pyros[p].toString()); +					} +				}  				serial_line.printf("c w\n");  			} catch (InterruptedException ie) {  			} catch (TimeoutException te) { @@ -431,6 +459,9 @@ public class AltosConfig implements ActionListener {  		if (pad_orientation.get() >= 0)  			pad_orientation.set(config_ui.pad_orientation());  		callsign.set(config_ui.callsign()); +		if (npyro.get() > 0) { +			pyros = config_ui.pyros(); +		}  		run_serial_thread(serial_mode_save);  	} @@ -477,6 +508,7 @@ public class AltosConfig implements ActionListener {  		callsign = new string_ref("N0CALL");  		version = new string_ref("unknown");  		product = new string_ref("unknown"); +		npyro = new int_ref(0);  		device = AltosDeviceDialog.show(owner, Altos.product_any);  		if (device != null) { diff --git a/altosui/AltosConfigPyroUI.java b/altosui/AltosConfigPyroUI.java new file mode 100644 index 00000000..17adb15f --- /dev/null +++ b/altosui/AltosConfigPyroUI.java @@ -0,0 +1,288 @@ +/* + * 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 altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; +import org.altusmetrum.AltosLib.*; + +public class AltosConfigPyroUI +	extends AltosDialog +	implements ItemListener, DocumentListener +{ +	AltosConfigUI	owner; +	Container	pane; + +	static Insets il = new Insets(4,4,4,4); +	static Insets ir = new Insets(4,4,4,4); + +	static String[] state_names; + +	static void make_state_names() { +		if (state_names == null) { + +			state_names = new String[AltosLib.ao_flight_landed - AltosLib.ao_flight_boost + 1]; +			for (int state = AltosLib.ao_flight_boost; state <= AltosLib.ao_flight_landed; state++) +				state_names[state - AltosLib.ao_flight_boost] = AltosLib.state_name_capital(state); +		} +	} + +	class PyroItem implements ItemListener, DocumentListener +	{ +		public int		flag; +		public JRadioButton	enable; +		public JTextField	value; +		public JComboBox	combo; +		AltosConfigPyroUI	ui; + +		public void set_enable(boolean enable) { +			if (value != null) +				value.setEnabled(enable); +			if (combo != null) +				combo.setEnabled(enable); +		} + +		public void itemStateChanged(ItemEvent e) { +			set_enable(enable.isSelected()); +			ui.set_dirty(); +		} + +		public void changedUpdate(DocumentEvent e) { +			ui.set_dirty(); +		} + +		public void insertUpdate(DocumentEvent e) { +			ui.set_dirty(); +		} + +		public void removeUpdate(DocumentEvent e) { +			ui.set_dirty(); +		} + +		public void set(boolean new_enable, double new_value) { +			enable.setSelected(new_enable); +			set_enable(new_enable); +			if (value != null) { +				double	scale = AltosPyro.pyro_to_scale(flag); +				String	format = "%6.0f"; +				if (scale >= 10) +					format = "%6.1f"; +				else if (scale >= 100) +					format = "%6.2f"; +				value.setText(String.format(format, new_value)); +			} +			if (combo != null) +				if (new_value >= AltosLib.ao_flight_boost && new_value <= AltosLib.ao_flight_landed) +					combo.setSelectedIndex((int) new_value - AltosLib.ao_flight_boost); +		} + +		public boolean enabled() { +			return enable.isSelected(); +		} + +		public double value() { +			if (value != null) +				return Double.parseDouble(value.getText()); +			if (combo != null) +				return combo.getSelectedIndex() + AltosLib.ao_flight_boost; +			return 0; +		} + +		public PyroItem(AltosConfigPyroUI in_ui, int in_flag, int x, int y) { + +			ui = in_ui; +			flag = in_flag; + +			GridBagConstraints	c; +			c = new GridBagConstraints(); +			c.gridx = x; c.gridy = y; +			c.gridwidth = 1; +			c.fill = GridBagConstraints.NONE; +			c.anchor = GridBagConstraints.LINE_START; +			c.insets = il; +			enable = new JRadioButton(); +			enable.addItemListener(this); +			pane.add(enable, c); +			 +			if ((flag & AltosPyro.pyro_no_value) == 0) { +				c = new GridBagConstraints(); +				c.gridx = x+1; c.gridy = y; +				c.gridwidth = 1; +				c.fill = GridBagConstraints.NONE; +				c.anchor = GridBagConstraints.LINE_START; +				c.insets = il; +				if ((flag & AltosPyro.pyro_state_value) != 0) { +					make_state_names(); +					combo = new JComboBox(state_names); +					combo.addItemListener(this); +					pane.add(combo, c); +				} else { +					value = new JTextField(10); +					value.getDocument().addDocumentListener(this); +					pane.add(value, c); +				} +			} +		} +	} + +	class PyroColumn { +		public PyroItem[]	items; +		public JLabel		label; +		int			channel; + +		public void set(AltosPyro pyro) { +			int row = 0; +			for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { +				if ((AltosPyro.pyro_all & flag) != 0) { +					items[row].set((pyro.flags & flag) != 0, +						       pyro.get_value(flag)); +					row++; +				} +			} +		} + +		public AltosPyro get() { +			AltosPyro	p = new AltosPyro(channel); + +			int row = 0; +			for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) { +				if ((AltosPyro.pyro_all & flag) != 0) { +					if (items[row].enabled()) { +						System.out.printf ("Flag %x enabled\n", flag); +						p.flags |= flag; +						p.set_value(flag, items[row].value()); +					} +					row++; +				} +			} +			System.out.printf ("Pyro %x %s\n", p.flags, p.toString()); +			return p; +		} + +		public PyroColumn(AltosConfigPyroUI ui, int x, int y, int in_channel) { + +			channel = in_channel; + +			int	nrow = 0; +			for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) +				if ((flag & AltosPyro.pyro_all) != 0) +					nrow++; + +			items = new PyroItem[nrow]; +			int row = 0; +			 +			GridBagConstraints	c; +			c = new GridBagConstraints(); +			c.gridx = x; c.gridy = y; +			c.gridwidth = 2; +			c.fill = GridBagConstraints.NONE; +			c.anchor = GridBagConstraints.CENTER; +			c.insets = il; +			label = new JLabel(String.format("Pyro Channel %d", channel)); +			pane.add(label, c); +			y++; + +			for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) +				if ((flag & AltosPyro.pyro_all) != 0) { +					items[row] = new PyroItem(ui, flag, x, y + row); +					row++; +				} +		} +	} + +	PyroColumn[]	columns; + +	public void set_pyros(AltosPyro[] pyros) { +		for (int i = 0; i < pyros.length; i++) { +			if (pyros[i].channel < columns.length) +				columns[pyros[i].channel].set(pyros[i]); +		} +	} + +	public AltosPyro[] get_pyros() { +		AltosPyro[]	pyros = new AltosPyro[columns.length]; +		for (int c = 0; c < columns.length; c++) +			pyros[c] = columns[c].get(); +		return pyros; +	} + +	public void set_dirty() { +		owner.set_dirty(); +	} + +	public void itemStateChanged(ItemEvent e) { +		owner.set_dirty(); +	} + +	public void changedUpdate(DocumentEvent e) { +		owner.set_dirty(); +	} + +	public void insertUpdate(DocumentEvent e) { +		owner.set_dirty(); +	} + +	public void removeUpdate(DocumentEvent e) { +		owner.set_dirty(); +	} + +	public AltosConfigPyroUI(AltosConfigUI in_owner, AltosPyro[] pyros) { + +		super(in_owner, "Configure Pyro Channels", false); + +		owner = in_owner; + +		GridBagConstraints	c; + +		pane = getContentPane(); +		pane.setLayout(new GridBagLayout()); + +		int	row = 1; + +		for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) { +			String	n; + +			n = AltosPyro.pyro_to_name(flag); +			if (n != null) { +				c = new GridBagConstraints(); +				c.gridx = 0; c.gridy = row; +				c.gridwidth = 1; +				c.fill = GridBagConstraints.NONE; +				c.anchor = GridBagConstraints.LINE_START; +				c.insets = il; +				JLabel label = new JLabel(n); +				pane.add(label, c); +				row++; +			} +		} + +		columns = new PyroColumn[pyros.length]; + +		for (int i = 0; i < pyros.length; i++) { +			columns[i] = new PyroColumn(this, i*2 + 1, 0, i); +			columns[i].set(pyros[i]); +		} +	} + +	public void make_visible() { +		pack(); +		setVisible(true); +	} +} diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index dd34a9cf..feac053b 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -29,7 +29,6 @@ public class AltosConfigUI  {  	Container	pane; -	Box		box;  	JLabel		product_label;  	JLabel		version_label;  	JLabel		serial_label; @@ -62,11 +61,15 @@ public class AltosConfigUI  	JComboBox	pad_orientation_value;  	JTextField	callsign_value; +	JButton		pyro; +  	JButton		save;  	JButton		reset;  	JButton		reboot;  	JButton		close; +	AltosPyro[]	pyros; +  	ActionListener	listener;  	static String[] main_deploy_values = { @@ -510,6 +513,20 @@ public class AltosConfigUI  		set_pad_orientation_tool_tip();  		row++; +		/* Pyro channels */ +		c = new GridBagConstraints(); +		c.gridx = 4; c.gridy = row; +		c.gridwidth = 4; +		c.fill = GridBagConstraints.HORIZONTAL; +		c.anchor = GridBagConstraints.LINE_START; +		c.insets = il; +		c.ipady = 5; +		pyro = new JButton("Configure Pyro Channels"); +		pane.add(pyro, c); +		pyro.addActionListener(this); +		pyro.setActionCommand("Pyro"); +		row++; +  		/* Buttons */  		c = new GridBagConstraints();  		c.gridx = 0; c.gridy = row; @@ -582,10 +599,30 @@ public class AltosConfigUI  		return true;  	} +	void set_dirty() { +		dirty = true; +		save.setEnabled(true); +	} + +	public void set_clean() { +		dirty = false; +		save.setEnabled(false); +	} + +	AltosConfigPyroUI	pyro_ui; +  	/* Listen for events from our buttons */  	public void actionPerformed(ActionEvent e) {  		String	cmd = e.getActionCommand(); +		if (cmd.equals("Pyro")) { +			if (pyro_ui == null && pyros != null) { +				pyro_ui = new AltosConfigPyroUI(this, pyros); +				pyro_ui.make_visible(); +			} +			return; +		} +  		if (cmd.equals("Close") || cmd.equals("Reboot"))  			if (!check_dirty(cmd))  				return; @@ -594,25 +631,25 @@ public class AltosConfigUI  			setVisible(false);  			dispose();  		} -		dirty = false; +		set_clean();  	}  	/* ItemListener interface method */  	public void itemStateChanged(ItemEvent e) { -		dirty = true; +		set_dirty();  	}  	/* DocumentListener interface methods */  	public void changedUpdate(DocumentEvent e) { -		dirty = true; +		set_dirty();  	}  	public void insertUpdate(DocumentEvent e) { -		dirty = true; +		set_dirty();  	}  	public void removeUpdate(DocumentEvent e) { -		dirty = true; +		set_dirty();  	}  	/* Let the config code hook on a listener */ @@ -725,8 +762,7 @@ public class AltosConfigUI  	}  	public void set_flight_log_max(int new_flight_log_max) { -		if (new_flight_log_max == 0) -			flight_log_max_value.setEnabled(false); +		flight_log_max_value.setEnabled(new_flight_log_max > 0);  		flight_log_max_value.setSelectedItem(Integer.toString(new_flight_log_max));  		set_flight_log_max_tool_tip();  	} @@ -793,7 +829,19 @@ public class AltosConfigUI  			return -1;  	} -	public void set_clean() { -		dirty = false; +	public void set_has_pyro(boolean has_pyro) { +		pyro.setEnabled(has_pyro); +	} + +	public void set_pyros(AltosPyro[] new_pyros) { +		pyros = new_pyros; +		if (pyro_ui != null) +			pyro_ui.set_pyros(pyros); +	} + +	public AltosPyro[] pyros() { +		if (pyro_ui != null) +			pyros = pyro_ui.get_pyros(); +		return pyros;  	}  } diff --git a/altosui/AltosDialog.java b/altosui/AltosDialog.java index eac371aa..c2a9d6e6 100644 --- a/altosui/AltosDialog.java +++ b/altosui/AltosDialog.java @@ -45,6 +45,12 @@ public class AltosDialog extends JDialog implements AltosUIListener {  		addWindowListener(new AltosDialogListener());  	} +	public AltosDialog(Dialog dialog, String label, boolean modal) { +		super(dialog, label, modal); +		AltosUIPreferences.register_ui_listener(this); +		addWindowListener(new AltosDialogListener()); +	} +  	public AltosDialog(Frame frame, boolean modal) {  		super(frame, modal);  		AltosUIPreferences.register_ui_listener(this); diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 9f03ceb6..2c46da4a 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -24,6 +24,7 @@ altosui_JAVA = \  	AltosConfig.java \  	AltosConfigFreqUI.java \  	AltosConfigUI.java \ +	AltosConfigPyroUI.java \  	AltosConfigureUI.java \  	AltosConfigTD.java \  	AltosConfigTDUI.java \ | 
