Add volume setting to play sound event

This commit is contained in:
0xb00bface 2022-07-03 11:58:52 +02:00
parent a64cd4f4c1
commit a030ba7e83
2 changed files with 64 additions and 45 deletions

View File

@ -1,35 +1,39 @@
package ctbrec.ui.event; package ctbrec.ui.event;
import java.io.File;
import java.net.URL;
import ctbrec.event.Action; import ctbrec.event.Action;
import ctbrec.event.Event; import ctbrec.event.Event;
import ctbrec.event.EventHandlerConfiguration.ActionConfiguration; import ctbrec.event.EventHandlerConfiguration.ActionConfiguration;
import javafx.scene.media.AudioClip; import javafx.scene.media.AudioClip;
import java.io.File;
import java.net.URL;
public class PlaySound extends Action { public class PlaySound extends Action {
private URL url; private URL url;
private double volume = 1.0d;
public PlaySound() { public PlaySound() {
name = "play sound"; name = "play sound";
} }
public PlaySound(URL url) { public PlaySound(URL url, double volume) {
this(); this();
this.url = url; this.url = url;
this.volume = volume;
} }
@Override @Override
public void accept(Event evt) { public void accept(Event evt) {
var clip = new AudioClip(url.toString()); var clip = new AudioClip(url.toString());
clip.setVolume(volume);
clip.play(); clip.play();
} }
@Override @Override
public void configure(ActionConfiguration config) throws Exception { public void configure(ActionConfiguration config) throws Exception {
var file = new File((String) config.getConfiguration().get("file")); var file = new File((String) config.getConfiguration().get("file"));
volume = Double.parseDouble(String.valueOf(config.getConfiguration().getOrDefault("volume", "1.0")));
url = file.toURI().toURL(); url = file.toURI().toURL();
} }
} }

View File

@ -1,38 +1,16 @@
package ctbrec.ui.settings; package ctbrec.ui.settings;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import javafx.scene.control.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.Config; import ctbrec.Config;
import ctbrec.Model; import ctbrec.Model;
import ctbrec.Recording; import ctbrec.Recording;
import ctbrec.StringUtil; import ctbrec.StringUtil;
import ctbrec.event.Event; import ctbrec.event.*;
import ctbrec.event.EventBusHolder;
import ctbrec.event.EventHandler;
import ctbrec.event.EventHandlerConfiguration;
import ctbrec.event.EventHandlerConfiguration.ActionConfiguration; import ctbrec.event.EventHandlerConfiguration.ActionConfiguration;
import ctbrec.event.EventHandlerConfiguration.PredicateConfiguration; import ctbrec.event.EventHandlerConfiguration.PredicateConfiguration;
import ctbrec.event.ExecuteProgram;
import ctbrec.event.MatchAllPredicate;
import ctbrec.event.ModelPredicate;
import ctbrec.event.ModelStatePredicate;
import ctbrec.event.RecordingStatePredicate;
import ctbrec.recorder.Recorder; import ctbrec.recorder.Recorder;
import ctbrec.ui.CamrecApplication; import ctbrec.ui.CamrecApplication;
import ctbrec.ui.DesktopIntegration; import ctbrec.ui.DesktopIntegration;
import ctbrec.ui.controls.Dialogs;
import ctbrec.ui.controls.FileSelectionBox; import ctbrec.ui.controls.FileSelectionBox;
import ctbrec.ui.controls.ProgramSelectionBox; import ctbrec.ui.controls.ProgramSelectionBox;
import ctbrec.ui.controls.Wizard; import ctbrec.ui.controls.Wizard;
@ -42,9 +20,11 @@ import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.geometry.VPos; import javafx.geometry.VPos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
@ -53,6 +33,21 @@ import javafx.scene.layout.Priority;
import javafx.stage.Modality; import javafx.stage.Modality;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.stage.Window; import javafx.stage.Window;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class ActionSettingsPanel extends GridPane { public class ActionSettingsPanel extends GridPane {
private static final Logger LOG = LoggerFactory.getLogger(ActionSettingsPanel.class); private static final Logger LOG = LoggerFactory.getLogger(ActionSettingsPanel.class);
@ -65,6 +60,7 @@ public class ActionSettingsPanel extends GridPane {
private final CheckBox playSound = new CheckBox("Play sound"); private final CheckBox playSound = new CheckBox("Play sound");
private final FileSelectionBox sound = new FileSelectionBox(); private final FileSelectionBox sound = new FileSelectionBox();
private final Slider soundVolume = new Slider(0, 100, 100);
private final CheckBox showNotification = new CheckBox("Notify me"); private final CheckBox showNotification = new CheckBox("Notify me");
private final Button testNotification = new Button("Test"); private final Button testNotification = new Button("Test");
private final ToggleButton toggleEvents = new ToggleButton(); private final ToggleButton toggleEvents = new ToggleButton();
@ -142,7 +138,7 @@ public class ActionSettingsPanel extends GridPane {
dialog.setScene(scene); dialog.setScene(scene);
centerOnParent(dialog); centerOnParent(dialog);
dialog.showAndWait(); dialog.showAndWait();
if(!root.isCancelled()) { if (!root.isCancelled()) {
createEventHandler(); createEventHandler();
} }
} }
@ -151,46 +147,47 @@ public class ActionSettingsPanel extends GridPane {
var config = new EventHandlerConfiguration(); var config = new EventHandlerConfiguration();
config.setName(name.getText()); config.setName(name.getText());
config.setEvent(event.getValue()); config.setEvent(event.getValue());
if(event.getValue() == Event.Type.MODEL_STATUS_CHANGED) { if (event.getValue() == Event.Type.MODEL_STATUS_CHANGED) {
var pc = new PredicateConfiguration(); var pc = new PredicateConfiguration();
pc.setType(ModelStatePredicate.class.getName()); pc.setType(ModelStatePredicate.class.getName());
pc.getConfiguration().put("state", modelState.getValue().name()); pc.getConfiguration().put("state", modelState.getValue().name());
pc.setName("state = " + modelState.getValue().toString()); pc.setName("state = " + modelState.getValue().toString());
config.getPredicates().add(pc); config.getPredicates().add(pc);
} else if(event.getValue() == Event.Type.RECORDING_STATUS_CHANGED) { } else if (event.getValue() == Event.Type.RECORDING_STATUS_CHANGED) {
var pc = new PredicateConfiguration(); var pc = new PredicateConfiguration();
pc.setType(RecordingStatePredicate.class.getName()); pc.setType(RecordingStatePredicate.class.getName());
pc.getConfiguration().put("state", recordingState.getValue().name()); pc.getConfiguration().put("state", recordingState.getValue().name());
pc.setName("state = " + recordingState.getValue().toString()); pc.setName("state = " + recordingState.getValue().toString());
config.getPredicates().add(pc); config.getPredicates().add(pc);
} else if(event.getValue() == Event.Type.NO_SPACE_LEFT) { } else if (event.getValue() == Event.Type.NO_SPACE_LEFT) {
var pc = new PredicateConfiguration(); var pc = new PredicateConfiguration();
pc.setType(MatchAllPredicate.class.getName()); pc.setType(MatchAllPredicate.class.getName());
pc.setName("no space left"); pc.setName("no space left");
config.getPredicates().add(pc); config.getPredicates().add(pc);
} }
if(!modelSelectionPane.isAllSelected()) { if (!modelSelectionPane.isAllSelected()) {
var pc = new PredicateConfiguration(); var pc = new PredicateConfiguration();
pc.setType(ModelPredicate.class.getName()); pc.setType(ModelPredicate.class.getName());
pc.setModels(modelSelectionPane.getSelectedItems()); pc.setModels(modelSelectionPane.getSelectedItems());
pc.setName("model is one of:" + modelSelectionPane.getSelectedItems()); pc.setName("model is one of:" + modelSelectionPane.getSelectedItems());
config.getPredicates().add(pc); config.getPredicates().add(pc);
} }
if(showNotification.isSelected()) { if (showNotification.isSelected()) {
var ac = new ActionConfiguration(); var ac = new ActionConfiguration();
ac.setType(ShowNotification.class.getName()); ac.setType(ShowNotification.class.getName());
ac.setName("show notification"); ac.setName("show notification");
config.getActions().add(ac); config.getActions().add(ac);
} }
if(playSound.isSelected()) { if (playSound.isSelected()) {
var ac = new ActionConfiguration(); var ac = new ActionConfiguration();
ac.setType(PlaySound.class.getName()); ac.setType(PlaySound.class.getName());
var file = new File(sound.fileProperty().get()); var file = new File(sound.fileProperty().get());
ac.getConfiguration().put("file", file.getAbsolutePath()); ac.getConfiguration().put("file", file.getAbsolutePath());
ac.getConfiguration().put("volume", soundVolume.getValue() / 100);
ac.setName("play " + file.getName()); ac.setName("play " + file.getName());
config.getActions().add(ac); config.getActions().add(ac);
} }
if(executeProgram.isSelected()) { if (executeProgram.isSelected()) {
var ac = new ActionConfiguration(); var ac = new ActionConfiguration();
ac.setType(ExecuteProgram.class.getName()); ac.setType(ExecuteProgram.class.getName());
var file = new File(program.fileProperty().get()); var file = new File(program.fileProperty().get());
@ -207,19 +204,19 @@ public class ActionSettingsPanel extends GridPane {
} }
private void validateSettings() { private void validateSettings() {
if(StringUtil.isBlank(name.getText())) { if (StringUtil.isBlank(name.getText())) {
throw new IllegalStateException("Name cannot be empty"); throw new IllegalStateException("Name cannot be empty");
} }
if(event.getValue() == Event.Type.MODEL_STATUS_CHANGED && modelState.getValue() == null) { if (event.getValue() == Event.Type.MODEL_STATUS_CHANGED && modelState.getValue() == null) {
throw new IllegalStateException("Select a state"); throw new IllegalStateException("Select a state");
} }
if(event.getValue() == Event.Type.RECORDING_STATUS_CHANGED && recordingState.getValue() == null) { if (event.getValue() == Event.Type.RECORDING_STATUS_CHANGED && recordingState.getValue() == null) {
throw new IllegalStateException("Select a state"); throw new IllegalStateException("Select a state");
} }
if(event.getValue() != Event.Type.NO_SPACE_LEFT && modelSelectionPane.getSelectedItems().isEmpty() && !modelSelectionPane.isAllSelected()) { if (event.getValue() != Event.Type.NO_SPACE_LEFT && modelSelectionPane.getSelectedItems().isEmpty() && !modelSelectionPane.isAllSelected()) {
throw new IllegalStateException("Select one or more models or tick off \"all\""); throw new IllegalStateException("Select one or more models or tick off \"all\"");
} }
if(!(showNotification.isSelected() || playSound.isSelected() || executeProgram.isSelected())) { if (!(showNotification.isSelected() || playSound.isSelected() || executeProgram.isSelected())) {
throw new IllegalStateException("No action selected"); throw new IllegalStateException("No action selected");
} }
} }
@ -254,7 +251,7 @@ public class ActionSettingsPanel extends GridPane {
event.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> { event.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> {
var modelRelatedStuffDisabled = false; var modelRelatedStuffDisabled = false;
if(newV == Event.Type.NO_SPACE_LEFT) { if (newV == Event.Type.NO_SPACE_LEFT) {
modelRelatedStuffDisabled = true; modelRelatedStuffDisabled = true;
modelSelectionPane.selectAll(); modelSelectionPane.selectAll();
} }
@ -294,9 +291,20 @@ public class ActionSettingsPanel extends GridPane {
}); });
testNotification.disableProperty().bind(showNotification.selectedProperty().not()); testNotification.disableProperty().bind(showNotification.selectedProperty().not());
HBox soundContainer = new HBox();
soundContainer.setAlignment(Pos.CENTER_LEFT);
soundContainer.setSpacing(5);
layout.add(playSound, 0, row); layout.add(playSound, 0, row);
layout.add(sound, 1, row++); layout.add(soundContainer, 1, row++);
soundContainer.getChildren().add(soundVolume);
soundContainer.getChildren().add(sound);
sound.disableProperty().bind(playSound.selectedProperty().not()); sound.disableProperty().bind(playSound.selectedProperty().not());
soundVolume.setTooltip(new Tooltip("Volume"));
soundVolume.disableProperty().bind(playSound.selectedProperty().not());
HBox.setHgrow(sound, Priority.ALWAYS);
Button soundTest = new Button("Test");
soundTest.setOnAction(this::testSound);
soundContainer.getChildren().add(soundTest);
layout.add(executeProgram, 0, row); layout.add(executeProgram, 0, row);
layout.add(program, 1, row); layout.add(program, 1, row);
@ -304,11 +312,18 @@ public class ActionSettingsPanel extends GridPane {
GridPane.setFillWidth(name, true); GridPane.setFillWidth(name, true);
GridPane.setHgrow(name, Priority.ALWAYS); GridPane.setHgrow(name, Priority.ALWAYS);
GridPane.setFillWidth(sound, true);
return layout; return layout;
} }
private void testSound(ActionEvent actionEvent) {
try {
URL soundFileUrl = new File(sound.fileProperty().getValue()).toURI().toURL();
new PlaySound(soundFileUrl, soundVolume.getValue() / 100).accept(null);
} catch (MalformedURLException e) {
Dialogs.showError(getScene(), "Error", e.getLocalizedMessage(), e);
}
}
private ListView<EventHandlerConfiguration> createActionTable() { private ListView<EventHandlerConfiguration> createActionTable() {
ListView<EventHandlerConfiguration> view = new ListView<>(); ListView<EventHandlerConfiguration> view = new ListView<>();
view.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); view.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);