001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.layer.geoimage; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.GridBagLayout; 007import java.awt.event.FocusListener; 008import java.awt.event.ItemListener; 009 010import javax.swing.JCheckBox; 011import javax.swing.JComponent; 012import javax.swing.JLabel; 013import javax.swing.JPanel; 014import javax.swing.JSeparator; 015import javax.swing.JSpinner; 016import javax.swing.SpinnerNumberModel; 017import javax.swing.SwingConstants; 018import javax.swing.event.ChangeListener; 019 020import org.openstreetmap.josm.data.gpx.GpxImageDirectionPositionSettings; 021import org.openstreetmap.josm.tools.GBC; 022 023/** 024 * Panel allowing user to enter {@link GpxImageDirectionPositionSettings}. 025 * @since 18061 026 */ 027public class ImageDirectionPositionPanel extends JPanel { 028 029 private final JCheckBox cChangeImageDirection = new JCheckBox(); 030 private final JSpinner sOffsetDegrees = new JSpinner(new SpinnerNumberModel(0, -360, 360, 1)); 031 032 private final JSpinner sX = new JSpinner(new SpinnerNumberModel(0.0, -50.0, 50.0, 0.1)); 033 private final JSpinner sY = new JSpinner(new SpinnerNumberModel(0.0, -50.0, 50.0, 0.1)); 034 private final JSpinner sZ = new JSpinner(new SpinnerNumberModel(0.0, -20.0, 20.0, 0.1)); 035 036 /** 037 * Constructs a new {@code ImageMetadataModificationPanel} 038 * @param changeDirectionText the text displayed for the change image direction combobox 039 */ 040 protected ImageDirectionPositionPanel(String changeDirectionText) { 041 super(new GridBagLayout()); 042 043 cChangeImageDirection.setText(changeDirectionText); 044 add(cChangeImageDirection, GBC.eol().insets(0, 0, 0, 5)); 045 cChangeImageDirection.addActionListener(e -> sOffsetDegrees.setEnabled(!sOffsetDegrees.isEnabled())); 046 addSetting(tr("Offset angle in degrees:"), sOffsetDegrees); 047 sOffsetDegrees.setEnabled(false); 048 049 add(new JSeparator(SwingConstants.HORIZONTAL), 050 GBC.eol().fill(GBC.HORIZONTAL).insets(0, 12, 0, 12)); 051 052 add(new JLabel(tr("Shift image relative to the direction (in meters)")), 053 GBC.eol().insets(0, 0, 0, 5)); 054 addSetting(tr("X:"), sX); 055 addSetting(tr("Y:"), sY); 056 addSetting(tr("Elevation:"), sZ); 057 } 058 059 /** 060 * Returns a new {@code ImageMetadataModificationPanel} in a GPX trace context. 061 * @return a new {@code ImageMetadataModificationPanel} in a GPX trace context 062 */ 063 public static ImageDirectionPositionPanel forGpxTrace() { 064 return new ImageDirectionPositionPanel(tr("Set image direction towards the next GPX waypoint")); 065 } 066 067 /** 068 * Returns a new {@code ImageMetadataModificationPanel} in an image sequence context. 069 * @return a new {@code ImageMetadataModificationPanel} in an image sequence context 070 */ 071 public static ImageDirectionPositionPanel forImageSequence() { 072 return new ImageDirectionPositionPanel(tr("Set image direction towards the next one")); 073 } 074 075 protected void addSetting(String text, JComponent component) { 076 add(new JLabel(text, JLabel.RIGHT), GBC.std().insets(15, 0, 5, 5).fill(GBC.HORIZONTAL).weight(0, 0)); 077 add(component, GBC.std().fill(GBC.HORIZONTAL)); 078 add(GBC.glue(1, 0), GBC.eol().fill(GBC.HORIZONTAL).weight(1, 0)); 079 } 080 081 /** 082 * Returns the settings set by user. 083 * @return the settings set by user 084 */ 085 public GpxImageDirectionPositionSettings getSettings() { 086 return new GpxImageDirectionPositionSettings( 087 cChangeImageDirection.isSelected(), 088 (Integer) sOffsetDegrees.getValue(), 089 (Double) sX.getValue(), 090 (Double) sY.getValue(), 091 (Double) sZ.getValue()); 092 } 093 094 /** 095 * Adds a focus listener on all spinners of this panel. 096 * @param focusListener focus listener to add 097 */ 098 public void addFocusListenerOnComponent(FocusListener focusListener) { 099 sOffsetDegrees.addFocusListener(focusListener); 100 sX.addFocusListener(focusListener); 101 sY.addFocusListener(focusListener); 102 sZ.addFocusListener(focusListener); 103 } 104 105 /** 106 * Adds a change listener on all checkboxes of this panel. 107 * @param listener change listener to add 108 * @since 18078 109 */ 110 public void addItemListenerOnComponents(ItemListener listener) { 111 cChangeImageDirection.addItemListener(listener); 112 } 113 114 /** 115 * Adds a change listener on all spinners of this panel. 116 * @param listener change listener to add 117 */ 118 public void addChangeListenerOnComponents(ChangeListener listener) { 119 sOffsetDegrees.addChangeListener(listener); 120 sX.addChangeListener(listener); 121 sY.addChangeListener(listener); 122 sZ.addChangeListener(listener); 123 } 124}