source: trunk/src_apollo/org/apollo/gui/ExpandedTrackPopup.java@ 315

Last change on this file since 315 was 315, checked in by bjn8, 16 years ago

Apollo spin-off added

File size: 22.5 KB
Line 
1package org.apollo.gui;
2
3import java.awt.BorderLayout;
4import java.awt.Color;
5import java.awt.Dimension;
6import java.awt.Event;
7import java.awt.Font;
8import java.awt.Graphics;
9import java.awt.GridBagConstraints;
10import java.awt.GridBagLayout;
11import java.awt.Insets;
12import java.awt.Point;
13import java.awt.Rectangle;
14import java.awt.event.ActionEvent;
15import java.awt.event.ActionListener;
16import java.awt.event.KeyEvent;
17import java.awt.event.KeyListener;
18import java.awt.event.MouseEvent;
19import java.awt.event.MouseListener;
20import java.awt.event.MouseMotionListener;
21
22import javax.sound.sampled.LineUnavailableException;
23import javax.swing.Icon;
24import javax.swing.JButton;
25import javax.swing.JPanel;
26import javax.swing.JSlider;
27import javax.swing.JSplitPane;
28import javax.swing.JToggleButton;
29import javax.swing.event.ChangeEvent;
30import javax.swing.event.ChangeListener;
31
32import org.apollo.audio.ApolloPlaybackMixer;
33import org.apollo.audio.ApolloSubjectChangedEvent;
34import org.apollo.audio.SampledTrackModel;
35import org.apollo.audio.TrackSequence;
36import org.apollo.audio.structure.AudioStructureModel;
37import org.apollo.audio.util.SoundDesk;
38import org.apollo.audio.util.TrackMixSubject;
39import org.apollo.io.IconRepository;
40import org.apollo.items.EmulatedTextItem;
41import org.apollo.items.EmulatedTextItem.TextChangeListener;
42import org.apollo.mvc.Observer;
43import org.apollo.mvc.Subject;
44import org.apollo.mvc.SubjectChangedEvent;
45import org.apollo.util.AudioMath;
46import org.apollo.widgets.TrackWidgetCommons;
47import org.expeditee.gui.Browser;
48import org.expeditee.gui.FrameGraphics;
49import org.expeditee.gui.Popup;
50import org.expeditee.gui.PopupManager;
51
52public class ExpandedTrackPopup extends Popup implements ActionListener, Observer {
53
54 private static final long serialVersionUID = 1L;
55
56 /** The observed subject. Can never be null */
57 private SampledTrackModel trackModel; // immutable
58
59 private String trackSourceFrameName; // immutable
60
61 private TrackMixSubject trackMix; // immutable
62
63 private JButton playPauseButton;
64 private JButton stopButton;
65 private JButton rewindButton;
66 private JButton closeButton;
67 private JToggleButton soloButton;
68 private JToggleButton muteButton;
69 private JSlider volumeSlider;
70 JPanel nameLabelParent;
71
72 private EmulatedTextItem nameLabel;
73
74 private JSplitPane splitPane;
75 private SampledTrackGraphViewPort zoomController;
76 private EditableSampledTrackGraphView zoomedTrackView;
77 private TimeAxisPanel timeAxis;
78
79 private boolean isUpdatingGUI = false;
80
81 /**
82 * Hidden constuctor: only ExpandedTrackManager can create these.
83 *
84 * @see {@link ExpandedTrackManager}
85 *
86 * @param trackModel
87 *
88 * @param trackMix
89 *
90 * @param trackSourceFrameName
91 * Where the expanded tracks track source was expanded from.
92 * Must not be null
93 *
94 * @param frameStart
95 * the initial zoom
96 *
97 * @param frameLength
98 * the initial zoom
99 *
100 * @throws NullPointerException
101 * If trackModel or trackMix is null.
102 */
103 private ExpandedTrackPopup(
104 SampledTrackModel trackModel,
105 TrackMixSubject trackMix,
106 String trackSourceFrameName,
107 int frameStart,
108 int frameLength) {
109 super(new BorderLayout());
110 super.setConsumeBackClick(true);
111
112 if (trackModel == null) throw new NullPointerException("trackModel");
113 if (trackMix == null) throw new NullPointerException("trackMix");
114 if (trackSourceFrameName == null) throw new NullPointerException("trackSourceFrameName");
115
116 this.trackModel = trackModel;
117 this.trackMix = trackMix;
118
119 final int BUTTON_SIZE = 40;
120
121 playPauseButton = new JButton();
122 playPauseButton.addActionListener(this);
123 playPauseButton.setIcon(IconRepository.getIcon("play.png"));
124 playPauseButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
125 playPauseButton.setToolTipText("Play selection / Pause");
126
127 stopButton = new JButton();
128 stopButton.setEnabled(false);
129 stopButton.addActionListener(this);
130 stopButton.setIcon(IconRepository.getIcon("stop.png"));
131 stopButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
132 stopButton.setToolTipText("Stop playback");
133
134 rewindButton = new JButton();
135 rewindButton.addActionListener(this);
136 rewindButton.setIcon(IconRepository.getIcon("rewind.png"));
137 rewindButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
138 rewindButton.setToolTipText("Rewind to start");
139
140 // Icon changes
141 muteButton = new JToggleButton();
142 muteButton.setSelectedIcon(IconRepository.getIcon("volmute.png"));
143 muteButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
144 muteButton.setToolTipText("Toggle mute");
145 muteButton.addChangeListener(new ChangeListener() {
146 public void stateChanged(ChangeEvent e) {
147 if (!ExpandedTrackPopup.this.isUpdatingGUI) {
148 ExpandedTrackPopup.this.trackMix.setMuted(muteButton.isSelected());
149
150 }
151 }
152 });
153
154 soloButton = new JToggleButton();
155 soloButton.setIcon(IconRepository.getIcon("solo.png"));
156 soloButton.setSelectedIcon(IconRepository.getIcon("soloon.png"));
157 soloButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
158 soloButton.setToolTipText("Toggle solo");
159 soloButton.addChangeListener(new ChangeListener() {
160 public void stateChanged(ChangeEvent e) {
161 if (!ExpandedTrackPopup.this.isUpdatingGUI) {
162 SoundDesk.getInstance().setSoloIDPrefix(soloButton.isSelected() ?
163 ExpandedTrackPopup.this.trackMix.getChannelID() : null
164 );
165
166 }
167 }
168 });
169
170 closeButton = new JButton();
171 closeButton.addActionListener(this);
172 closeButton.setIcon(IconRepository.getIcon("close.png"));
173 closeButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
174 closeButton.setToolTipText("Close");
175
176 final int VOLUME_SPACING = 6;
177 volumeSlider = new JSlider(JSlider.HORIZONTAL);
178 volumeSlider.setMinimum(0);
179 volumeSlider.setMaximum(100);
180 volumeSlider.addChangeListener(new ChangeListener() {
181 public void stateChanged(ChangeEvent e) {
182 if (!ExpandedTrackPopup.this.isUpdatingGUI) {
183 ExpandedTrackPopup.this.trackMix.setVolume(((float)volumeSlider.getValue()) / 100.0f);
184 }
185 // Update the icons
186 updateButtonGUI();
187 }
188 });
189 volumeSlider.setPreferredSize(new Dimension(100 - (2 * VOLUME_SPACING), BUTTON_SIZE));
190
191 zoomedTrackView = new EditableSampledTrackGraphView();
192 zoomedTrackView.setSelectAllOnDoubleClick(true);
193
194 zoomController = new SampledTrackGraphViewPort();
195
196 // Keep timescale in zoomedTrackView consistance with zoom controller
197 zoomController.addZoomChangeListener(new ZoomChangeListener() {
198
199 public void zoomChanged(Event e) {
200
201 int minFrame = Math.min(
202 zoomController.getZoomStartFrame(), zoomController.getZoomEndFrame());
203
204 int maxFrame = Math.max(
205 zoomController.getZoomStartFrame(), zoomController.getZoomEndFrame());
206
207
208 zoomedTrackView.setTimeScale(minFrame, maxFrame - minFrame);
209 }
210
211 });
212
213 timeAxis = new TimeAxisPanel(zoomedTrackView);
214 timeAxis.setPreferredSize(new Dimension(100, 40));
215
216 nameLabelParent = new JPanel();
217
218 nameLabelParent.addMouseListener(new MouseListener() {
219
220 public void mouseClicked(MouseEvent e) {
221 if (nameLabel != null) {
222 if (nameLabel.onMouseClicked(e)) {
223 e.consume();
224 return;
225 }
226 }
227 }
228
229 public void mouseEntered(MouseEvent e) {
230 }
231
232 public void mouseExited(MouseEvent e) {
233 }
234
235 public void mousePressed(MouseEvent e) {
236 if (nameLabel != null) {
237 if (nameLabel.onMousePressed(e)) {
238 e.consume();
239 }
240 }
241 }
242
243 public void mouseReleased(MouseEvent e) {
244 if (nameLabel != null) {
245 if (nameLabel.onMouseReleased(e)) {
246 e.consume();
247 }
248 }
249 }
250
251 });
252
253 nameLabelParent.addMouseMotionListener(new MouseMotionListener() {
254
255 public void mouseDragged(MouseEvent e) {
256 if (nameLabel != null) {
257 if (nameLabel.onMouseDragged(e)) {
258 e.consume();
259 }
260 }
261 }
262
263 public void mouseMoved(MouseEvent e) {
264 if (nameLabel != null) {
265 nameLabel.onMouseMoved(e, nameLabelParent);
266 }
267 }
268
269 });
270
271 nameLabelParent.addKeyListener(new KeyListener() {
272
273 public void keyPressed(KeyEvent e) {
274 if (nameLabel != null) {
275 if (nameLabel.onKeyPressed(e, nameLabelParent)) {
276 e.consume();
277 }
278 }
279 }
280
281 public void keyReleased(KeyEvent e) {
282 if (nameLabel != null) {
283 if (nameLabel.onKeyReleased(e, nameLabelParent)) {
284 e.consume();
285 }
286 }
287
288 }
289
290 public void keyTyped(KeyEvent e) {
291 }
292
293 });
294
295 nameLabel = new EmulatedTextItem(nameLabelParent, new Point(10, 25));
296 nameLabel.setFontStyle(Font.BOLD);
297 nameLabel.setFontSize(16);
298 nameLabel.setBackgroundColor(Color.WHITE);
299 nameLabel.setText(trackModel.getName());
300
301 nameLabel.addTextChangeListener(new TextChangeListener() { // a little bit loopy!
302
303 public void onTextChanged(Object source, String newLabel) {
304 if (ExpandedTrackPopup.this.trackModel != null && !nameLabel.getText().equals(ExpandedTrackPopup.this.trackModel.getName())) {
305 ExpandedTrackPopup.this.trackModel.setName(nameLabel.getText());
306 }
307 }
308
309 });
310
311 JPanel workArea = new JPanel(new BorderLayout());
312
313 workArea.add(zoomedTrackView, BorderLayout.CENTER);
314 workArea.add(timeAxis, BorderLayout.SOUTH);
315
316 splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
317 splitPane.setTopComponent(workArea);
318 splitPane.setBottomComponent(zoomController);
319 splitPane.setOneTouchExpandable(true);
320 splitPane.setResizeWeight(1.0);
321
322 // Create the toolbar
323 JPanel toolBarPanel = new JPanel(new GridBagLayout());
324
325 GridBagConstraints c = new GridBagConstraints();
326 c.gridx = 0;
327 c.gridy = 0;
328 c.fill = GridBagConstraints.BOTH;
329 toolBarPanel.add(playPauseButton, c);
330
331 c = new GridBagConstraints();
332 c.gridx = 1;
333 c.gridy = 0;
334 c.fill = GridBagConstraints.BOTH;
335 toolBarPanel.add(stopButton, c);
336
337 c = new GridBagConstraints();
338 c.gridx = 2;
339 c.gridy = 0;
340 c.fill = GridBagConstraints.BOTH;
341 toolBarPanel.add(rewindButton, c);
342
343 c = new GridBagConstraints();
344 c.gridx = 3;
345 c.gridy = 0;
346 c.fill = GridBagConstraints.BOTH;
347 toolBarPanel.add(soloButton, c);
348
349 c = new GridBagConstraints();
350 c.gridx = 4;
351 c.gridy = 0;
352 c.fill = GridBagConstraints.BOTH;
353 toolBarPanel.add(muteButton, c);
354
355 c = new GridBagConstraints();
356 c.gridx = 5;
357 c.gridy = 0;
358 c.fill = GridBagConstraints.BOTH;
359 c.insets = new Insets(0,VOLUME_SPACING,0,VOLUME_SPACING);
360 toolBarPanel.add(volumeSlider, c);
361
362 c = new GridBagConstraints();
363 c.gridx = 6;
364 c.gridy = 0;
365 c.fill = GridBagConstraints.BOTH;
366 c.weightx = 1.0f;
367 toolBarPanel.add(nameLabelParent, c);
368
369 c = new GridBagConstraints();
370 c.gridx = 7;
371 c.gridy = 0;
372 c.fill = GridBagConstraints.BOTH;
373 toolBarPanel.add(closeButton, c);
374
375 this.add(toolBarPanel, BorderLayout.NORTH);
376 this.add(splitPane, BorderLayout.CENTER);
377
378 // Observe track model
379 trackModel.addObserver(zoomedTrackView);
380 trackModel.addObserver(zoomController);
381 trackModel.addObserver(this);
382
383 // Setup mix to use
384 zoomedTrackView.setMix(trackMix);
385
386 // Setup the initial zoom
387 zoomController.setZoom(frameStart, frameStart + frameLength);
388
389 updateBorderColor();
390 }
391
392 /**
393 * Giver/receiver design pattern for only allowing the ExpandedTrackManager singleton
394 * to create expanded views.
395 *
396 * @param trackModel
397 * The track model to observe.
398 *
399 * @param trackMix
400 * The mix to use.
401 *
402 * @param trackSourceFrameName
403 * Where the expanded tracks track source was expanded from.
404 * Must not be null
405 *
406 * @param frameStart
407 * the initial zoom - clamped
408 *
409 * @param frameLength
410 * the initial zoom - clamped
411 *
412 * @throws NullPointerException
413 * If trackModel or trackMix or trackSourceFrameName or localFilename is null.
414 *
415 */
416 static void giveToExpandedTrackManager(
417 SampledTrackModel trackModel,
418 TrackMixSubject trackMix,
419 String trackSourceFrameName,
420 int frameStart,
421 int frameLength) {
422
423 ExpandedTrackPopup xtp = new ExpandedTrackPopup(
424 trackModel,
425 trackMix,
426 trackSourceFrameName,
427 frameStart,
428 frameLength);
429
430 ExpandedTrackManager.getInstance().receiveExpandedTrackPopup(xtp);
431 }
432
433 @Override
434 public void onShowing() {
435
436 }
437
438 @Override
439 public void onShow() {
440
441 if (splitPane.getHeight() < 140) {
442 splitPane.setDividerLocation(splitPane.getHeight() - 30);
443 } else {
444 splitPane.setDividerLocation(splitPane.getHeight() - 60);
445 }
446
447 if (zoomedTrackView.getMix() != null) {
448 updateVolume((int)(100 * zoomedTrackView.getMix().getVolume()));
449 updateMute(zoomedTrackView.getMix().isMuted());
450 updateSolo(SoundDesk.getInstance().isSolo(zoomedTrackView.getMix().getChannelID()));
451 }
452
453 SoundDesk.getInstance().addObserver(this);
454 trackMix.addObserver(this);
455
456 // Invalidate full frame for shading
457 if (Browser._theBrowser != null) {
458 FrameGraphics.refresh(false);
459 }
460 }
461
462 @Override
463 public void onHide() {
464 ExpandedTrackManager.getInstance().expandedTrackPopupHidden(this);
465 releaseMemory(); // get rid of buffer etc..
466
467 SoundDesk.getInstance().removeObserver(this);
468 trackMix.removeObserver(this);
469
470 // Invalidate full frame for shading
471 if (Browser._theBrowser != null) {
472 FrameGraphics.refresh(false);
473 }
474 }
475
476
477
478
479 @Override
480 public void paint(Graphics g) {
481 super.paint(g);
482
483 g.translate(-getX(), -getY());
484 nameLabel.paint(g);
485 g.translate(getX(), getY());
486
487 }
488
489 public void actionPerformed(ActionEvent e) {
490 if (trackModel == null) return;
491
492 if (trackMix == null) return;
493
494 if (e.getSource() == playPauseButton) {
495
496 try {
497
498 if (!SoundDesk.getInstance().isPlaying(trackMix.getChannelID())) { // play / resume
499
500 int startFrame = -1, endFrame = -1;
501
502 // Resume playback?
503 if (SoundDesk.getInstance().isPaused(trackMix.getChannelID())) {
504 startFrame = SoundDesk.getInstance().getLastPlayedFramePosition(trackMix.getChannelID());
505 if (startFrame >= 0 && startFrame < trackModel.getFrameCount()) {
506
507 // The user may have edited the audio track and reselected it
508 // since the last pause. Thus select an appropriate end frame
509 endFrame = (trackModel.getSelectionLength() > 1) ?
510 trackModel.getSelectionStart() + trackModel.getSelectionLength():
511 trackModel.getFrameCount() - 1;
512
513 // Changed selection? it play range invalid?
514 if (endFrame <= startFrame || startFrame < trackModel.getSelectionStart()) {
515 startFrame = -1; // Play new selection (see below)
516
517 } else if (endFrame >= trackModel.getFrameCount()) {
518 endFrame = trackModel.getFrameCount() - 1;
519 }
520
521 }
522 }
523
524 // Play from beginning of selection to end of selection
525 if (startFrame < 0) {
526 startFrame = trackModel.getSelectionStart();
527 endFrame = (trackModel.getSelectionLength() > 1) ?
528 startFrame + trackModel.getSelectionLength():
529 trackModel.getFrameCount() - 1;
530 }
531
532 // Safety clamp:
533 if (endFrame >= trackModel.getFrameCount()) {
534 endFrame = trackModel.getFrameCount() - 1;
535 }
536
537 if (startFrame < endFrame) {
538 SoundDesk.getInstance().playSampledTrackModel(
539 trackModel,
540 trackMix.getChannelID(),
541 startFrame,
542 endFrame,
543 0);
544 }
545
546 } else { // pause
547
548 TrackSequence ts = SoundDesk.getInstance().getTrackSequence(trackMix.getChannelID());
549
550 if (ts != null &&
551 ts.isPlaying()) {
552
553 // Mark channel as paused.
554 SoundDesk.getInstance().setPaused(trackMix.getChannelID(), true);
555
556 // Stop playback for this channel
557 ApolloPlaybackMixer.getInstance().stop(ts);
558
559 }
560
561 }
562
563 } catch (LineUnavailableException e1) {
564 e1.printStackTrace();
565 }
566
567 } else if (e.getSource() == stopButton) {
568
569 TrackSequence ts = SoundDesk.getInstance().getTrackSequence(trackMix.getChannelID());
570
571 // reset any paused mark
572 SoundDesk.getInstance().setPaused(trackMix.getChannelID(), false);
573
574 if (ts != null &&
575 ts.isPlaying()) {
576 // Stop playback
577 ApolloPlaybackMixer.getInstance().stop(ts);
578 }
579
580 } else if (e.getSource() == rewindButton) {
581
582 trackModel.setSelection(0, 0);
583 SoundDesk.getInstance().setPaused(trackMix.getChannelID(), false);
584
585 } else if (e.getSource() == closeButton) {
586
587 // If there are more expanded tracks showing then the ExpandedTrackManager
588 // will automatically re-layout the remaing views.
589 PopupManager.getInstance().hidePopup(this,
590 PopupManager.getInstance().new ExpandShrinkAnimator(
591 new Rectangle(0, getY(), 1, getHeight()),
592 Color.LIGHT_GRAY));
593
594 }
595
596 }
597
598 /**
599 * Gets rid of image buffers and threads... Frees this instance from
600 * being referenced from the track model - very very important.
601 */
602 void releaseMemory() {
603
604
605 trackModel.removeObserver(zoomedTrackView);
606 trackModel.removeObserver(zoomController);
607 trackModel.removeObserver(this);
608
609 assert (zoomedTrackView.getObservedSubject() == null);
610 assert (zoomController.getObservedSubject() == null);
611
612 zoomedTrackView.releaseBuffer();
613 zoomController.releaseBuffer();
614
615 SoundDesk.getInstance().removeObserver(this);
616 trackMix.removeObserver(this);
617
618 }
619
620 /**
621 * @return The observed track model. Never null
622 */
623 public Subject getObservedSubject() {
624 return trackModel;
625 }
626
627 /**
628 * @return The observed track model.
629 */
630 SampledTrackModel getObservedTrackModel() {
631 return trackModel;
632 }
633
634
635 public void setObservedSubject(Subject parent) {
636 }
637
638 public void modelChanged(Subject source, SubjectChangedEvent event) {
639
640
641 // Synch GUI with track state
642 switch (event.getID()) {
643
644 case ApolloSubjectChangedEvent.TRACK_SEQUENCE_CREATED: // from sound desk
645
646 if (event.getState().equals(trackMix.getChannelID())) {
647 // The channel being played is the same as this one ...
648 // even if the track model is unloaded must enter into a playing state
649 // if the created track sequence will play
650 TrackSequence ts = SoundDesk.getInstance().getTrackSequence(trackMix.getChannelID());
651 assert(ts != null);
652 assert(!ts.hasFinished());
653 assert(!ts.isPlaying());
654 ts.addObserver(this);
655 }
656
657 break;
658
659 case ApolloSubjectChangedEvent.PLAYBACK_STARTED: // From observed track sequence
660 stopButton.setEnabled(true);
661 rewindButton.setEnabled(false);
662 playPauseButton.setIcon(IconRepository.getIcon("pause.png"));
663
664 setBorderThickness(TrackWidgetCommons.PLAYING_TRACK_EDGE_THICKNESS);
665
666 break;
667
668 case ApolloSubjectChangedEvent.PLAYBACK_STOPPED: // From observed track sequence
669
670 rewindButton.setEnabled(true);
671 stopButton.setEnabled(false);
672 playPauseButton.setIcon(IconRepository.getIcon("play.png"));
673
674 // Note:
675 // No need to remove self from observing the dead track since the track references this
676 // and will get garbage collected
677
678 setBorderThickness(TrackWidgetCommons.STOPPED_TRACK_EDGE_THICKNESS);
679
680
681 break;
682
683 case ApolloSubjectChangedEvent.PAUSE_MARK_CHANGED: // When stopped or paused
684 /*
685 if (ae.getState().equals(trackMix.getChannelID())) {
686
687 if (MixDesk.getInstance().isPaused(trackMix.getChannelID())) {
688 // Do nothing .. the paused mark is set prior to a stop
689 } else {
690 // Esnure that the GUI represents a stopped state
691 stopButton.setEnabled(false);
692 playPauseButton.setIcon(IconRepository.getIcon("play.png"));
693 }
694
695 }*/
696
697 break;
698
699 case ApolloSubjectChangedEvent.VOLUME: // From obseved track mix
700 updateVolume((int)(100 * trackMix.getVolume()));
701 break;
702
703 case ApolloSubjectChangedEvent.MUTE: // From obseved track mix
704 updateMute(trackMix.isMuted());
705 updateBorderColor();
706 break;
707
708 case ApolloSubjectChangedEvent.SOLO_PREFIX_CHANGED: // From mix desk
709 updateSolo(SoundDesk.getInstance().isSolo(trackMix.getChannelID()));
710 updateBorderColor();
711 break;
712
713 case ApolloSubjectChangedEvent.NAME_CHANGED:
714 if (!nameLabel.getText().equals(trackModel.getName())) {
715 nameLabel.setText(trackModel.getName());
716 }
717
718 // Keep graph model consistant
719 AudioStructureModel.getInstance().onTrackWidgetNameChanged(
720 trackModel.getLocalFilename(), // may not be in model ... but does not matter in such a case
721 null,
722 trackModel.getName());
723
724 break;
725
726 case ApolloSubjectChangedEvent.AUDIO_INSERTED: // from track model
727 case ApolloSubjectChangedEvent.AUDIO_REMOVED:
728
729 long newRunningTime = AudioMath.framesToMilliseconds(
730 trackModel.getFrameCount(), trackModel.getFormat());
731 assert(newRunningTime > 0);
732
733 if (trackModel != null) {
734
735 // Keep TrackGraphModel consistant
736 AudioStructureModel.getInstance().onTrackWidgetAudioEdited(
737 trackModel.getLocalFilename(),
738 null,
739 newRunningTime);
740 }
741
742 break;
743 }
744
745 }
746
747
748
749 /**
750 * Updates the volume GUI.
751 * {@link #volumeChanged()} is not raised as a result of this call.
752 *
753 * @param vol
754 * The volume ranging from 0 - 100. Clamped.
755 */
756 protected void updateVolume(int vol) {
757
758 if (volumeSlider.getValue() == vol) return;
759
760 // Clamp
761 if(vol < 0) vol = 0;
762 else if (vol > 100) vol = 100;
763
764 isUpdatingGUI = true;
765
766 volumeSlider.setValue(vol);
767
768 isUpdatingGUI = false;
769 }
770
771
772 /**
773 * Updates the mute button GUI.
774 * {@link #muteChanged()} is not raised as a result of this call.
775 *
776 * @param isMuted
777 * True if set gui to muted.
778 */
779 protected void updateMute(boolean isMuted) {
780
781 if (muteButton.isSelected() == isMuted) return;
782
783 isUpdatingGUI = true;
784
785 muteButton.setSelected(isMuted);
786
787 isUpdatingGUI = false;
788 }
789
790
791 /**
792 * Updates the solo button GUI.
793 * {@link #muteChanged()} is not raised as a result of this call.
794 *
795 * @param isSolo
796 * True if set gui to solo on.
797 */
798 protected void updateSolo(boolean isSolo) {
799
800 if (soloButton.isSelected() == isSolo) return;
801
802 isUpdatingGUI = true;
803
804 soloButton.setSelected(isSolo);
805
806 isUpdatingGUI = false;
807 }
808
809 private void updateBorderColor() {
810
811 // Get border color currently used
812 Color oldC = getBorderColor();
813
814 Color newC = TrackWidgetCommons.getBorderColor(
815 SoundDesk.getInstance().isSolo(trackMix.getChannelID()),
816 trackMix.isMuted());
817
818 // Update the color
819 if (!newC.equals(oldC)) {
820 setBorderColor(newC);
821 }
822 }
823
824 /**
825 * Sets the mute icon to represent the current volume value in the slider.
826 * Note: this is not the icon if mute is on.
827 */
828 private void updateButtonGUI() {
829
830 Icon newIcon = null;
831 if (volumeSlider.getValue() <= 25)
832 newIcon = IconRepository.getIcon("vol25.png");
833 else if (volumeSlider.getValue() <= 50)
834 newIcon = IconRepository.getIcon("vol50.png");
835 else if (volumeSlider.getValue() <= 75)
836 newIcon = IconRepository.getIcon("vol75.png");
837 else // maxing
838 newIcon = IconRepository.getIcon("vol100.png");
839
840 muteButton.setIcon(newIcon);
841 }
842
843 /**
844 * @return
845 * The frame at where this expanded view came from.
846 * Never null.
847 */
848 public String getTrackSourceFrameName() {
849 return trackSourceFrameName;
850 }
851
852
853}
Note: See TracBrowser for help on using the repository browser.