File: SelectorDisplay.java

package info (click to toggle)
gpsprune 22.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 4,664 kB
  • sloc: java: 44,711; sh: 25; makefile: 22; python: 15
file content (359 lines) | stat: -rw-r--r-- 11,184 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
package tim.prune.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import tim.prune.DataSubscriber;
import tim.prune.I18nManager;
import tim.prune.data.TrackInfo;

/**
 * Class to allow selection of points and photos
 * as a visual component
 */
public class SelectorDisplay extends GenericDisplay
{
	// Track details
	private JLabel _trackpointsLabel = null;
	private JLabel _filenameLabel = null;
	// Scroll bar
	private JScrollBar _scroller = null;
	private boolean _ignoreScrollEvents = false;

	// Panel containing lists
	private JPanel _listsPanel = null;
	private int _visiblePanels = 1;
	// Waypoints
	private JPanel _waypointListPanel = null;
	private JList<String> _waypointList = null;
	private WaypointListModel _waypointListModel = null;
	// Photos
	private JPanel _photoListPanel = null;
	private JList<String> _photoList = null;
	private MediaListModel _photoListModel = null;
	// Audio files
	private JPanel _audioListPanel = null;
	private JList<String> _audioList = null;
	private MediaListModel _audioListModel = null;

	// scrollbar interval
	private static final int SCROLLBAR_INTERVAL = 50;
	// number of rows in lists
	private static final int NUM_LIST_ENTRIES = 7;


	/**
	 * Constructor
	 * @param inTrackInfo Track info object
	 */
	public SelectorDisplay(TrackInfo inTrackInfo)
	{
		super(inTrackInfo);
		setLayout(new BorderLayout());

		JPanel mainPanel = new JPanel();
		mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
		mainPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));

		// Track details panel
		JPanel trackDetailsPanel = new JPanel();
		trackDetailsPanel.setLayout(new BoxLayout(trackDetailsPanel, BoxLayout.Y_AXIS));
		trackDetailsPanel.setBorder(BorderFactory.createCompoundBorder(
			BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(3, 3, 3, 3))
		);
		JLabel trackDetailsLabel = new JLabel(I18nManager.getText("details.trackdetails"));
		Font biggerFont = trackDetailsLabel.getFont();
		biggerFont = biggerFont.deriveFont(Font.BOLD, biggerFont.getSize2D() + 2.0f);
		trackDetailsLabel.setFont(biggerFont);
		trackDetailsPanel.add(trackDetailsLabel);
		_trackpointsLabel = new JLabel(I18nManager.getText("details.notrack"));
		trackDetailsPanel.add(_trackpointsLabel);
		_filenameLabel = new JLabel("");
		_filenameLabel.setMinimumSize(new Dimension(120, 10));
		trackDetailsPanel.add(_filenameLabel);

		// Scroll bar
		_scroller = new JScrollBar(JScrollBar.HORIZONTAL, 0, SCROLLBAR_INTERVAL, 0, 100);
		_scroller.addAdjustmentListener(new AdjustmentListener() {
			public void adjustmentValueChanged(AdjustmentEvent e) {
				selectPoint(e.getValue());
			}
		});
		_scroller.setEnabled(false);

		// Add panel for waypoints / photos
		_listsPanel = new JPanel();
		_listsPanel.setLayout(new GridLayout(0, 1));
		_listsPanel.setBorder(BorderFactory.createCompoundBorder(
			BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(3, 3, 3, 3))
		);
		_waypointListModel = new WaypointListModel(_trackInfo.getTrack());
		_waypointList = new JList<String>(_waypointListModel);
		_waypointList.setVisibleRowCount(NUM_LIST_ENTRIES);
		_waypointList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e)
			{
				if (!e.getValueIsAdjusting()) selectWaypoint(_waypointList.getSelectedIndex());
			}
		});
		_waypointListPanel = makeListPanel("details.lists.waypoints", _waypointList);
		_listsPanel.add(_waypointListPanel);
		// photo list
		_photoListModel = new MediaListModel(_trackInfo.getPhotoList());
		_photoList = new JList<String>(_photoListModel);
		_photoList.setVisibleRowCount(NUM_LIST_ENTRIES);
		_photoList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e)
			{
				if (!e.getValueIsAdjusting()) {
					selectPhoto(_photoList.getSelectedIndex());
				}
			}});
		_photoListPanel = makeListPanel("details.lists.photos", _photoList);
		// don't add photo list (because there aren't any photos yet)

		// List for audio clips
		_audioListModel = new MediaListModel(_trackInfo.getAudioList());
		_audioList = new JList<String>(_audioListModel);
		_audioList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e)
			{
				if (!e.getValueIsAdjusting()) {
					selectAudio(_audioList.getSelectedIndex());
				}
			}});
		_audioListPanel = makeListPanel("details.lists.audio", _audioList);
		// don't add audio list either
		_listsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);

		// add the controls to the main panel
		mainPanel.add(trackDetailsPanel);
		mainPanel.add(Box.createVerticalStrut(5));
		mainPanel.add(_scroller);
		mainPanel.add(Box.createVerticalStrut(5));

		// add the main panel at the top
		add(mainPanel, BorderLayout.NORTH);
		// and lists in the centre
		add(_listsPanel, BorderLayout.CENTER);
		// set preferred width to be small
		setPreferredSize(new Dimension(100, 100));
	}


	/**
	 * Select the specified point
	 * @param inValue value to select
	 */
	private void selectPoint(int inValue)
	{
		if (_track != null && !_ignoreScrollEvents) {
			_trackInfo.selectPoint(inValue);
		}
	}


	/**
	 * Select the specified photo
	 * @param inPhotoIndex index of selected photo
	 */
	private void selectPhoto(int inPhotoIndex)
	{
		_trackInfo.selectPhoto(inPhotoIndex);
	}

	/**
	 * Select the specified audio clip
	 * @param inIndex index of selected audio clip
	 */
	private void selectAudio(int inIndex)
	{
		_trackInfo.selectAudio(inIndex);
	}

	/**
	 * Select the specified waypoint
	 * @param inWaypointIndex index of selected waypoint
	 */
	private void selectWaypoint(int inWaypointIndex)
	{
		if (inWaypointIndex >= 0) {
			_trackInfo.selectPoint(_waypointListModel.getWaypoint(inWaypointIndex));
		}
	}


	/**
	 * Notification that Track has been updated
	 */
	public void dataUpdated(byte inUpdateType)
	{
		// Update track data
		if (_track == null || _track.getNumPoints() <= 0)
		{
			_trackpointsLabel.setText(I18nManager.getText("details.notrack"));
			_filenameLabel.setText("");
			_filenameLabel.setToolTipText("");
		}
		else
		{
			_trackpointsLabel.setText(I18nManager.getText("details.track.points") + ": "
				+ _track.getNumPoints());
			int numFiles = _trackInfo.getFileInfo().getNumFiles();
			if (numFiles == 1)
			{
				final String filenameString = _trackInfo.getFileInfo().getFilename();
				_filenameLabel.setText(I18nManager.getText("details.track.file") + ": "
					+ filenameString);
				_filenameLabel.setToolTipText(filenameString);
			}
			else if (numFiles > 1)
			{
				final String labelText = I18nManager.getText("details.track.numfiles") + ": " + numFiles;
				_filenameLabel.setText(labelText);
				_filenameLabel.setToolTipText(labelText);
			}
			else
			{
				_filenameLabel.setText("");
				_filenameLabel.setToolTipText("");
			}
		}

		// Update scroller settings
		int currentPointIndex = _trackInfo.getSelection().getCurrentPointIndex();
		_ignoreScrollEvents = true;
		if (_track == null || _track.getNumPoints() < 2)
		{
			// careful to avoid event loops here
			// _scroller.setValue(0);
			_scroller.setEnabled(false);
		}
		else
		{
			_scroller.setMaximum(_track.getNumPoints() -1 + SCROLLBAR_INTERVAL);
			if (currentPointIndex >= 0)
				_scroller.setValue(currentPointIndex);
			_scroller.setEnabled(true);
		}
		_ignoreScrollEvents = false;

		// update waypoints and photos if necessary
		if ((inUpdateType |
			(DataSubscriber.DATA_ADDED_OR_REMOVED | DataSubscriber.DATA_EDITED | DataSubscriber.WAYPOINTS_MODIFIED)) > 0)
		{
			_waypointListModel.fireChanged();
		}
		if ((inUpdateType &
			(DataSubscriber.DATA_ADDED_OR_REMOVED | DataSubscriber.DATA_EDITED | DataSubscriber.PHOTOS_MODIFIED)) > 0)
		{
			_photoListModel.fireChanged();
			_audioListModel.fireChanged();
		}
		// Deselect selected waypoint if selected point has since changed
		if (_waypointList.getSelectedIndex() >= 0)
		{
			if (_trackInfo.getCurrentPoint() == null
			 || _waypointList.getSelectedIndex() >= _waypointListModel.getSize()
			 || !_waypointListModel.getWaypoint(_waypointList.getSelectedIndex()).equals(_trackInfo.getCurrentPoint()))
			{
				// point is selected in list but different from current point - deselect
				_waypointList.clearSelection();
			}
		}
		// Hide photo list if no photos loaded, same for audio
		redrawLists(_photoListModel.getSize() > 0, _audioListModel.getSize() > 0);

		// Make sure correct photo is selected
		if (_photoListModel.getSize() > 0)
		{
			int photoIndex = _trackInfo.getSelection().getCurrentPhotoIndex();
			int listSelection = _photoList.getSelectedIndex();
			// Change listbox selection if indexes not equal
			if (listSelection != photoIndex)
			{
				if (photoIndex < 0) {
					_photoList.clearSelection();
				}
				else {
					_photoList.setSelectedIndex(photoIndex);
				}
			}
		}
		// Same for audio clips
		if (_audioListModel.getSize() > 0)
		{
			int audioIndex = _trackInfo.getSelection().getCurrentAudioIndex();
			int listSelection = _audioList.getSelectedIndex();
			// Change listbox selection if indexes not equal
			if (listSelection != audioIndex)
			{
				if (audioIndex < 0) {
					_audioList.clearSelection();
				}
				else {
					_audioList.setSelectedIndex(audioIndex);
				}
			}
		}
	}

	/**
	 * Make one of the three list panels
	 * @param inNameKey key for heading text
	 * @param inList list object
	 * @return panel object
	 */
	private static JPanel makeListPanel(String inNameKey, JList<String> inList)
	{
		JPanel panel = new JPanel();
		panel.setLayout(new BorderLayout());
		panel.add(new JLabel(I18nManager.getText(inNameKey)), BorderLayout.NORTH);
		inList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		panel.add(new JScrollPane(inList), BorderLayout.CENTER);
		return panel;
	}

	/**
	 * Redraw the list panels in the display according to which ones should be shown
	 * @param inShowPhotos true to show photo list
	 * @param inShowAudio true to show audio list
	 */
	private void redrawLists(boolean inShowPhotos, boolean inShowAudio)
	{
		// exit if same as last time
		int panels = 1 + (inShowPhotos?2:0) + (inShowAudio?4:0);
		if (panels == _visiblePanels) return;
		_visiblePanels = panels;
		// remove all panels and re-add them
		_listsPanel.removeAll();
		_listsPanel.setLayout(new GridLayout(0, 1));
		_listsPanel.add(_waypointListPanel);
		if (inShowPhotos) {
			_listsPanel.add(_photoListPanel);
		}
		if (inShowAudio) {
			_listsPanel.add(_audioListPanel);
		}
		_listsPanel.invalidate();
		_listsPanel.getParent().validate();
	}
}