-
Notifications
You must be signed in to change notification settings - Fork 269
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#1723 work in progress - adds playback controls and playback of selec…
…ted call.
- Loading branch information
Dennis Sheirer
committed
Dec 23, 2023
1 parent
0cf77ba
commit db58dbd
Showing
4 changed files
with
374 additions
and
22 deletions.
There are no files selected for viewing
279 changes: 279 additions & 0 deletions
279
src/main/java/io/github/dsheirer/audio/call/AudioPlaybackControlView.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,279 @@ | ||
/* | ||
* ***************************************************************************** | ||
* Copyright (C) 2014-2023 Dennis Sheirer | ||
* | ||
* 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, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* 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, see <http://www.gnu.org/licenses/> | ||
* **************************************************************************** | ||
*/ | ||
|
||
package io.github.dsheirer.audio.call; | ||
|
||
import javafx.beans.property.ObjectProperty; | ||
import javafx.beans.property.SimpleObjectProperty; | ||
import javafx.scene.control.Button; | ||
import javafx.scene.control.Toggle; | ||
import javafx.scene.control.ToggleButton; | ||
import javafx.scene.control.ToggleGroup; | ||
import javafx.scene.control.Tooltip; | ||
import javafx.scene.layout.HBox; | ||
import javafx.scene.media.MediaPlayer; | ||
import javafx.scene.paint.Color; | ||
import jiconfont.icons.font_awesome.FontAwesome; | ||
import jiconfont.javafx.IconNode; | ||
|
||
/** | ||
* Audio playback controller. | ||
*/ | ||
public class AudioPlaybackControlView extends HBox | ||
{ | ||
private static final int ICON_SIZE = 16; | ||
private ObjectProperty<MediaPlayer> mMediaPlayer = new SimpleObjectProperty<>(); | ||
private Button mForwardButton; | ||
private Button mBackwardButton; | ||
private Button mRestartButton; | ||
private ToggleButton mAutoRepeatButton; | ||
private ToggleGroup mPlaybackGroup; | ||
private ToggleButton mPlayButton; | ||
private ToggleButton mPauseButton; | ||
private ToggleButton mStopButton; | ||
|
||
/** | ||
* Constructs an instance | ||
*/ | ||
public AudioPlaybackControlView() | ||
{ | ||
setSpacing(2); | ||
getChildren().addAll(getStopButton(), getPlayButton(), getPauseButton(), getRestartButton(), | ||
getBackwardButton(), getForwardButton(), getAutoRepeatButton()); | ||
mediaPlayerProperty().addListener((o, oldV, newV) -> updateControls()); | ||
} | ||
|
||
/** | ||
* Update the controls when the media player changes | ||
*/ | ||
private void updateControls() | ||
{ | ||
boolean disable = mediaPlayerProperty().get() == null; | ||
getStopButton().setDisable(disable); | ||
getPlayButton().setDisable(disable); | ||
getPauseButton().setDisable(disable); | ||
getForwardButton().setDisable(disable); | ||
getBackwardButton().setDisable(disable); | ||
getRestartButton().setDisable(disable); | ||
getAutoRepeatButton().setDisable(disable); | ||
} | ||
|
||
/** | ||
* Media player property that can be bound to a media player controller. | ||
*/ | ||
public ObjectProperty<MediaPlayer> mediaPlayerProperty() | ||
{ | ||
return mMediaPlayer; | ||
} | ||
|
||
/** | ||
* Clears the media player for this view. | ||
*/ | ||
public void clearMediaPlayer() | ||
{ | ||
mMediaPlayer.set(null); | ||
} | ||
|
||
private ToggleGroup getPlaybackGroup() | ||
{ | ||
if(mPlaybackGroup == null) | ||
{ | ||
mPlaybackGroup = new ToggleGroup(); | ||
} | ||
|
||
return mPlaybackGroup; | ||
} | ||
|
||
/** | ||
* Play button | ||
*/ | ||
private ToggleButton getPlayButton() | ||
{ | ||
if(mPlayButton == null) | ||
{ | ||
mPlayButton = new ToggleButton(); | ||
mPlayButton.setToggleGroup(getPlaybackGroup()); | ||
mPlayButton.setTooltip(new Tooltip("Play Audio")); | ||
mPlayButton.setDisable(true); | ||
IconNode iconNode = new IconNode(FontAwesome.PLAY); | ||
iconNode.setIconSize(ICON_SIZE); | ||
iconNode.setFill(Color.BLACK); | ||
mPlayButton.setGraphic(iconNode); | ||
mPlayButton.onActionProperty().set(event -> { | ||
MediaPlayer mediaPlayer = mediaPlayerProperty().get(); | ||
if(mediaPlayer != null) | ||
{ | ||
mediaPlayer.play(); | ||
} | ||
}); | ||
} | ||
|
||
return mPlayButton; | ||
} | ||
|
||
/** | ||
* Pause button | ||
*/ | ||
private ToggleButton getPauseButton() | ||
{ | ||
if(mPauseButton == null) | ||
{ | ||
mPauseButton = new ToggleButton(); | ||
mPlayButton.setToggleGroup(getPlaybackGroup()); | ||
mPauseButton.setTooltip(new Tooltip("Pause Audio Playback")); | ||
mPauseButton.setDisable(true); | ||
IconNode iconNode = new IconNode(FontAwesome.PAUSE); | ||
iconNode.setIconSize(ICON_SIZE); | ||
iconNode.setFill(Color.BLACK); | ||
mPauseButton.setGraphic(iconNode); | ||
mPauseButton.onActionProperty().set(event -> { | ||
MediaPlayer mediaPlayer = mediaPlayerProperty().get(); | ||
|
||
if(mediaPlayer != null) | ||
{ | ||
mediaPlayer.pause(); | ||
} | ||
}); | ||
} | ||
|
||
return mPauseButton; | ||
} | ||
|
||
/** | ||
* Stop button | ||
*/ | ||
private ToggleButton getStopButton() | ||
{ | ||
if(mStopButton == null) | ||
{ | ||
mStopButton = new ToggleButton(); | ||
mStopButton.setToggleGroup(getPlaybackGroup()); | ||
mStopButton.setTooltip(new Tooltip("Stop Audio Playback")); | ||
mStopButton.setDisable(true); | ||
IconNode iconNode = new IconNode(FontAwesome.STOP); | ||
iconNode.setIconSize(ICON_SIZE); | ||
iconNode.setFill(Color.BLACK); | ||
mStopButton.setGraphic(iconNode); | ||
mStopButton.onActionProperty().set(event -> { | ||
MediaPlayer mediaPlayer = mediaPlayerProperty().get(); | ||
if(mediaPlayer != null) | ||
{ | ||
mediaPlayer.stop(); | ||
} | ||
}); | ||
} | ||
|
||
return mStopButton; | ||
} | ||
|
||
/** | ||
* Restart audio playback button | ||
*/ | ||
private Button getRestartButton() | ||
{ | ||
if(mRestartButton == null) | ||
{ | ||
mRestartButton = new Button(); | ||
mRestartButton.setTooltip(new Tooltip("Restart Audio Playback")); | ||
mRestartButton.setDisable(true); | ||
IconNode iconNode = new IconNode(FontAwesome.FAST_BACKWARD); | ||
iconNode.setIconSize(ICON_SIZE); | ||
iconNode.setFill(Color.BLACK); | ||
mRestartButton.setGraphic(iconNode); | ||
mRestartButton.onActionProperty().set(event -> { | ||
MediaPlayer mediaPlayer = mediaPlayerProperty().get(); | ||
if(mediaPlayer != null) | ||
{ | ||
Toggle selected = getPlaybackGroup().getSelectedToggle(); | ||
if(getPlayButton().equals(selected)) | ||
{ | ||
mediaPlayer.stop(); | ||
mediaPlayer.play(); | ||
} | ||
else if(getStopButton().equals(selected)) | ||
{ | ||
mediaPlayer.play(); | ||
} | ||
else if(getPauseButton().equals(selected)) | ||
{ | ||
mediaPlayer.stop(); | ||
mediaPlayer.play(); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
return mRestartButton; | ||
} | ||
|
||
/** | ||
* Rewind button | ||
*/ | ||
private Button getBackwardButton() | ||
{ | ||
if(mBackwardButton == null) | ||
{ | ||
mBackwardButton = new Button(); | ||
mBackwardButton.setTooltip(new Tooltip("Rewind Audio Playback 3 Seconds")); | ||
mBackwardButton.setDisable(true); | ||
IconNode iconNode = new IconNode(FontAwesome.BACKWARD); | ||
iconNode.setIconSize(ICON_SIZE); | ||
iconNode.setFill(Color.BLACK); | ||
mBackwardButton.setGraphic(iconNode); | ||
} | ||
|
||
return mBackwardButton; | ||
} | ||
|
||
/** | ||
* Fast Forward button | ||
*/ | ||
private Button getForwardButton() | ||
{ | ||
if(mForwardButton == null) | ||
{ | ||
mForwardButton = new Button(); | ||
mForwardButton.setTooltip(new Tooltip("Fast Forward Audio Playback 3 Seconds")); | ||
mForwardButton.setDisable(true); | ||
IconNode iconNode = new IconNode(FontAwesome.FORWARD); | ||
iconNode.setIconSize(ICON_SIZE); | ||
iconNode.setFill(Color.BLACK); | ||
mForwardButton.setGraphic(iconNode); | ||
} | ||
|
||
return mForwardButton; | ||
} | ||
|
||
private ToggleButton getAutoRepeatButton() | ||
{ | ||
if(mAutoRepeatButton == null) | ||
{ | ||
mAutoRepeatButton = new ToggleButton(); | ||
mAutoRepeatButton.setSelected(true); | ||
mAutoRepeatButton.setTooltip(new Tooltip("Auto-repeat audio playback toggle button.")); | ||
mAutoRepeatButton.setDisable(true); | ||
IconNode iconNode = new IconNode(FontAwesome.REPEAT); | ||
iconNode.setIconSize(ICON_SIZE); | ||
iconNode.setFill(Color.BLACK); | ||
mAutoRepeatButton.setGraphic(iconNode); | ||
} | ||
|
||
return mAutoRepeatButton; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.