Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added the ability to add custom sounds, refactoring #138

Merged
merged 1 commit into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 109 additions & 11 deletions src/main/java/com/codedead/opal/controller/MainWindowController.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.media.MediaPlayer;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
Expand All @@ -38,6 +40,10 @@

public final class MainWindowController implements IAudioTimer, TrayIconListener {

@FXML
private GridPane grpCustom;
@FXML
private TitledPane pneCustom;
@FXML
private TitledPane pneOther;
@FXML
Expand Down Expand Up @@ -269,8 +275,8 @@ private List<SoundPane> getSoundPanes(final GridPane parent) {
private void openFile(final String path) {
if (path == null)
throw new NullPointerException("Path cannot be null!");
if (path.isEmpty())
throw new IllegalArgumentException("Path cannot be empty!");
if (path.isBlank())
throw new IllegalArgumentException("Path cannot be blank!");

try {
helpUtils.openFile(new RunnableFileOpener(path, new IRunnableHelper() {
Expand Down Expand Up @@ -319,6 +325,19 @@ private void initialize() {
e.setVisible(true);
e.setManaged(true);
});

final List<SoundPane> customSoundPanes = getSoundPanes(grpCustom);
if (!customSoundPanes.isEmpty()) {
pneCustom.setExpanded(true);
pneCustom.setVisible(true);
pneCustom.setManaged(true);

customSoundPanes.forEach(e -> {
e.setVisible(true);
e.setManaged(true);
});
}

btnClearSearch.setVisible(false);
btnClearSearch.setManaged(false);

Expand All @@ -344,15 +363,36 @@ private void initialize() {
});
return;
}

Platform.runLater(() -> {
getAllSoundPanes()
.forEach(e -> {
e.setVisible(e.getName().toLowerCase().contains(newValue.trim().toLowerCase()));
e.setManaged(e.isVisible());
});

getSoundPanes(grpCustom)
.forEach(e -> {
e.setVisible(e.getName().toLowerCase().contains(newValue.trim().toLowerCase()));
e.setManaged(e.isVisible());
});

// Check if there are still active sound panes on pneCustom
final List<SoundPane> customSoundPanes = getSoundPanes(grpCustom);
if (!customSoundPanes.isEmpty()) {
customSoundPanes.stream().filter(Node::isVisible).findFirst().ifPresentOrElse(_ -> {
pneCustom.setExpanded(true);
pneCustom.setVisible(true);
pneCustom.setManaged(true);
}, () -> {
pneCustom.setExpanded(false);
pneCustom.setVisible(false);
pneCustom.setManaged(false);
});
}

// Check if there are still active sound panes on pneNature
getSoundPanes(grpNature).stream().filter(Node::isVisible).findFirst().ifPresentOrElse(e -> {
getSoundPanes(grpNature).stream().filter(Node::isVisible).findFirst().ifPresentOrElse(_ -> {
pneNature.setExpanded(true);
pneNature.setVisible(true);
pneNature.setManaged(true);
Expand All @@ -363,7 +403,7 @@ private void initialize() {
});

// Check if there are still active sound panes on pneOffice
getSoundPanes(grpOffice).stream().filter(Node::isVisible).findFirst().ifPresentOrElse(e -> {
getSoundPanes(grpOffice).stream().filter(Node::isVisible).findFirst().ifPresentOrElse(_ -> {
pneOffice.setExpanded(true);
pneOffice.setVisible(true);
pneOffice.setManaged(true);
Expand All @@ -374,7 +414,7 @@ private void initialize() {
});

// Check if there are still active sound panes on pneAudiences
getSoundPanes(grpAudiences).stream().filter(Node::isVisible).findFirst().ifPresentOrElse(e -> {
getSoundPanes(grpAudiences).stream().filter(Node::isVisible).findFirst().ifPresentOrElse(_ -> {
pneAudiences.setExpanded(true);
pneAudiences.setVisible(true);
pneAudiences.setManaged(true);
Expand All @@ -385,7 +425,7 @@ private void initialize() {
});

// Check if there are still active sound panes on pneRadioFrequencyStatic
getSoundPanes(grpRadioFrequencyStatic).stream().filter(Node::isVisible).findFirst().ifPresentOrElse(e -> {
getSoundPanes(grpRadioFrequencyStatic).stream().filter(Node::isVisible).findFirst().ifPresentOrElse(_ -> {
pneRadioFrequencyStatic.setExpanded(true);
pneRadioFrequencyStatic.setVisible(true);
pneRadioFrequencyStatic.setManaged(true);
Expand All @@ -396,7 +436,7 @@ private void initialize() {
});

// Check if there are still active sound panes on pneOther
getSoundPanes(grpOther).stream().filter(Node::isVisible).findFirst().ifPresentOrElse(e -> {
getSoundPanes(grpOther).stream().filter(Node::isVisible).findFirst().ifPresentOrElse(_ -> {
pneOther.setExpanded(true);
pneOther.setVisible(true);
pneOther.setManaged(true);
Expand Down Expand Up @@ -442,6 +482,52 @@ private void openSoundPresetAction() {
}
}

/**
* Open a custom sound
*/
@FXML
private void addCustomSound() {
logger.info("Opening a custom sound");
final FileChooser chooser = new FileChooser();

final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("MP3 (*.mp3)", "*.mp3");
chooser.getExtensionFilters().add(extFilter);

final File file = chooser.showOpenDialog(new Stage());

if (file != null && file.exists()) {
if (file.getAbsolutePath().isBlank())
throw new IllegalArgumentException("Path cannot be blank!");

logger.info("Loading custom sound from {}", file.getAbsolutePath());

try {
final RowConstraints row = new RowConstraints();
row.setVgrow(Priority.ALWAYS);

grpCustom.getRowConstraints().add(row);

final SoundPane customSoundPane = new SoundPane();
final int count = getSoundPanes(grpCustom).size() + 1;

customSoundPane.setName(translationBundle.getString("CustomSound") + " #" + count);
customSoundPane.setMediaKey("custom" + count);
customSoundPane.setMediaPath(file.toURI().toURL().toString());
customSoundPane.setImage("/images/customsound.png");
customSoundPane.setResourceFile(false);

grpCustom.add(customSoundPane, 0, count - 1);

pneCustom.setExpanded(true);
pneCustom.setVisible(true);
pneCustom.setManaged(true);
} catch (final IOException ex) {
logger.error("Unable to open the custom sound from {}", file.getAbsolutePath(), ex);
FxUtils.showErrorAlert(translationBundle.getString("OpenCustomSoundError"), ex.toString(), getClass().getResourceAsStream(SharedVariables.ICON_URL));
}
}
}

/**
* Open a sound preset
*
Expand All @@ -450,17 +536,17 @@ private void openSoundPresetAction() {
private void openSoundPreset(final String path) {
if (path == null)
throw new NullPointerException("Path cannot be null!");
if (path.isEmpty())
throw new IllegalArgumentException("Path cannot be empty!");
if (path.isBlank())
throw new IllegalArgumentException("Path cannot be blank!");

logger.info("Loading sound preset from {}", path);

try {
final Path filePath = Path.of(path);
final String actual = Files.readString(filePath);

if (actual.isEmpty())
throw new IllegalArgumentException("Sound preset cannot be empty!");
if (actual.isBlank())
throw new IllegalArgumentException("Sound preset cannot be blank!");

final TypeReference<HashMap<String, Double>> typeRef = new TypeReference<>() {
};
Expand Down Expand Up @@ -518,6 +604,10 @@ private void playPauseAction() {
for (final SoundPane soundPane : getAllSoundPanes()) {
soundPane.playPause();
}

for (final SoundPane soundPane : getSoundPanes(grpCustom)) {
soundPane.playPause();
}
} catch (final MediaPlayerException ex) {
logger.error("Unable to play / pause MediaPlayer", ex);
FxUtils.showErrorAlert(translationBundle.getString("PlayPauseError"), ex.toString(), getClass().getResourceAsStream(SharedVariables.ICON_URL));
Expand All @@ -531,6 +621,13 @@ private void playPauseAction() {
private void resetAction() {
logger.info("Resetting all audio sliders");
getAllSoundPanes().forEach(e -> e.getSlider().setValue(0));

getSoundPanes(grpCustom).forEach(SoundPane::disposeMediaPlayer);
grpCustom.getChildren().clear();

pneCustom.setExpanded(false);
pneCustom.setVisible(false);
pneCustom.setManaged(false);
}

/**
Expand Down Expand Up @@ -684,6 +781,7 @@ private void clearSearchAction() {
public void fired() {
cancelTimer();
getAllSoundPanes().forEach(SoundPane::pause);
getSoundPanes(grpCustom).forEach(SoundPane::pause);

if (Boolean.parseBoolean(settingsController.getProperties().getProperty("timerComputerShutdown", "false"))) {
final String command = switch (platformName.toLowerCase()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ public String getPropertiesResourceLocation() {
* @param propertiesResourceLocation The resource location of the default properties file
*/
public void setPropertiesResourceLocation(final String propertiesResourceLocation) {
if (propertiesResourceLocation == null || propertiesResourceLocation.isEmpty())
throw new IllegalArgumentException("Properties resource location cannot be null!");
if (propertiesResourceLocation == null)
throw new NullPointerException("Properties resource location cannot be null!");
if (propertiesResourceLocation.isBlank())
throw new IllegalArgumentException("Properties resource location cannot be blank!");

this.propertiesResourceLocation = propertiesResourceLocation;
}
Expand All @@ -107,8 +109,10 @@ public String getPropertiesFileLocation() {
* @param propertiesFileLocation The properties file location
*/
public void setPropertiesFileLocation(final String propertiesFileLocation) {
if (propertiesFileLocation == null || propertiesFileLocation.isEmpty())
throw new IllegalArgumentException("Properties file location cannot be null or empty!");
if (propertiesFileLocation == null)
throw new NullPointerException("Properties file location cannot be null!");
if (propertiesFileLocation.isBlank())
throw new IllegalArgumentException("Properties file location cannot be blank!");

this.propertiesFileLocation = propertiesFileLocation;
}
Expand Down
20 changes: 10 additions & 10 deletions src/main/java/com/codedead/opal/controller/UpdateController.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ public UpdateController(final String updateUrl, final String currentVersion) {
public Optional<PlatformUpdate> checkForUpdates(final String currentPlatform, final boolean isPortable) throws InterruptedException, InvalidHttpResponseCodeException, IOException {
if (currentPlatform == null)
throw new NullPointerException("Current platform cannot be null!");
if (currentPlatform.isEmpty())
throw new IllegalArgumentException("Current platform cannot be empty!");
if (currentPlatform.isBlank())
throw new IllegalArgumentException("Current platform cannot be blank!");

logger.info("Attempting to retrieve the latest PlatformUpdate objects");

Expand Down Expand Up @@ -151,12 +151,12 @@ public List<PlatformUpdate> getUpdates() throws IOException, InterruptedExceptio
public void downloadFile(final String url, final String path) throws IOException, URISyntaxException {
if (url == null)
throw new NullPointerException("URL cannot be null!");
if (url.isEmpty())
throw new IllegalArgumentException("URL cannot be empty!");
if (url.isBlank())
throw new IllegalArgumentException("URL cannot be blank!");
if (path == null)
throw new NullPointerException("Path cannot be null!");
if (path.isEmpty())
throw new IllegalArgumentException("Path cannot be empty!");
if (path.isBlank())
throw new IllegalArgumentException("Path cannot be blank!");

logger.info("Attempting to download file from {} and store it at {}", url, path);

Expand Down Expand Up @@ -187,8 +187,8 @@ public String getUpdateUrl() {
public void setUpdateUrl(final String updateUrl) {
if (updateUrl == null)
throw new NullPointerException("Update URL cannot be null!");
if (updateUrl.isEmpty())
throw new IllegalArgumentException("Update URL cannot be empty!");
if (updateUrl.isBlank())
throw new IllegalArgumentException("Update URL cannot be blank!");

this.updateUrl = updateUrl;
}
Expand All @@ -201,8 +201,8 @@ public void setUpdateUrl(final String updateUrl) {
public void setCurrentVersion(final String currentVersion) {
if (currentVersion == null)
throw new NullPointerException("currentVersion cannot be null!");
if (currentVersion.isEmpty())
throw new IllegalArgumentException("currentVersion cannot be empty!");
if (currentVersion.isBlank())
throw new IllegalArgumentException("currentVersion cannot be blank!");

this.currentVersion = currentVersion;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/codedead/opal/domain/NumberTextField.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ public NumberTextField() {
this.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.UP) {
int currentValue = 0;
if (!this.getText().isEmpty()) {
if (!this.getText().isBlank()) {
currentValue = Integer.parseInt(this.getText());
}
currentValue++;
this.setText(Integer.toString(currentValue));
} else if (e.getCode() == KeyCode.DOWN) {
int currentValue = 0;
if (!this.getText().isEmpty()) {
if (!this.getText().isBlank()) {
currentValue = Integer.parseInt(this.getText());
}
if (currentValue - 1 >= getMin()) {
Expand Down
Loading
Loading