listView) {
- this.saveService = saveService;
- this.listView = listView;
- setContentDisplay(ContentDisplay.BOTTOM);
- vbox.getStylesheets().addAll(Objects.requireNonNull(getClass().getResource("/assets/1.css"), "Unable to find 1.css").toExternalForm());
- vbox.setAlignment(Pos.TOP_CENTER);
- textField.setOnAction(e -> {
- if (textField.getText().trim().isEmpty())
- return;
- commitEdit(getItem());
- });
- textField.setMaxWidth(listView.getWidth() - 30.0D);
- textField.setMaxHeight(30.0D);
- setOnMouseClicked(mouseClickedEvent -> {
- if (mouseClickedEvent.getButton() == MouseButton.PRIMARY && mouseClickedEvent.getClickCount() == 1)
- if (isEditing())
- cancelEdit();
- });
- }
-
- @Override
- protected void updateItem(Device device, boolean empty) {
- super.updateItem(device, empty);
- if (empty || device == null) {
- setGraphic(null);
- setText("");
- setMaxHeight(-1.0D);
- } else {
- setGraphic(vbox);
- imageView.setImage(device.getPreviewImage());
- setText(device.getDisplayName());
- vbox.setMaxHeight(30.0D + imageView.getFitHeight());
- }
- }
-
- @Override
- public void startEdit() {
- super.startEdit();
- textField.setText(getText());
- vbox.getChildren().add(0, textField);
- setText("");
- textField.requestFocus();
- textField.selectAll();
- }
-
- @Override
- public void cancelEdit() {
- super.cancelEdit();
- vbox.getChildren().remove(0);
- setText(getItem().getDisplayName());
- }
-
- @Override
- public void commitEdit(Device device) {
- var newValue = textField.getText().trim();
- super.commitEdit(device);
- listView.getSelectionModel().select(device);
- setText(newValue);
- device.setDisplayName(newValue);
- saveService.save();
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/FxHelper.java b/src/main/java/com/getpcpanel/ui/FxHelper.java
deleted file mode 100644
index 356b88d8..00000000
--- a/src/main/java/com/getpcpanel/ui/FxHelper.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.io.IOException;
-import java.net.URL;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.springframework.stereotype.Service;
-
-import com.getpcpanel.MainFX;
-import com.getpcpanel.device.Device;
-import com.getpcpanel.device.PCPanelMiniUI;
-import com.getpcpanel.device.PCPanelProUI;
-import com.getpcpanel.device.PCPanelRGBUI;
-import com.getpcpanel.profile.DeviceSave;
-import com.getpcpanel.profile.Profile;
-import com.getpcpanel.ui.AppFinderDialog.AppFinderParams;
-import com.getpcpanel.ui.BasicMacro.MacroArgs;
-import com.getpcpanel.ui.ProfileSettingsDialog.ProfileSettingsArgs;
-import com.getpcpanel.ui.UIInitializer.SingleParamInitializer;
-
-import javafx.fxml.FXMLLoader;
-import javafx.stage.Stage;
-import lombok.RequiredArgsConstructor;
-
-/**
- * Factory for creating FX dialogs
- */
-@Service
-@RequiredArgsConstructor
-public class FxHelper {
- public FXMLLoader getLoader(@Nullable URL location) {
- var loader = new FXMLLoader(location);
- loader.setControllerFactory(MainFX::getBean);
- return loader;
- }
-
- public > @Nonnull T open(@Nonnull Class dialogClass, @Nullable P params) {
- var loader = getLoader(getClass().getResource("/assets/%s.fxml".formatted(dialogClass.getSimpleName())));
- try {
- loader.load();
- var controller = loader.getController();
- if (params != null) {
- controller.initUI(params);
- }
- return controller;
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- public ProfileSettingsDialog buildProfileSettingsDialog(DeviceSave save, Profile profile) {
- return open(ProfileSettingsDialog.class, new ProfileSettingsArgs(save, profile));
- }
-
- public SettingsDialog buildSettingsDialog(Stage parentStage) {
- return open(SettingsDialog.class, new SingleParamInitializer<>(parentStage));
- }
-
- public RGBLightingDialog buildRGBLightingDialog(PCPanelRGBUI device) {
- return open(RGBLightingDialog.class, new SingleParamInitializer<>(device));
- }
-
- public ProLightingDialog buildProLightingDialog(PCPanelProUI device) {
- return open(ProLightingDialog.class, new SingleParamInitializer<>(device));
- }
-
- public MiniLightingDialog buildMiniLightingDialog(PCPanelMiniUI device) {
- return open(MiniLightingDialog.class, new SingleParamInitializer<>(device));
- }
-
- public BasicMacro buildBasicMacro(Device device, int knob, boolean hasButton, String name, String analogType) {
- return open(BasicMacro.class, new MacroArgs(device, knob, hasButton, name, analogType));
- }
-
- public BasicMacro buildBasicMacro(Device device, int knob) {
- return open(BasicMacro.class, new MacroArgs(device, knob, true, null, null));
- }
-
- public AppFinderDialog buildAppFinderDialog(@Nullable Stage parentStage, boolean volumeApps) {
- return open(AppFinderDialog.class, new AppFinderParams(parentStage, volumeApps));
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/HomePage.java b/src/main/java/com/getpcpanel/ui/HomePage.java
deleted file mode 100644
index c5188c14..00000000
--- a/src/main/java/com/getpcpanel/ui/HomePage.java
+++ /dev/null
@@ -1,265 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.util.Objects;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.context.event.EventListener;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.device.Device;
-import com.getpcpanel.hid.DeviceHolder;
-import com.getpcpanel.hid.DeviceScanner;
-import com.getpcpanel.profile.SaveService;
-import com.getpcpanel.util.version.VersionChecker.NewVersionAvailableEvent;
-
-import jakarta.annotation.PostConstruct;
-import javafx.application.Application;
-import javafx.application.Platform;
-import javafx.fxml.FXML;
-import javafx.scene.Scene;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.control.ListView;
-import javafx.scene.control.Slider;
-import javafx.scene.image.Image;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.Region;
-import javafx.scene.layout.VBox;
-import javafx.scene.text.Font;
-import javafx.stage.Stage;
-import javafx.stage.StageStyle;
-import lombok.RequiredArgsConstructor;
-import lombok.Setter;
-import lombok.extern.log4j.Log4j2;
-import one.util.streamex.StreamEx;
-
-@Log4j2
-@Component
-@RequiredArgsConstructor
-public class HomePage extends Application {
- private static final String TITLE_FORMAT = "PCPanel Controller %s";
- @SuppressWarnings("StaticNonFinalField") @Setter private static HomePage window;
- @SuppressWarnings("StaticNonFinalField") @Setter public static Stage stage;
- private final FxHelper fxHelper;
- private final SaveService saveService;
- private final DeviceScanner deviceScanner;
- private final DeviceHolder devices;
- private final ApplicationEventPublisher applicationEventPublisher;
-
- @Value("${application.version}") private String version;
- @Value("${application.build}") private String build;
-
- @FXML private Pane deviceHolder;
- @FXML private Pane titleHolder;
- @FXML private Pane hintHolder;
- @FXML private Pane lightingButtonHolder;
- @FXML private Pane profileHolder;
- @FXML private Button close;
- @FXML private Button min;
- @FXML private Button deviceListToggle;
- @FXML private Button settings;
- @FXML private Label versionLabel;
- @FXML private VBox labelTarget;
- @FXML private Label noDevicesLabel;
- @FXML private Label hintLabel;
- @FXML private ListView connectedDeviceList;
- @FXML private Slider globalBrightness;
- private Pane pane;
-
- @Override
- @PostConstruct
- public void init() {
- if (window != null) {
- log.error("Error 2 windows");
- return;
- }
- setWindow(this);
- }
-
- public void start(Stage stage, boolean quiet) throws Exception {
- start(stage);
- if (!quiet)
- stage.show();
- }
-
- @Override
- public void start(Stage stage) throws Exception {
- setStage(stage);
- var loader = fxHelper.getLoader(getClass().getResource("/assets/HomePage.fxml"));
- loader.setController(this);
- pane = loader.load();
- pane.setId("pane");
- var scene = new Scene(pane, 1000.0D, 870.0D);
- showHint(false);
- initWindow();
- scene.getStylesheets().addAll(Objects.requireNonNull(getClass().getResource("/assets/1.css")).toExternalForm());
- stage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResource("/assets/256x256.png")).toExternalForm()));
- stage.setScene(scene);
- ResizeHelper.addResizeListener(stage, 200.0D, 200.0D);
- Platform.setImplicitExit(false);
- stage.initStyle(StageStyle.UNDECORATED);
- stage.sizeToScene();
- stage.setTitle(TITLE_FORMAT.formatted(version));
- addBrightnessListener();
-
- deviceScanner.init();
- }
-
- @EventListener
- public void globalBrightnessChanged(GlobalBrightnessChangedEvent event) {
- if (!event.isSource(this)) {
- globalBrightness.setValue(connectedDeviceList.getSelectionModel().getSelectedItem().getLightingConfig().getGlobalBrightness());
- }
- }
-
- private void addBrightnessListener() {
- globalBrightness.valueProperty().addListener((observable, oldValue, newValue) -> {
- var device = connectedDeviceList.getSelectionModel().getSelectedItem();
- if (device == null) {
- return;
- }
- var serialNumber = device.getSerialNumber();
-
- // Set saved brightness
- saveService.getProfile(serialNumber).ifPresent(profile -> {
- var cfg = profile.getLightingConfig();
- cfg.setGlobalBrightness(newValue.byteValue());
- profile.setLightingConfig(cfg);
- saveService.debouncedSave();
- });
-
- // Set current brightness
- var light = device.getLightingConfig();
- light.setGlobalBrightness(newValue.byteValue());
- device.setLighting(light, false);
- applicationEventPublisher.publishEvent(new GlobalBrightnessChangedEvent(this, serialNumber, newValue.intValue()));
- });
- }
-
- private String buildVersion() {
- return version + (StringUtils.containsIgnoreCase(version, "snapshot") ? " (" + build + ")" : "");
- }
-
- public static void showHint(boolean show) {
- if (show) {
- if (!window.hintHolder.getChildren().contains(window.hintLabel))
- window.hintHolder.getChildren().add(window.hintLabel);
- } else
- window.hintHolder.getChildren().remove(window.hintLabel);
- }
-
- @EventListener(ShowMainEvent.class)
- public void reopen() {
- Platform.runLater(() -> {
- stage.show();
- stage.setIconified(false);
- stage.toFront();
- });
- }
-
- @EventListener
- public void onDeviceConnected(DeviceScanner.DeviceConnectedEvent event) {
- Platform.runLater(() -> devices.getDevice(event.serialNum()).ifPresent(this::addDeviceToUI));
- }
-
- @EventListener
- public void onDeviceDisconnected(DeviceScanner.DeviceDisconnectedEvent event) {
- Platform.runLater(() -> StreamEx.of(connectedDeviceList.getItems()).filterBy(Device::getSerialNumber, event.serialNum()).findFirst().ifPresent(connectedDeviceList.getItems()::remove));
- }
-
- private void addDeviceToUI(Device device) {
- device.setLighting(device.getLightingConfig(), true);
- if (devices.size() == 2)
- setConnectedDeviceListVisible(true);
- connectedDeviceList.getItems().add(device);
- connectedDeviceList.getSelectionModel().select(device);
- }
-
- private boolean isConnectedDeviceListVisisble() {
- return pane.getChildren().contains(connectedDeviceList);
- }
-
- private void setConnectedDeviceListVisible(boolean vis) {
- if (vis) {
- if (!pane.getChildren().contains(connectedDeviceList))
- pane.getChildren().add(0, connectedDeviceList);
- } else {
- pane.getChildren().remove(connectedDeviceList);
- }
- }
-
- private void initWindow() {
- connectedDeviceList.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
- if (!deviceHolder.getChildren().isEmpty())
- deviceHolder.getChildren().clear();
- if (!titleHolder.getChildren().isEmpty())
- titleHolder.getChildren().clear();
- if (!lightingButtonHolder.getChildren().isEmpty())
- lightingButtonHolder.getChildren().clear();
- if (!profileHolder.getChildren().isEmpty())
- profileHolder.getChildren().clear();
- if (newValue == null) {
- titleHolder.getChildren().add(noDevicesLabel);
- } else {
- deviceHolder.getChildren().add(newValue.getDevicePane());
- titleHolder.getChildren().add(newValue.getLabel());
- lightingButtonHolder.getChildren().add(newValue.getLightingButton());
- profileHolder.getChildren().add(newValue.getProfileMenu());
- globalBrightness.setValue(newValue.getLightingConfig().getGlobalBrightness());
- }
- });
- connectedDeviceList.setCellFactory(DeviceCell.buildFactory(saveService));
- connectedDeviceList.setEditable(true);
- setConnectedDeviceListVisible(false);
- var apex = Font.loadFont(getClass().getResourceAsStream("/assets/apex-mk2.regular.otf"), 50.0D);
- noDevicesLabel.setFont(apex);
- close.setOnAction(e -> stage.hide());
- settings.setOnAction(e -> {
- try {
- var sd = fxHelper.buildSettingsDialog(stage);
- var childDialogStage = new Stage();
- sd.start(childDialogStage);
- } catch (Exception ex) {
- log.error("Unable to open settings dialog", ex);
- }
- });
- min.setOnAction(e -> stage.setIconified(true));
- var icon = new Region();
- icon.setId("icon");
- min.setGraphic(icon);
- deviceListToggle.setOnAction(e -> setConnectedDeviceListVisible(!isConnectedDeviceListVisisble()));
- versionLabel.setText(TITLE_FORMAT.formatted(buildVersion()));
- }
-
- @EventListener
- public void newVersionAvailable(NewVersionAvailableEvent event) {
- var label = new Label("New version available: " + event.version().versionDisplay());
- label.setStyle("-fx-text-fill: #ff8888; -fx-font-weight: bold;");
- label.setOnMouseClicked(e -> getHostServices().showDocument(event.version().html_url()));
- Platform.runLater(() -> labelTarget.getChildren().add(label));
- }
-
- @EventListener
- public void onSaveEvent(SaveService.SaveEvent event) {
- Platform.runLater(() -> {
- showHint(event.isNew());
-
- var selectedDevice = connectedDeviceList.getSelectionModel().getSelectedItem();
- if (selectedDevice != null) {
- globalBrightness.setValue(selectedDevice.getLightingConfig().getGlobalBrightness());
- }
- });
- }
-
- public record ShowMainEvent() {
- }
-
- public record GlobalBrightnessChangedEvent(Object source, String serialNr, int brightness) {
- public boolean isSource(Object other) {
- //noinspection ObjectEquality
- return source == other;
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/ILightingDialogMuteOverrideHelper.java b/src/main/java/com/getpcpanel/ui/ILightingDialogMuteOverrideHelper.java
deleted file mode 100644
index f365102d..00000000
--- a/src/main/java/com/getpcpanel/ui/ILightingDialogMuteOverrideHelper.java
+++ /dev/null
@@ -1,179 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.function.Consumer;
-
-import javax.annotation.Nullable;
-
-import org.apache.commons.lang3.StringUtils;
-
-import com.getpcpanel.MainFX;
-import com.getpcpanel.cpp.AudioDevice;
-import com.getpcpanel.ui.colorpicker.ColorDialog;
-import com.getpcpanel.voicemeeter.Voicemeeter;
-import com.getpcpanel.voicemeeter.Voicemeeter.ButtonType;
-import com.getpcpanel.voicemeeter.Voicemeeter.ControlType;
-
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.ComboBox;
-import javafx.scene.control.Label;
-import javafx.scene.control.Tab;
-import javafx.scene.control.TabPane;
-import javafx.scene.control.TabPane.TabClosingPolicy;
-import javafx.scene.control.Tooltip;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Color;
-import one.util.streamex.EntryStream;
-import one.util.streamex.StreamEx;
-
-public interface ILightingDialogMuteOverrideHelper {
- String FOLLOW_PROCESS = "Follow what is controlled by this knob/slider";
-
- record OverrideTarget(CheckBox[] cb, ComboBox[] deviceProcess, ColorDialog[] cd) {
- }
-
- enum OverrideTargetType {
- KNOB, SLIDER, SLIDER_LABEL
- }
-
- CheckBox[] getMuteOverrideCheckboxesKnobs();
-
- ComboBox[] getMuteOverrideComboBoxesKnobs();
-
- ColorDialog[] getMuteOverrideColorsKnobs();
-
- default CheckBox[] getMuteOverrideCheckboxesSliders() {
- return new CheckBox[0];
- }
-
- default ComboBox[] getMuteOverrideComboBoxesSliders() {
- //noinspection unchecked
- return new ComboBox[0];
- }
-
- default ColorDialog[] getMuteOverrideColorsSliders() {
- return new ColorDialog[0];
- }
-
- default CheckBox[] getMuteOverrideCheckboxesSliderLabels() {
- return new CheckBox[0];
- }
-
- default ComboBox[] getMuteOverrideComboBoxesSliderLabels() {
- //noinspection unchecked
- return new ComboBox[0];
- }
-
- default ColorDialog[] getMuteOverrideColorsSliderLabels() {
- return new ColorDialog[0];
- }
-
- Collection getDevices();
-
- @SuppressWarnings("NestedAssignment")
- default TabPane tabWithMuteOverride(ProLightingDialog.OverrideTargetType ott, int button, TabPane tab) {
- var target = getOverrideTarget(ott);
- var vBox = new VBox();
- var cd = target.cd()[button] = new ColorDialog();
- var deviceProcess = target.deviceProcess()[button] = new ComboBox<>();
- var cb = target.cb()[button] = new CheckBox("Enable mute override");
- var label = new Label(
- "Mute override looks at the action on the dial/slider, not the button. If a dial controls the volume of a device or process, "
- + "the mute override will set the color when that device or process is muted. If the button action triggers mute but the slider/dial "
- + "does not control that device/process, mute override will do nothing.");
- var insets = new Insets(15, 15, 0, 15);
- label.setPadding(insets);
- cb.setPadding(insets);
- label.setWrapText(true);
- vBox.getChildren().addAll(
- label,
- cb,
- setDeviceProcessOptions(deviceProcess, insets),
- cd
- );
-
- var muteTab = new Tab("Mute override", vBox);
- var originalTab = new Tab("Color", tab);
-
- var result = new TabPane(originalTab, muteTab);
- result.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
- return result;
- }
-
- private HBox setDeviceProcessOptions(ComboBox deviceProcess, Insets insets) {
- deviceProcess.setEditable(true);
- deviceProcess.setTooltip(new Tooltip("Can be a partial device name"));
-
- StreamEx.of(FOLLOW_PROCESS).append(devices())
- .append(voiceMeeterOptions())
- .forEach(deviceProcess.getItems()::add);
-
- deviceProcess.setPrefWidth(20000);
- var label = new Label("Follow: ");
- label.setMinWidth(100);
-
- var deviceProcessBox = new HBox();
- deviceProcessBox.setPadding(insets);
- deviceProcessBox.setAlignment(Pos.CENTER);
- deviceProcessBox.getChildren().add(label);
- deviceProcessBox.getChildren().add(deviceProcess);
- return deviceProcessBox;
- }
-
- default StreamEx devices() {
- return StreamEx.of(getDevices()).map(AudioDevice::name).sorted();
- }
-
- default StreamEx voiceMeeterOptions() {
- var voiceMeeter = MainFX.getBean(Voicemeeter.class);
- var version = voiceMeeter.getVersion();
- if (!voiceMeeter.login() || version == null) {
- return StreamEx.of();
- }
-
- return EntryStream.of(Collections.nCopies(voiceMeeter.getNumStrips(), ControlType.STRIP)).append(EntryStream.of(Collections.nCopies(voiceMeeter.getNumBuses(), ControlType.BUS)))
- .flatMapKeyValue((idx, ct) -> StreamEx.of(ButtonType.stateButtonsFor(ct, version)).map(sb -> "VoiceMeeter: " + ct.getDn() + " " + (idx + 1) + ", " + sb));
- }
-
- default CheckBox[] allOverrideCheckboxes() {
- return StreamEx.of(OverrideTargetType.values()).flatMap(t -> StreamEx.of(getOverrideTarget(t).cb())).toArray(CheckBox[]::new);
- }
-
- default ColorDialog[] allOverrideColors() {
- return StreamEx.of(OverrideTargetType.values()).flatMap(t -> StreamEx.of(getOverrideTarget(t).cd())).toArray(ColorDialog[]::new);
- }
-
- default ComboBox>[] allOverrideComboBoxes() {
- return StreamEx.of(OverrideTargetType.values()).flatMap(t -> StreamEx.of(getOverrideTarget(t).deviceProcess())).toArray(ComboBox[]::new);
- }
-
- default OverrideTarget getOverrideTarget(OverrideTargetType ott) {
- return switch (ott) {
- case KNOB -> new OverrideTarget(getMuteOverrideCheckboxesKnobs(), getMuteOverrideComboBoxesKnobs(), getMuteOverrideColorsKnobs());
- case SLIDER -> new OverrideTarget(getMuteOverrideCheckboxesSliders(), getMuteOverrideComboBoxesSliders(), getMuteOverrideColorsSliders());
- case SLIDER_LABEL -> new OverrideTarget(getMuteOverrideCheckboxesSliderLabels(), getMuteOverrideComboBoxesSliderLabels(), getMuteOverrideColorsSliderLabels());
- };
- }
-
- default void setOverride(OverrideTargetType type, int typeIndex, @Nullable String deviceOrFollow, @Nullable String muteOverrideColor) {
- var target = getOverrideTarget(type);
- target.cb()[typeIndex].setSelected(StringUtils.isNotBlank(muteOverrideColor));
- target.deviceProcess()[typeIndex].setValue(deviceOrFollow);
- target.cd()[typeIndex].setCustomColor(Color.web(StringUtils.defaultIfBlank(muteOverrideColor, "black")));
- }
-
- default void setOverrideSetting(OverrideTargetType type, int typeIdx, Consumer deviceFollowSetter, Consumer colorSetter) {
- var target = getOverrideTarget(type);
- if (target.cb()[typeIdx].isSelected()) {
- deviceFollowSetter.accept(target.deviceProcess()[typeIdx].getValue());
- colorSetter.accept(target.cd()[typeIdx].getCustomColor());
- } else {
- deviceFollowSetter.accept(null);
- colorSetter.accept(null);
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/LightingChangedToDefaultEvent.java b/src/main/java/com/getpcpanel/ui/LightingChangedToDefaultEvent.java
deleted file mode 100644
index f4d1fb55..00000000
--- a/src/main/java/com/getpcpanel/ui/LightingChangedToDefaultEvent.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.getpcpanel.ui;
-
-public enum LightingChangedToDefaultEvent {
- INSTANCE
-}
diff --git a/src/main/java/com/getpcpanel/ui/LimitedTextField.java b/src/main/java/com/getpcpanel/ui/LimitedTextField.java
deleted file mode 100644
index a087d16d..00000000
--- a/src/main/java/com/getpcpanel/ui/LimitedTextField.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.util.Objects;
-
-import javafx.beans.property.IntegerProperty;
-import javafx.beans.property.SimpleIntegerProperty;
-import javafx.scene.control.TextField;
-
-public class LimitedTextField extends TextField {
- private final IntegerProperty maxLength;
-
- public LimitedTextField(int limit) {
- maxLength = new SimpleIntegerProperty(limit);
- }
-
- public IntegerProperty maxLengthProperty() {
- return maxLength;
- }
-
- public final Integer getMaxLength() {
- return maxLength.getValue();
- }
-
- public final void setMaxLength(Integer maxLength) {
- Objects.requireNonNull(maxLength, "Max length cannot be null, -1 for no limit");
- this.maxLength.setValue(maxLength);
- }
-
- @Override
- public void replaceText(int start, int end, String insertedText) {
- if (getMaxLength() <= 0) {
- super.replaceText(start, end, insertedText);
- } else {
- var currentText = (getText() == null) ? "" : getText();
- var finalText = currentText.substring(0, start) + insertedText + currentText.substring(end);
- var numberOfexceedingCharacters = finalText.length() - getMaxLength();
- if (numberOfexceedingCharacters <= 0) {
- super.replaceText(start, end, insertedText);
- } else {
- var cutInsertedText = insertedText.substring(
- 0,
- insertedText.length() - numberOfexceedingCharacters);
- super.replaceText(start, end, cutInsertedText);
- }
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/MacroControllerService.java b/src/main/java/com/getpcpanel/ui/MacroControllerService.java
deleted file mode 100644
index 93e1ae5c..00000000
--- a/src/main/java/com/getpcpanel/ui/MacroControllerService.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.getpcpanel.ui;
-
-import static java.util.Objects.requireNonNull;
-
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
-import org.springframework.core.type.filter.AnnotationTypeFilter;
-import org.springframework.stereotype.Service;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.spring.OsHelper;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.Cmd.Type;
-import com.getpcpanel.ui.command.DialCommandController;
-
-import jakarta.annotation.PostConstruct;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Service
-@RequiredArgsConstructor
-public class MacroControllerService {
- private static final Map> typeToControllers = new EnumMap<>(Type.class);
- private static final Map, ControllerInfo> commandToController = new HashMap<>();
- private final OsHelper osHelper;
-
- @SneakyThrows
- @PostConstruct
- public void init() {
- var provider = new ClassPathScanningCandidateComponentProvider(false);
- provider.addIncludeFilter(new AnnotationTypeFilter(Cmd.class));
-
- var beanDefs = provider.findCandidateComponents("com.getpcpanel");
- for (var bd : beanDefs) {
- var controllerClass = Class.forName(bd.getBeanClassName());
- var cmd = controllerClass.getAnnotation(Cmd.class);
-
- if (!osHelper.isOs(cmd.os())) {
- continue;
- }
-
- var info = new ControllerInfo(controllerClass, cmd);
- var type = getTypeForController(controllerClass);
- typeToControllers.computeIfAbsent(type, t -> new ArrayList<>()).add(info);
- for (var command : cmd.cmds()) {
- commandToController.put(command, info);
- }
- }
-
- for (var type : Type.values()) {
- typeToControllers.computeIfAbsent(type, t -> new ArrayList<>()).sort(Comparator.comparing(a -> a.cmd().name()));
- }
- }
-
- public ControllerInfo getControllerForCommand(Class extends Command> cmd) {
- return commandToController.get(cmd);
- }
-
- public List getControllersForType(Type type) {
- return typeToControllers.get(type);
- }
-
- private static Type getTypeForController(Class> controllerClass) {
- return DialCommandController.class.isAssignableFrom(controllerClass) ? Type.dial : Type.button;
- }
-
- public record ControllerInfo(Class> controllerClass, Cmd cmd) {
- public URL getFxml() {
- return requireNonNull(getClass().getResource("/assets/command/%s/%s.fxml".formatted(getTypeForController(controllerClass).name(), cmd.fxml())));
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/MiniLightingDialog.java b/src/main/java/com/getpcpanel/ui/MiniLightingDialog.java
deleted file mode 100644
index ec1f4b1d..00000000
--- a/src/main/java/com/getpcpanel/ui/MiniLightingDialog.java
+++ /dev/null
@@ -1,373 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.util.Collection;
-import java.util.Objects;
-
-import javax.annotation.Nonnull;
-
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.cpp.AudioDevice;
-import com.getpcpanel.cpp.ISndCtrl;
-import com.getpcpanel.device.Device;
-import com.getpcpanel.profile.LightingConfig;
-import com.getpcpanel.profile.LightingConfig.LightingMode;
-import com.getpcpanel.profile.SaveService;
-import com.getpcpanel.profile.SingleKnobLightingConfig.SINGLE_KNOB_MODE;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.UIInitializer.SingleParamInitializer;
-import com.getpcpanel.ui.colorpicker.ColorDialog;
-import com.getpcpanel.ui.colorpicker.HueSlider;
-import com.getpcpanel.util.Util;
-
-import javafx.application.Application;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.geometry.Side;
-import javafx.scene.Node;
-import javafx.scene.Scene;
-import javafx.scene.control.Button;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.ComboBox;
-import javafx.scene.control.Label;
-import javafx.scene.control.Slider;
-import javafx.scene.control.Tab;
-import javafx.scene.control.TabPane;
-import javafx.scene.control.TabPane.TabClosingPolicy;
-import javafx.scene.image.Image;
-import javafx.scene.layout.GridPane;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Color;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-public class MiniLightingDialog extends Application implements UIInitializer>, ILightingDialogMuteOverrideHelper {
- private final SaveService saveService;
- private final ApplicationEventPublisher eventPublisher;
- private final ISndCtrl sndCtrl;
- private Device device;
-
- private Stage stage;
- @FXML private TabPane mainPane;
- @FXML private TabPane knobsTabbedPane;
- @FXML private TabPane fullBodyTabbedPane;
- @FXML private Slider rainbowPhaseShift;
- @FXML private Slider rainbowBrightness;
- @FXML private Slider rainbowSpeed;
- @FXML private CheckBox rainbowReverse;
- @FXML private CheckBox rainbowVertical;
- private HueSlider waveHue;
- @FXML private Slider waveBrightness;
- @FXML private Slider waveSpeed;
- @FXML private CheckBox waveReverse;
- @FXML private CheckBox waveBounce;
- private HueSlider breathHue;
- @FXML private Slider breathBrightness;
- @FXML private Slider breathSpeed;
- @FXML private VBox wavebox;
- @FXML private VBox breathbox;
- @FXML private Button applyToAllButton;
- private ColorDialog allKnobColor;
- private static final int NUM_KNOBS = 4;
- private final TabPane[] knobSingleTabPane = new TabPane[NUM_KNOBS];
- private final ColorDialog[] knobStaticCDs = new ColorDialog[NUM_KNOBS];
- private final ColorDialog[] knobVolumeGradientCD1 = new ColorDialog[NUM_KNOBS];
- private final ColorDialog[] knobVolumeGradientCD2 = new ColorDialog[NUM_KNOBS];
- @Getter private final CheckBox[] muteOverrideCheckboxesKnobs = new CheckBox[NUM_KNOBS];
- @SuppressWarnings("unchecked") @Getter private final ComboBox[] muteOverrideComboBoxesKnobs = new ComboBox[NUM_KNOBS];
- @Getter private final ColorDialog[] muteOverrideColorsKnobs = new ColorDialog[NUM_KNOBS];
-
- private boolean pressedOk;
- @FXML private Pane root;
- private LightingConfig lightingConfig;
-
- @Override
- public void initUI(@Nonnull SingleParamInitializer args) {
- device = args.param();
- lightingConfig = device.getSavedLightingConfig().deepCopy();
- setDeviceLighting();
- postInit();
- }
-
- private void setDeviceLighting() {
- device.setLighting(lightingConfig.deepCopy(), true);
- }
-
- @Override
- public void start(Stage stage) {
- this.stage = stage;
- UIHelper.closeOnEscape(stage);
- var scene = new Scene(Objects.requireNonNull(root));
- scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/assets/dark_theme.css")).toExternalForm());
- stage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResource("/assets/256x256.png")).toExternalForm()));
- stage.setOnHiding(e -> {
- if (!pressedOk) {
- device.setLighting(device.getSavedLightingConfig(), true);
- }
- eventPublisher.publishEvent(LightingChangedToDefaultEvent.INSTANCE);
- });
- stage.initModality(Modality.APPLICATION_MODAL);
- stage.initOwner(HomePage.stage);
- stage.setScene(scene);
- stage.sizeToScene();
- stage.setTitle("Lighting Dialog");
- stage.show();
- }
-
- public MiniLightingDialog select(int idx) {
- mainPane.getSelectionModel().select(1);
- knobsTabbedPane.getSelectionModel().select(idx);
- return this;
- }
-
- @FXML
- private void onCancel(ActionEvent event) {
- stage.close();
- }
-
- @FXML
- private void ok(ActionEvent event) {
- log.debug("{} {}", stage.getWidth(), stage.getHeight());
- pressedOk = true;
- device.setSavedLighting(lightingConfig);
- saveService.save();
- stage.close();
- }
-
- @FXML
- private void turnOffLights(ActionEvent event) {
- allKnobColor.setCustomColor(Color.WHITE);
- allKnobColor.setCustomColor(Color.BLACK);
- mainPane.getSelectionModel().select(0);
- fullBodyTabbedPane.getSelectionModel().select(0);
- }
-
- private void postInit() {
- for (var i = 0; i < NUM_KNOBS; i++) {
- var knob = i + 1;
- var tab = new Tab("Knob " + knob);
- var cd = new ColorDialog(Color.BLACK);
- knobStaticCDs[i] = cd;
- knobVolumeGradientCD1[i] = new ColorDialog();
- knobVolumeGradientCD2[i] = new ColorDialog();
- var volGradientGP = makeFourPanelGridPane(
- knobVolumeGradientCD2[i], knobVolumeGradientCD1[i]);
- var vbox = new VBox(volGradientGP);
- var staticTab = new Tab("Static", cd);
- var volGradient = new Tab("Volume Gradient", vbox);
- var singleKnobTabPane = new TabPane(staticTab, volGradient);
- knobSingleTabPane[i] = singleKnobTabPane;
- Util.adjustTabs(singleKnobTabPane, 140, 30);
- singleKnobTabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
- singleKnobTabPane.setSide(Side.LEFT);
- tab.setContent(tabWithMuteOverride(OverrideTargetType.KNOB, i, singleKnobTabPane));
- knobsTabbedPane.getTabs().add(tab);
- }
- Util.adjustTabs(fullBodyTabbedPane, 120, 30);
- allKnobColor = new ColorDialog();
- fullBodyTabbedPane.getTabs().get(0).setContent(allKnobColor);
- var allSliders = new Slider[] { rainbowPhaseShift, rainbowBrightness, rainbowSpeed,
- waveBrightness, waveSpeed,
- breathBrightness, breathSpeed };
- var allCheckBoxes = new CheckBox[] { rainbowReverse, rainbowVertical,
- waveReverse, waveBounce };
- waveHue = new HueSlider();
- wavebox.getChildren().add(1, waveHue);
- breathHue = new HueSlider();
- breathbox.getChildren().add(1, breathHue);
- applyToAllButton.setOnAction(e -> {
- if (mainPane.getSelectionModel().getSelectedIndex() == 1) {
- var knobIndex = knobsTabbedPane.getSelectionModel().getSelectedIndex();
- for (var i = 0; i < lightingConfig.getKnobConfigs().length; i++) {
- if (i != knobIndex)
- lightingConfig.getKnobConfigs()[i].set(lightingConfig.getKnobConfigs()[knobIndex]);
- }
- }
- initFields();
- });
- initFields();
- initListeners(allSliders, allCheckBoxes);
- }
-
- private void initFields() {
- var mode = lightingConfig.getLightingMode();
- if (mode == LightingMode.ALL_COLOR) {
- mainPane.getSelectionModel().select(0);
- fullBodyTabbedPane.getSelectionModel().select(0);
- allKnobColor.setCustomColor(Color.web(lightingConfig.getAllColor()));
- } else if (mode == LightingMode.ALL_RAINBOW) {
- mainPane.getSelectionModel().select(0);
- fullBodyTabbedPane.getSelectionModel().select(1);
- rainbowPhaseShift.setValue(lightingConfig.getRainbowPhaseShift() & 0xFF);
- rainbowBrightness.setValue(lightingConfig.getRainbowBrightness() & 0xFF);
- rainbowSpeed.setValue(lightingConfig.getRainbowSpeed() & 0xFF);
- rainbowReverse.setSelected(lightingConfig.getRainbowReverse() == 1);
- rainbowVertical.setSelected(lightingConfig.getRainbowVertical() == 1);
- } else if (mode == LightingMode.ALL_WAVE) {
- mainPane.getSelectionModel().select(0);
- fullBodyTabbedPane.getSelectionModel().select(2);
- waveHue.setHue(lightingConfig.getWaveHue() & 0xFF);
- waveBrightness.setValue(lightingConfig.getWaveBrightness() & 0xFF);
- waveSpeed.setValue(lightingConfig.getWaveSpeed() & 0xFF);
- waveReverse.setSelected(lightingConfig.getWaveReverse() == 1);
- waveBounce.setSelected(lightingConfig.getWaveBounce() == 1);
- } else if (mode == LightingMode.ALL_BREATH) {
- mainPane.getSelectionModel().select(0);
- fullBodyTabbedPane.getSelectionModel().select(3);
- breathHue.setHue(lightingConfig.getBreathHue() & 0xFF);
- breathBrightness.setValue(lightingConfig.getBreathBrightness() & 0xFF);
- breathSpeed.setValue(lightingConfig.getBreathSpeed() & 0xFF);
- } else if (mode == LightingMode.CUSTOM) {
- if (mainPane.getSelectionModel().getSelectedIndex() == 0)
- mainPane.getSelectionModel().select(1);
- var knobConfigs = lightingConfig.getKnobConfigs();
- for (var i = 0; i < NUM_KNOBS; i++) {
- var knobConfig = knobConfigs[i];
- if (knobConfig.getMode() == SINGLE_KNOB_MODE.STATIC) {
- knobSingleTabPane[i].getSelectionModel().select(0);
- knobStaticCDs[i].setCustomColor(Color.web(knobConfig.getColor1()));
- } else if (knobConfig.getMode() == SINGLE_KNOB_MODE.VOLUME_GRADIENT) {
- knobSingleTabPane[i].getSelectionModel().select(1);
- knobVolumeGradientCD1[i].setCustomColor(Color.web(knobConfig.getColor1()));
- knobVolumeGradientCD2[i].setCustomColor(Color.web(knobConfig.getColor2()));
- }
- setOverride(OverrideTargetType.KNOB, i, knobConfig.getMuteOverrideDeviceOrFollow(), knobConfig.getMuteOverrideColor());
- }
- }
- updateApplyToAllButton();
- }
-
- private void addListener(ColorDialog[]... xs) {
- for (var x : xs) {
- for (var cd : x) {
- cd.customColorProperty().addListener((a, bb, c) -> updateColors());
- }
- }
- }
-
- private void addListener(TabPane... tbs) {
- for (var tb : tbs) {
- tb.getSelectionModel().selectedItemProperty().addListener((a, bb, c) -> updateColors());
- }
- }
-
- private void addListener(CheckBox[]... checkss) {
- for (var checks : checkss) {
- for (var check : checks) {
- check.setOnAction(a -> updateColors());
- }
- }
- }
-
- private void addListener(ComboBox>[]... boxes) {
- for (var checks : boxes) {
- for (var check : checks) {
- check.setOnAction(a -> updateColors());
- }
- }
- }
-
- private void initListeners(Slider[] allSliders, CheckBox[] allCheckBoxes) {
- addListener(knobStaticCDs, knobVolumeGradientCD1, allOverrideColors(), knobVolumeGradientCD2);
- addListener(knobSingleTabPane);
- allKnobColor.customColorProperty().addListener((observable, oldValue, newValue) -> {
- for (var cd : knobStaticCDs) {
- cd.setCustomColor(newValue);
- }
- updateColors();
- });
- addListener(fullBodyTabbedPane);
- addListener(allOverrideCheckboxes());
- addListener(allOverrideComboBoxes());
- for (var slider : allSliders) {
- slider.valueProperty().addListener((observable, oldValue, newValue) -> updateColors());
- }
- for (var cb : allCheckBoxes) {
- cb.selectedProperty().addListener((observable, oldValue, newValue) -> updateColors());
- }
-
- waveHue.getHueProperty().addListener((observable, oldValue, newValue) -> updateColors());
- breathHue.getHueProperty().addListener((observable, oldValue, newValue) -> updateColors());
- mainPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
- updateColors();
- updateApplyToAllButton();
- });
- }
-
- private void updateApplyToAllButton() {
- if (mainPane.getSelectionModel().getSelectedIndex() == 0 || mainPane.getSelectionModel().getSelectedIndex() == 4) {
- applyToAllButton.setVisible(false);
- return;
- }
- applyToAllButton.setVisible(true);
- if (mainPane.getSelectionModel().getSelectedIndex() == 1) {
- applyToAllButton.setText("Apply To All Knobs");
- } else if (mainPane.getSelectionModel().getSelectedIndex() == 2) {
- applyToAllButton.setText("Apply To All Sliders");
- } else if (mainPane.getSelectionModel().getSelectedIndex() == 3) {
- applyToAllButton.setText("Apply To All Slider Labels");
- }
- }
-
- @SuppressWarnings("NumericCastThatLosesPrecision")
- private void updateColors() {
- if (mainPane.getSelectionModel().getSelectedIndex() == 0) {
- if (fullBodyTabbedPane.getSelectionModel().getSelectedIndex() == 0) {
- lightingConfig = LightingConfig.createAllColor(allKnobColor.getCustomColor());
- setDeviceLighting();
- } else if (fullBodyTabbedPane.getSelectionModel().getSelectedIndex() == 1) {
- lightingConfig = LightingConfig.createRainbowAnimation((byte) (int) rainbowPhaseShift.getValue(), (byte) (int) rainbowBrightness.getValue(),
- (byte) (int) rainbowSpeed.getValue(), rainbowReverse.isSelected(), rainbowVertical.isSelected());
- setDeviceLighting();
- } else if (fullBodyTabbedPane.getSelectionModel().getSelectedIndex() == 2) {
- lightingConfig = LightingConfig.createWaveAnimation((byte) waveHue.getHue(), (byte) (int) waveBrightness.getValue(), (byte) (int) waveSpeed.getValue(),
- waveReverse.isSelected(), waveBounce.isSelected());
- setDeviceLighting();
- } else if (fullBodyTabbedPane.getSelectionModel().getSelectedIndex() == 3) {
- lightingConfig = LightingConfig.createBreathAnimation((byte) breathHue.getHue(), (byte) (int) breathBrightness.getValue(), (byte) (int) breathSpeed.getValue());
- setDeviceLighting();
- }
- } else {
- lightingConfig = new LightingConfig(NUM_KNOBS, 0);
- lightingConfig.setLightingMode(LightingMode.CUSTOM);
- for (var knob = 0; knob < NUM_KNOBS; knob++) {
- var knobConfig = lightingConfig.getKnobConfigs()[knob];
- if (knobSingleTabPane[knob].getSelectionModel().getSelectedIndex() == 0) {
- knobConfig.setMode(SINGLE_KNOB_MODE.STATIC);
- knobConfig.setColor1FromColor(knobStaticCDs[knob].getCustomColor());
- } else if (knobSingleTabPane[knob].getSelectionModel().getSelectedIndex() == 1) {
- knobConfig.setMode(SINGLE_KNOB_MODE.VOLUME_GRADIENT);
- knobConfig.setColor1FromColor(knobVolumeGradientCD1[knob].getCustomColor());
- knobConfig.setColor2FromColor(knobVolumeGradientCD2[knob].getCustomColor());
- }
- setOverrideSetting(OverrideTargetType.KNOB, knob, knobConfig::setMuteOverrideDeviceOrFollow, knobConfig::setMuteOverrideColorFromColor);
- }
- setDeviceLighting();
- }
- }
-
- private static GridPane makeFourPanelGridPane(Node obj1, Node obj2) {
- var gp = new GridPane();
- var l1 = new Label("Color when volume is 100");
- var l2 = new Label("Color when volume is 0");
- l1.setWrapText(true);
- l2.setWrapText(true);
- gp.addColumn(0, l1, l2);
- gp.addColumn(1, obj1, obj2);
- return gp;
- }
-
- @Override
- public Collection getDevices() {
- return sndCtrl.getDevices();
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/MqttSettingsDialog.java b/src/main/java/com/getpcpanel/ui/MqttSettingsDialog.java
deleted file mode 100644
index a45496e6..00000000
--- a/src/main/java/com/getpcpanel/ui/MqttSettingsDialog.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.getpcpanel.ui;
-
-import static com.getpcpanel.profile.MqttSettings.DEFAULT_MQTT_PORT;
-
-import javax.annotation.Nonnull;
-
-import org.apache.commons.lang3.math.NumberUtils;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.mqtt.MqttDeviceService;
-import com.getpcpanel.profile.MqttSettings;
-import com.getpcpanel.profile.Save;
-import com.getpcpanel.spring.Prototype;
-
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.Alert;
-import javafx.scene.control.ButtonType;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.TextField;
-import lombok.RequiredArgsConstructor;
-
-@Component
-@Prototype
-@RequiredArgsConstructor
-public class MqttSettingsDialog {
- private final MqttDeviceService mqttDeviceService;
- @FXML private CheckBox enabled;
- @FXML private TextField host;
- @FXML private TextField port;
- @FXML private TextField username;
- @FXML private TextField password;
- @FXML private CheckBox secure;
- @FXML private TextField baseTopic;
- @FXML private CheckBox enableHomeAssistantDiscovery;
- @FXML private TextField homeAssistantBaseTopic;
- @FXML private CheckBox homeAssistantAvailability;
-
- public void save(Save save) {
- save.setMqtt(new MqttSettings(
- enabled.isSelected(),
- host.getText(),
- NumberUtils.toInt(port.getText(), DEFAULT_MQTT_PORT),
- username.getText(),
- password.getText(),
- secure.isSelected(),
- baseTopic.getText(),
- new MqttSettings.HomeAssistantSettings(enableHomeAssistantDiscovery.isSelected(), homeAssistantBaseTopic.getText(), homeAssistantAvailability.isSelected())
- ));
- }
-
- public void populate(Save save) {
- if (save.getMqtt() != null) {
- populate(save.getMqtt());
- } else {
- populate(MqttSettings.DEFAULT);
- }
- }
-
- private void populate(@Nonnull MqttSettings settings) {
- enabled.setSelected(settings.enabled());
- host.setText(settings.host());
- port.setText(settings.port().toString());
- username.setText(settings.username());
- password.setText(settings.password());
- secure.setSelected(settings.secure());
- baseTopic.setText(settings.baseTopic());
-
- enableHomeAssistantDiscovery.setSelected(settings.homeAssistant().enableDiscovery());
- homeAssistantBaseTopic.setText(settings.homeAssistant().baseTopic());
- homeAssistantAvailability.setSelected(settings.homeAssistant().availability());
- }
-
- public void clearCurrentTopics(ActionEvent actionEvent) {
- if (!mqttDeviceService.clear()) {
- new Alert(Alert.AlertType.WARNING, "You must be connected to clear the mqtt broker", ButtonType.OK).show();
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/OSCSettingsDialog.java b/src/main/java/com/getpcpanel/ui/OSCSettingsDialog.java
deleted file mode 100644
index 8644e84e..00000000
--- a/src/main/java/com/getpcpanel/ui/OSCSettingsDialog.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.util.List;
-
-import org.apache.commons.lang3.math.NumberUtils;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.profile.OSCConnectionInfo;
-import com.getpcpanel.profile.Save;
-import com.getpcpanel.spring.Prototype;
-
-import javafx.fxml.FXML;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.control.TextField;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.VBox;
-import lombok.RequiredArgsConstructor;
-import one.util.streamex.StreamEx;
-
-@Component
-@Prototype
-@RequiredArgsConstructor
-public class OSCSettingsDialog {
- @FXML private VBox connectHostPorts;
- @FXML private TextField port;
-
- public void addConnectHostPort(MouseEvent ignored) {
- add("localhost", 8000);
- }
-
- private void add(String host, int port) {
- var target = new HBox();
- target.setAlignment(Pos.CENTER_LEFT);
- var hostLabel = new Label("Host");
- var hostField = new TextField(host);
- var portLabel = new Label("Port");
- var portField = new TextField(String.valueOf(port));
- var deleteBtn = new Button("X");
-
- target.getChildren().addAll(hostLabel, hostField, portLabel, portField, deleteBtn);
- HBox.setMargin(hostField, new Insets(0, 15, 0, 5));
- HBox.setMargin(portLabel, new Insets(0, 5, 0, 5));
- connectHostPorts.getChildren().add(target);
-
- deleteBtn.setOnMouseClicked(e -> connectHostPorts.getChildren().remove(target));
- }
-
- public List getConnections() {
- return StreamEx.of(connectHostPorts.getChildren())
- .map(node -> ((HBox) node).getChildren())
- .mapToEntry(c -> ((TextField) c.get(1)).getText(), c -> ((TextField) c.get(3)).getText())
- .mapValues(val -> NumberUtils.toInt(val, -1))
- .filterValues(val -> val != -1)
- .mapKeyValue(OSCConnectionInfo::new)
- .toList();
- }
-
- private void setConnections(Integer port, List oscConnections) {
- if (port != null) {
- this.port.setText(String.valueOf(port));
- }
- if (oscConnections != null) {
- oscConnections.forEach(c -> add(c.host(), c.port()));
- }
- }
-
- public Integer getListenPort() {
- var thePort = NumberUtils.toInt(port.getText(), -1);
- return thePort == -1 ? null : thePort;
- }
-
- public void save(Save save) {
- save.setOscListenPort(getListenPort());
- save.setOscConnections(getConnections());
- }
-
- public void populate(Save save) {
- setConnections(save.getOscListenPort(), save.getOscConnections());
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/Overlay.java b/src/main/java/com/getpcpanel/ui/Overlay.java
deleted file mode 100644
index 5c43baf7..00000000
--- a/src/main/java/com/getpcpanel/ui/Overlay.java
+++ /dev/null
@@ -1,201 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.awt.Toolkit;
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-
-import org.springframework.context.event.EventListener;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.Commands;
-import com.getpcpanel.commands.IconService;
-import com.getpcpanel.commands.PCPanelControlEvent;
-import com.getpcpanel.commands.command.ButtonAction;
-import com.getpcpanel.commands.command.DialAction;
-import com.getpcpanel.profile.SaveService;
-import com.getpcpanel.profile.SaveService.SaveEvent;
-import com.getpcpanel.spring.ConditionalOnWindows;
-import com.getpcpanel.util.Debouncer;
-
-import jakarta.annotation.Nonnull;
-import jakarta.annotation.PostConstruct;
-import javafx.application.Platform;
-import javafx.fxml.FXML;
-import javafx.scene.Node;
-import javafx.scene.Scene;
-import javafx.scene.control.Label;
-import javafx.scene.control.ProgressBar;
-import javafx.scene.image.Image;
-import javafx.scene.image.ImageView;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
-import javafx.scene.paint.Color;
-import javafx.stage.Popup;
-import javafx.stage.Stage;
-import javafx.stage.StageStyle;
-import lombok.RequiredArgsConstructor;
-import one.util.streamex.StreamEx;
-
-@Component
-@ConditionalOnWindows
-@RequiredArgsConstructor
-public class Overlay extends Popup {
- private final FxHelper fxHelper;
- private final SaveService save;
- private final IconService iconService;
- private final Debouncer debouncer;
-
- @FXML private Pane panel;
- @FXML private HBox volumePanel;
- @FXML private HBox textPanel;
- @FXML private ProgressBar volume;
- @FXML private Label volumeText;
- @FXML private Label text;
- @FXML private ImageView icon;
- private Stage stage;
-
- @PostConstruct
- public void doInit() {
- Platform.runLater(() -> prepareStage(new Stage(StageStyle.UTILITY)));
- }
-
- public void prepareStage(Stage helperStage) {
- stage = helperStage;
- stage.setOpacity(0);
- stage.setScene(new Scene(new Pane(), 1, 1));
- helperStage.show();
- var loader = fxHelper.getLoader(getClass().getResource("/assets/Overlay.fxml"));
-
- loader.setController(this);
- HBox panel;
- try {
- panel = loader.load();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- getContent().addAll(panel);
- updateSaveValues();
- }
-
- @EventListener(SaveEvent.class)
- public void updateSaveValues() {
- updateStyle();
- determinePosition();
- }
-
- private void determinePosition() {
- var window = Toolkit.getDefaultToolkit().getScreenSize();
- var x = window.getWidth();
- var y = window.getHeight();
- var width = getWidth();
- var height = getHeight();
-
- switch (save.get().getOverlayPosition()) {
- case topLeft, topMiddle, topRight -> setY(save.get().getOverlayPadding());
- case middleLeft, middleMiddle, middleRight -> setY(y / 2 - height / 2);
- case bottomLeft, bottomMiddle, bottomRight -> setY(y - getHeight() - save.get().getOverlayPadding());
- }
- switch (save.get().getOverlayPosition()) {
- case topLeft, middleLeft, bottomLeft -> setX(save.get().getOverlayPadding());
- case topMiddle, middleMiddle, bottomMiddle -> setX(x / 2 - width / 2);
- case topRight, middleRight, bottomRight -> setX(x - width - save.get().getOverlayPadding());
- }
- }
-
- @EventListener(SaveEvent.class)
- public void updateStyle() {
- var save = this.save.get();
- var style = "-fx-background-color: " + save.getOverlayBackgroundColor() + ";";
- if (save.getOverlayWindowCornerRounding() > 0)
- style += "-fx-background-radius: " + save.getOverlayWindowCornerRounding() + "px;";
- panel.setStyle(style);
- volumeText.setTextFill(Color.web(save.getOverlayTextColor()));
- text.setTextFill(Color.web(save.getOverlayTextColor()));
- }
-
- private void initAfterShow() {
- determinePosition();
- var save = this.save.get();
- if (save.getOverlayBarCornerRounding() > 0) {
- var barStyle = "-fx-background-radius: " + save.getOverlayBarCornerRounding() + "px;";
- volume.setStyle(barStyle);
- volume.lookup(".track").setStyle(barStyle + "-fx-background-color: " + save.getOverlayBarBackgroundColor() + ";");
- volume.lookup(".bar").setStyle(barStyle + "-fx-background-color: " + save.getOverlayBarColor() + ";");
- }
- volume.setPrefHeight(save.getOverlayBarHeight());
- }
-
- @EventListener
- public void handleControl(PCPanelControlEvent event) {
- if (event.initial()) {
- return;
- }
- showDebounced(() -> determineIconImage(event), command -> {
- if (event.vol() != null) {
- var value = save.get().isOverlayUseLog() ? event.vol().getValue(null, 0, 255) : event.vol().value();
- setVisible(volumePanel);
- volume.setProgress(value / 255f);
-
- if (save.get().isOverlayShowNumber()) {
- volumeText.setText(String.valueOf(Math.round(value / 2.55f)));
- volumeText.setVisible(true);
- volumeText.setManaged(true);
- } else {
- volumeText.setVisible(false);
- volumeText.setManaged(false);
- }
- return true;
- } else {
- setVisible(textPanel);
- var firstButtonAction = StreamEx.of(Commands.cmds(command)).select(ButtonAction.class).findFirst();
- if (firstButtonAction.isPresent()) {
- text.setText(firstButtonAction.get().getOverlayText());
- return true;
- }
- return false;
- }
- });
- }
-
- private void showDebounced(Supplier pre, Predicate pred) {
- if (!save.get().isOverlayEnabled()) {
- return;
- }
- Platform.runLater(() -> {
- var cai = pre.get();
- if (hasOverlay(cai.command) && pred.test(cai.command)) {
- icon.setImage(cai.icon);
- show(stage);
- initAfterShow();
- }
- });
- debouncer.debounce(this, () -> Platform.runLater(this::hide), 2, TimeUnit.SECONDS);
- }
-
- private boolean hasOverlay(Commands commands) {
- return Commands.hasCommands(commands) &&
- StreamEx.of(commands.getCommands()).anyMatch(command -> command instanceof DialAction da && da.hasOverlay()
- || command instanceof ButtonAction ba && ba.hasOverlay());
- }
-
- @Nonnull
- private CommandAndIcon determineIconImage(PCPanelControlEvent event) {
- return save.getProfile(event.serialNum()).map(profile -> {
- var data = event.cmd();
- var setting = event.vol() == null ? null : profile.getKnobSettings(event.knob());
- return new CommandAndIcon(data, iconService.getImageFrom(data, setting));
- }).orElse(CommandAndIcon.DEFAULT);
- }
-
- @SuppressWarnings("ObjectEquality")
- private void setVisible(Node param) {
- List.of(volumePanel, textPanel).forEach(node -> node.setVisible(node == param));
- }
-
- private record CommandAndIcon(Commands command, Image icon) {
- static final CommandAndIcon DEFAULT = new CommandAndIcon(Commands.EMPTY, IconService.DEFAULT);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/OverlayPosition.java b/src/main/java/com/getpcpanel/ui/OverlayPosition.java
deleted file mode 100644
index 4cc40965..00000000
--- a/src/main/java/com/getpcpanel/ui/OverlayPosition.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.getpcpanel.ui;
-
-public enum OverlayPosition {
- topLeft, topMiddle, topRight,
- middleLeft, middleMiddle, middleRight,
- bottomLeft, bottomMiddle, bottomRight
-}
diff --git a/src/main/java/com/getpcpanel/ui/PickProcessesController.java b/src/main/java/com/getpcpanel/ui/PickProcessesController.java
deleted file mode 100644
index 44d8b2a0..00000000
--- a/src/main/java/com/getpcpanel/ui/PickProcessesController.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Optional;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.util.Images;
-
-import javafx.beans.Observable;
-import javafx.beans.binding.Bindings;
-import javafx.beans.property.SimpleLongProperty;
-import javafx.collections.ListChangeListener;
-import javafx.fxml.FXML;
-import javafx.scene.control.Button;
-import javafx.scene.control.TextField;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.VBox;
-import javafx.stage.Stage;
-import lombok.RequiredArgsConstructor;
-import lombok.Setter;
-import one.util.streamex.StreamEx;
-
-@Component
-@Prototype
-@RequiredArgsConstructor
-public class PickProcessesController {
- public enum PickType {
- file, soundSource, process
- }
-
- private final FxHelper fxHelper;
- @Setter private boolean single;
-
- @FXML private VBox pickRows;
- @Setter private PickType pickType;
-
- public void initialize() {
- ensureLastEmpty();
- }
-
- public List getSelection() {
- return StreamEx.of(pickRows.getChildren()).select(Pane.class).map(pane -> pane.getChildren().get(0)).select(TextField.class).map(TextField::getText).filter(StringUtils::isNotBlank).toList();
- }
-
- public void setSelection(Collection volData) {
- StreamEx.of(volData).map(StringUtils::trimToNull).nonNull().map(this::createProcessRow).forEach(pickRows.getChildren()::add);
- removeEmptyIfNotLast();
-
- if (!single) {
- pickRows.getChildren().add(createProcessRow(""));
- ensureLastEmpty();
- }
- }
-
- public void setDisable(boolean disable) {
- StreamEx.of(pickRows.getChildren()).select(Pane.class).flatCollection(Pane::getChildren).forEach(ctrl -> ctrl.setDisable(disable));
- }
-
- public Observable getObservable() {
- var binding = new SimpleLongProperty();
- pickRows.getChildren().addListener((ListChangeListener.Change> c) -> {
- binding.unbind();
- var values = StreamEx.of(pickRows.getChildren()).select(Pane.class).map(pane -> pane.getChildren().get(0)).select(TextField.class).map(TextField::textProperty).toArray(Observable[]::new);
- binding.bind(Bindings.createLongBinding(System::currentTimeMillis, values));
- });
- return binding;
- }
-
- private void removeEmptyIfNotLast() {
- var toRemove = StreamEx.of(pickRows.getChildren())
- .select(Pane.class)
- .filter(ar -> StringUtils.isBlank(((TextField) ar.getChildren().get(0)).getText()))
- .filter(ar -> !ar.equals(pickRows.getChildren().get(pickRows.getChildren().size() - 1)))
- .toList();
- toRemove.forEach(pickRows.getChildren()::remove);
- }
-
- private void ensureLastEmpty() {
- if (single)
- return;
-
- if (pickRows.getChildren().isEmpty()) {
- pickRows.getChildren().add(createProcessRow(""));
- } else {
- var pane = (Pane) pickRows.getChildren().get(pickRows.getChildren().size() - 1);
- if (!StringUtils.isBlank(((TextField) pane.getChildren().get(0)).getText())) {
- pickRows.getChildren().add(createProcessRow(""));
- }
- }
- }
-
- private Pane createProcessRow(String value) {
- var pane = new HBox();
-
- var textField = new TextField();
- textField.setPromptText("Process");
- textField.setText(value);
-
- var button = new Button("", Images.magnify());
- button.setPrefSize(34, 31);
- button.setOnAction(e -> {
- switch (pickType) {
- case file -> UIHelper.showFilePicker("Application", textField);
- case soundSource -> showAppFinder(true, textField);
- case process -> showAppFinder(false, textField);
- }
- ensureLastEmpty();
- });
- var clear = new Button("", Images.delete());
- clear.setPrefSize(34, 31);
- clear.setOnAction(e -> {
- textField.setText("");
- removeEmptyIfNotLast();
- });
-
- textField.setOnKeyReleased(e -> ensureLastEmpty());
- textField.focusedProperty().addListener((o, oldPropertyValue, newPropertyValue) -> {
- if (!newPropertyValue) {
- removeEmptyIfNotLast();
- }
- });
-
- HBox.setHgrow(textField, Priority.ALWAYS);
- pane.getChildren().add(textField);
- pane.getChildren().add(button);
- pane.getChildren().add(clear);
- return pane;
- }
-
- private void showAppFinder(boolean sound, TextField textField) {
- var afd = fxHelper.buildAppFinderDialog(null, sound);
- var afdStage = new Stage();
- afd.start(afdStage, true);
-
- Optional.ofNullable(StringUtils.trimToNull(afd.getProcessName())).ifPresent(textField::setText);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/ProLightingDialog.java b/src/main/java/com/getpcpanel/ui/ProLightingDialog.java
deleted file mode 100644
index c3788b13..00000000
--- a/src/main/java/com/getpcpanel/ui/ProLightingDialog.java
+++ /dev/null
@@ -1,550 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.util.Collection;
-import java.util.Objects;
-
-import javax.annotation.Nonnull;
-
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.cpp.AudioDevice;
-import com.getpcpanel.cpp.ISndCtrl;
-import com.getpcpanel.device.Device;
-import com.getpcpanel.profile.LightingConfig;
-import com.getpcpanel.profile.LightingConfig.LightingMode;
-import com.getpcpanel.profile.SaveService;
-import com.getpcpanel.profile.SingleKnobLightingConfig.SINGLE_KNOB_MODE;
-import com.getpcpanel.profile.SingleLogoLightingConfig.SINGLE_LOGO_MODE;
-import com.getpcpanel.profile.SingleSliderLabelLightingConfig.SINGLE_SLIDER_LABEL_MODE;
-import com.getpcpanel.profile.SingleSliderLightingConfig.SINGLE_SLIDER_MODE;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.UIInitializer.SingleParamInitializer;
-import com.getpcpanel.ui.colorpicker.ColorDialog;
-import com.getpcpanel.ui.colorpicker.HueSlider;
-import com.getpcpanel.util.Util;
-
-import javafx.application.Application;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.geometry.Side;
-import javafx.scene.Node;
-import javafx.scene.Scene;
-import javafx.scene.control.Button;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.ComboBox;
-import javafx.scene.control.Label;
-import javafx.scene.control.Slider;
-import javafx.scene.control.Tab;
-import javafx.scene.control.TabPane;
-import javafx.scene.control.TabPane.TabClosingPolicy;
-import javafx.scene.image.Image;
-import javafx.scene.layout.GridPane;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Color;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-public class ProLightingDialog extends Application implements UIInitializer>, ILightingDialogMuteOverrideHelper {
- private final SaveService saveService;
- private final ApplicationEventPublisher eventPublisher;
- private final ISndCtrl sndCtrl;
-
- private Stage stage;
- @FXML private TabPane mainPane;
- @FXML private TabPane knobsTabbedPane;
- @FXML private TabPane slidersTabbedPane;
- @FXML private TabPane sliderLabelsTabbedPane;
- @FXML private TabPane logoTabPane;
- @FXML private TabPane fullBodyTabbedPane;
- @FXML private Slider rainbowPhaseShift;
- @FXML private Slider rainbowBrightness;
- @FXML private Slider rainbowSpeed;
- @FXML private CheckBox rainbowReverse;
- private HueSlider waveHue;
- @FXML private Slider waveBrightness;
- @FXML private Slider waveSpeed;
- @FXML private CheckBox waveReverse;
- @FXML private CheckBox waveBounce;
- private HueSlider breathHue;
- @FXML private Slider breathBrightness;
- @FXML private Slider breathSpeed;
- @FXML private VBox wavebox;
- @FXML private VBox breathbox;
- @FXML private Button applyToAllButton;
- private ColorDialog allKnobColor;
- private static final int NUM_KNOBS = 5;
- private static final int NUM_SLIDERS = 4;
- private final TabPane[] knobSingleTabPane = new TabPane[NUM_KNOBS];
- private final TabPane[] sliderSingleTabPane = new TabPane[NUM_SLIDERS];
- private final TabPane[] sliderLabelSingleTabPane = new TabPane[NUM_SLIDERS];
- private final ColorDialog[] knobStaticCDs = new ColorDialog[NUM_KNOBS];
- private final ColorDialog[] knobVolumeGradientCD1 = new ColorDialog[NUM_KNOBS];
- private final ColorDialog[] knobVolumeGradientCD2 = new ColorDialog[NUM_KNOBS];
- @Getter private final CheckBox[] muteOverrideCheckboxesKnobs = new CheckBox[NUM_KNOBS];
- @SuppressWarnings("unchecked") @Getter private final ComboBox[] muteOverrideComboBoxesKnobs = new ComboBox[NUM_KNOBS];
- @Getter private final ColorDialog[] muteOverrideColorsKnobs = new ColorDialog[NUM_KNOBS];
- @Getter private final CheckBox[] muteOverrideCheckboxesSliders = new CheckBox[NUM_SLIDERS];
- @SuppressWarnings("unchecked") @Getter private final ComboBox[] muteOverrideComboBoxesSliders = new ComboBox[NUM_SLIDERS];
- @Getter private final ColorDialog[] muteOverrideColorsSliders = new ColorDialog[NUM_SLIDERS];
- @Getter private final CheckBox[] muteOverrideCheckboxesSliderLabels = new CheckBox[NUM_SLIDERS];
- @SuppressWarnings("unchecked") @Getter private final ComboBox[] muteOverrideComboBoxesSliderLabels = new ComboBox[NUM_SLIDERS];
- @Getter private final ColorDialog[] muteOverrideColorsSliderLabels = new ColorDialog[NUM_SLIDERS];
- private final ColorDialog[] sliderStaticCDs = new ColorDialog[NUM_SLIDERS];
- private final ColorDialog[] sliderStaticGradientTopCD = new ColorDialog[NUM_SLIDERS];
- private final ColorDialog[] sliderStaticGradientBottomCD = new ColorDialog[NUM_SLIDERS];
- private final ColorDialog[] sliderVolumeGradientCD1 = new ColorDialog[NUM_SLIDERS];
- private final ColorDialog[] sliderVolumeGradientCD2 = new ColorDialog[NUM_SLIDERS];
- private final ColorDialog[] sliderLabelStaticCDs = new ColorDialog[NUM_SLIDERS];
- private ColorDialog logoStaticColor;
- @FXML private Slider logoRainbowSpeed;
- @FXML private Slider logoRainbowBrightness;
- private HueSlider logoBreathHue;
- @FXML private VBox logoBreathBox;
- @FXML private Slider logoBreathBrightness;
- @FXML private Slider logoBreathSpeed;
- private Device device;
- private LightingConfig lightingConfig;
- private boolean pressedOk;
- @FXML private Pane root;
-
- @Override
- public void initUI(@Nonnull SingleParamInitializer args) {
- device = args.param();
- lightingConfig = device.getSavedLightingConfig().deepCopy();
- setDeviceLighting();
- postInit();
- }
-
- private void setDeviceLighting() {
- device.setLighting(lightingConfig.deepCopy(), true);
- }
-
- public ProLightingDialog select(int button) {
- if (button > 4) {
- button -= 5;
- mainPane.getSelectionModel().select(2);
- slidersTabbedPane.getSelectionModel().select(button);
- } else {
- mainPane.getSelectionModel().select(1);
- knobsTabbedPane.getSelectionModel().select(button);
- }
-
- return this;
- }
-
- @Override
- public void start(Stage stage) {
- this.stage = stage;
- UIHelper.closeOnEscape(stage);
- var scene = new Scene(root);
- scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/assets/dark_theme.css")).toExternalForm());
- stage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResource("/assets/256x256.png")).toExternalForm()));
- stage.setOnHiding(e -> {
- if (!pressedOk) {
- device.setLighting(device.getSavedLightingConfig(), true);
- }
- eventPublisher.publishEvent(LightingChangedToDefaultEvent.INSTANCE);
- });
- stage.initModality(Modality.APPLICATION_MODAL);
- stage.initOwner(HomePage.stage);
- stage.setScene(scene);
- stage.sizeToScene();
- stage.setTitle("Lighting Dialog");
- stage.show();
- }
-
- @FXML
- private void onCancel(ActionEvent event) {
- stage.close();
- }
-
- @FXML
- private void ok(ActionEvent event) {
- log.debug("{} {}", stage.getWidth(), stage.getHeight());
- pressedOk = true;
- device.setSavedLighting(lightingConfig);
- saveService.save();
- stage.close();
- }
-
- @FXML
- private void turnOffLights(ActionEvent event) {
- allKnobColor.setCustomColor(Color.WHITE);
- allKnobColor.setCustomColor(Color.BLACK);
- mainPane.getSelectionModel().select(0);
- fullBodyTabbedPane.getSelectionModel().select(0);
- }
-
- private void postInit() {
- int i;
- for (i = 0; i < NUM_KNOBS; i++) {
- var knob = i + 1;
- var tab = new Tab("Knob " + knob);
- var cd = new ColorDialog(Color.BLACK);
- knobStaticCDs[i] = cd;
- knobVolumeGradientCD1[i] = new ColorDialog();
- knobVolumeGradientCD2[i] = new ColorDialog();
- var volGradientGP = makeFourPanelGridPane("Color when volume is 100", "Color when volume is 0", knobVolumeGradientCD2[i], knobVolumeGradientCD1[i]);
- var vbox = new VBox(volGradientGP);
- var staticTab = new Tab("Static", cd);
- var volGradient = new Tab("Volume Gradient", vbox);
- var singleKnobTabPane = new TabPane(staticTab, volGradient);
- knobSingleTabPane[i] = singleKnobTabPane;
- Util.adjustTabs(singleKnobTabPane, 140, 30);
- singleKnobTabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
- singleKnobTabPane.setSide(Side.LEFT);
- tab.setContent(tabWithMuteOverride(OverrideTargetType.KNOB, i, singleKnobTabPane));
- knobsTabbedPane.getTabs().add(tab);
- }
- for (i = 0; i < NUM_SLIDERS; i++) {
- var tab = new Tab("Slider " + (i + 1));
- var cd = new ColorDialog(Color.BLACK);
- sliderStaticCDs[i] = cd;
- sliderStaticGradientTopCD[i] = new ColorDialog();
- sliderStaticGradientBottomCD[i] = new ColorDialog();
- var staticGradientGP = makeFourPanelGridPane("Top Color", "Bottom Color", sliderStaticGradientTopCD[i], sliderStaticGradientBottomCD[i]);
- sliderVolumeGradientCD1[i] = new ColorDialog();
- sliderVolumeGradientCD2[i] = new ColorDialog();
- var volGradientGP = makeFourPanelGridPane("Color when volume is 100", "Color when volume is 0",
- sliderVolumeGradientCD2[i], sliderVolumeGradientCD1[i]);
- var staticTab = new Tab("Static", cd);
- var staticGradient = new Tab("Static Gradient", staticGradientGP);
- var volGradient = new Tab("Volume Gradient", volGradientGP);
- var singleSliderTabPane = new TabPane(staticTab, staticGradient, volGradient);
- sliderSingleTabPane[i] = singleSliderTabPane;
- Util.adjustTabs(singleSliderTabPane, 140, 30);
- singleSliderTabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
- singleSliderTabPane.setSide(Side.LEFT);
- tab.setContent(tabWithMuteOverride(OverrideTargetType.SLIDER, i, singleSliderTabPane));
- slidersTabbedPane.getTabs().add(tab);
- }
- for (i = 0; i < NUM_SLIDERS; i++) {
- var tab = new Tab("Slider " + (i + 1));
- sliderLabelStaticCDs[i] = new ColorDialog();
- var staticTab = new Tab("Static", sliderLabelStaticCDs[i]);
- var singleSliderLabelTabPane = new TabPane(staticTab);
- sliderLabelSingleTabPane[i] = singleSliderLabelTabPane;
- Util.adjustTabs(singleSliderLabelTabPane, 140, 30);
- singleSliderLabelTabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
- singleSliderLabelTabPane.setSide(Side.LEFT);
- tab.setContent(tabWithMuteOverride(OverrideTargetType.SLIDER_LABEL, i, singleSliderLabelTabPane));
- sliderLabelsTabbedPane.getTabs().add(tab);
- }
- Util.adjustTabs(fullBodyTabbedPane, 120, 30);
- Util.adjustTabs(logoTabPane, 120, 30);
- logoStaticColor = new ColorDialog();
- logoTabPane.getTabs().get(0).setContent(logoStaticColor);
- allKnobColor = new ColorDialog();
- fullBodyTabbedPane.getTabs().get(0).setContent(allKnobColor);
- var allSliders = new Slider[] {
- rainbowPhaseShift, rainbowBrightness, rainbowSpeed,
- waveBrightness, waveSpeed,
- breathBrightness, breathSpeed,
- logoRainbowBrightness, logoRainbowSpeed,
- logoBreathBrightness,
- logoBreathSpeed };
- var allCheckBoxes = new CheckBox[] { rainbowReverse,
- waveReverse, waveBounce };
- waveHue = new HueSlider();
- wavebox.getChildren().add(1, waveHue);
- breathHue = new HueSlider();
- breathbox.getChildren().add(1, breathHue);
- logoBreathHue = new HueSlider();
- logoBreathBox.getChildren().add(1, logoBreathHue);
- applyToAllButton.setOnAction(e -> {
- if (mainPane.getSelectionModel().getSelectedIndex() == 1) {
- var knobIndex = knobsTabbedPane.getSelectionModel().getSelectedIndex();
- for (var idx = 0; idx < lightingConfig.getKnobConfigs().length; idx++) {
- if (idx != knobIndex)
- lightingConfig.getKnobConfigs()[idx].set(lightingConfig.getKnobConfigs()[knobIndex]);
- }
- } else if (mainPane.getSelectionModel().getSelectedIndex() == 2) {
- var index = slidersTabbedPane.getSelectionModel().getSelectedIndex();
- for (var idx = 0; idx < lightingConfig.getSliderConfigs().length; idx++) {
- if (idx != index)
- lightingConfig.getSliderConfigs()[idx].set(lightingConfig.getSliderConfigs()[index]);
- }
- } else if (mainPane.getSelectionModel().getSelectedIndex() == 3) {
- var index = sliderLabelsTabbedPane.getSelectionModel().getSelectedIndex();
- for (var idx = 0; idx < lightingConfig.getSliderLabelConfigs().length; idx++) {
- if (idx != index)
- lightingConfig.getSliderLabelConfigs()[idx].set(lightingConfig.getSliderLabelConfigs()[index]);
- }
- }
- initFields();
- });
- initFields();
- initListeners(allSliders, allCheckBoxes);
- }
-
- private void initFields() {
- var mode = lightingConfig.getLightingMode();
- if (mode == LightingMode.ALL_COLOR) {
- mainPane.getSelectionModel().select(0);
- fullBodyTabbedPane.getSelectionModel().select(0);
- allKnobColor.setCustomColor(Color.web(lightingConfig.getAllColor()));
- } else if (mode == LightingMode.ALL_RAINBOW) {
- mainPane.getSelectionModel().select(0);
- fullBodyTabbedPane.getSelectionModel().select(1);
- rainbowPhaseShift.setValue(lightingConfig.getRainbowPhaseShift() & 0xFF);
- rainbowBrightness.setValue(lightingConfig.getRainbowBrightness() & 0xFF);
- rainbowSpeed.setValue(lightingConfig.getRainbowSpeed() & 0xFF);
- rainbowReverse.setSelected(lightingConfig.getRainbowReverse() == 1);
- } else if (mode == LightingMode.ALL_WAVE) {
- mainPane.getSelectionModel().select(0);
- fullBodyTabbedPane.getSelectionModel().select(2);
- waveHue.setHue(lightingConfig.getWaveHue() & 0xFF);
- waveBrightness.setValue(lightingConfig.getWaveBrightness() & 0xFF);
- waveSpeed.setValue(lightingConfig.getWaveSpeed() & 0xFF);
- waveReverse.setSelected(lightingConfig.getWaveReverse() == 1);
- waveBounce.setSelected(lightingConfig.getWaveBounce() == 1);
- } else if (mode == LightingMode.ALL_BREATH) {
- mainPane.getSelectionModel().select(0);
- fullBodyTabbedPane.getSelectionModel().select(3);
- breathHue.setHue(lightingConfig.getBreathHue() & 0xFF);
- breathBrightness.setValue(lightingConfig.getBreathBrightness() & 0xFF);
- breathSpeed.setValue(lightingConfig.getBreathSpeed() & 0xFF);
- } else if (mode == LightingMode.CUSTOM) {
- if (mainPane.getSelectionModel().getSelectedIndex() == 0)
- mainPane.getSelectionModel().select(1);
- var knobConfigs = lightingConfig.getKnobConfigs();
- var sliderLabelConfigs = lightingConfig.getSliderLabelConfigs();
- var sliderConfigs = lightingConfig.getSliderConfigs();
- var logoConfig = lightingConfig.getLogoConfig();
- int i;
- for (i = 0; i < NUM_KNOBS; i++) {
- var knobConfig = knobConfigs[i];
- if (knobConfig.getMode() == SINGLE_KNOB_MODE.STATIC) {
- knobSingleTabPane[i].getSelectionModel().select(0);
- knobStaticCDs[i].setCustomColor(Color.web(knobConfig.getColor1()));
- } else if (knobConfig.getMode() == SINGLE_KNOB_MODE.VOLUME_GRADIENT) {
- knobSingleTabPane[i].getSelectionModel().select(1);
- knobVolumeGradientCD1[i].setCustomColor(Color.web(knobConfig.getColor1()));
- knobVolumeGradientCD2[i].setCustomColor(Color.web(knobConfig.getColor2()));
- }
- setOverride(OverrideTargetType.KNOB, i, knobConfig.getMuteOverrideDeviceOrFollow(), knobConfig.getMuteOverrideColor());
- }
- for (i = 0; i < NUM_SLIDERS; i++) {
- var sliderLabelConfig = sliderLabelConfigs[i];
- if (sliderLabelConfig.getMode() == SINGLE_SLIDER_LABEL_MODE.STATIC) {
- sliderLabelSingleTabPane[i].getSelectionModel().select(0);
- sliderLabelStaticCDs[i].setCustomColor(Color.web(sliderLabelConfig.getColor()));
- }
- setOverride(OverrideTargetType.SLIDER_LABEL, i, sliderLabelConfig.getMuteOverrideDeviceOrFollow(), sliderLabelConfig.getMuteOverrideColor());
- }
- for (i = 0; i < NUM_SLIDERS; i++) {
- var sliderConfig = sliderConfigs[i];
- if (sliderConfig.getMode() == SINGLE_SLIDER_MODE.STATIC) {
- sliderSingleTabPane[i].getSelectionModel().select(0);
- sliderStaticCDs[i].setCustomColor(Color.web(sliderConfig.getColor1()));
- } else if (sliderConfig.getMode() == SINGLE_SLIDER_MODE.STATIC_GRADIENT) {
- sliderSingleTabPane[i].getSelectionModel().select(1);
- sliderStaticGradientBottomCD[i].setCustomColor(Color.web(sliderConfig.getColor1()));
- sliderStaticGradientTopCD[i].setCustomColor(Color.web(sliderConfig.getColor2()));
- } else if (sliderConfig.getMode() == SINGLE_SLIDER_MODE.VOLUME_GRADIENT) {
- sliderSingleTabPane[i].getSelectionModel().select(2);
- sliderVolumeGradientCD1[i].setCustomColor(Color.web(sliderConfig.getColor1()));
- sliderVolumeGradientCD2[i].setCustomColor(Color.web(sliderConfig.getColor2()));
- }
- setOverride(OverrideTargetType.SLIDER, i, sliderConfig.getMuteOverrideDeviceOrFollow(), sliderConfig.getMuteOverrideColor());
- }
- if (logoConfig.getMode() == SINGLE_LOGO_MODE.STATIC) {
- logoTabPane.getSelectionModel().select(0);
- logoStaticColor.setCustomColor(Color.web(logoConfig.getColor()));
- } else if (logoConfig.getMode() == SINGLE_LOGO_MODE.RAINBOW) {
- logoTabPane.getSelectionModel().select(1);
- logoRainbowBrightness.setValue(logoConfig.getBrightness() & 0xFF);
- logoRainbowSpeed.setValue(logoConfig.getSpeed() & 0xFF);
- } else if (logoConfig.getMode() == SINGLE_LOGO_MODE.BREATH) {
- logoTabPane.getSelectionModel().select(2);
- logoBreathHue.setHue(logoConfig.getHue() & 0xFF);
- logoBreathBrightness.setValue(logoConfig.getBrightness() & 0xFF);
- logoBreathSpeed.setValue(logoConfig.getSpeed() & 0xFF);
- }
- }
- updateApplyToAllButton();
- }
-
- private void addListener(ColorDialog[]... xs) {
- for (var x : xs) {
- for (var cd : x) {
- cd.customColorProperty().addListener((a, bb, c) -> updateColors());
- }
- }
- }
-
- private void addListener(TabPane[]... xs) {
- for (var x : xs) {
- for (var cd : x) {
- cd.getSelectionModel().selectedItemProperty().addListener((a, bb, c) -> updateColors());
- }
- }
- }
-
- private void addListener(TabPane... tbs) {
- for (var tb : tbs) {
- tb.getSelectionModel().selectedItemProperty().addListener((a, bb, c) -> updateColors());
- }
- }
-
- private void addListener(CheckBox[]... checkss) {
- for (var checks : checkss) {
- for (var check : checks) {
- check.setOnAction(a -> updateColors());
- }
- }
- }
-
- private void addListener(ComboBox>[]... boxess) {
- for (var boxes : boxess) {
- for (var box : boxes) {
- box.setOnAction(a -> updateColors());
- }
- }
- }
-
- private void initListeners(Slider[] allSliders, CheckBox[] allCheckBoxes) {
- addListener(knobStaticCDs, knobVolumeGradientCD1, allOverrideColors(), knobVolumeGradientCD2,
- sliderStaticCDs, sliderStaticGradientBottomCD, sliderStaticGradientTopCD, sliderVolumeGradientCD1, sliderVolumeGradientCD2,
- sliderLabelStaticCDs);
- addListener(knobSingleTabPane, sliderLabelSingleTabPane, sliderSingleTabPane);
- addListener(allOverrideCheckboxes());
- addListener(allOverrideComboBoxes());
- logoStaticColor.customColorProperty().addListener((a, b, c) -> updateColors());
- allKnobColor.customColorProperty().addListener((observable, oldValue, newValue) -> {
- for (var cd : knobStaticCDs) {
- cd.setCustomColor(newValue);
- }
- updateColors();
- });
- addListener(logoTabPane, fullBodyTabbedPane);
- for (var slider : allSliders) {
- slider.valueProperty().addListener((observable, oldValue, newValue) -> updateColors());
- }
- for (var cb : allCheckBoxes) {
- cb.selectedProperty().addListener((observable, oldValue, newValue) -> updateColors());
- }
- waveHue.getHueProperty().addListener((observable, oldValue, newValue) -> updateColors());
- breathHue.getHueProperty().addListener((observable, oldValue, newValue) -> updateColors());
- logoBreathHue.getHueProperty().addListener((observable, oldValue, newValue) -> updateColors());
- mainPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
- updateColors();
- updateApplyToAllButton();
- });
- }
-
- private void updateApplyToAllButton() {
- if (mainPane.getSelectionModel().getSelectedIndex() == 0 || mainPane.getSelectionModel().getSelectedIndex() == 4) {
- applyToAllButton.setVisible(false);
- return;
- }
- applyToAllButton.setVisible(true);
- if (mainPane.getSelectionModel().getSelectedIndex() == 1) {
- applyToAllButton.setText("Apply To All Knobs");
- } else if (mainPane.getSelectionModel().getSelectedIndex() == 2) {
- applyToAllButton.setText("Apply To All Sliders");
- } else if (mainPane.getSelectionModel().getSelectedIndex() == 3) {
- applyToAllButton.setText("Apply To All Slider Labels");
- }
- }
-
- @SuppressWarnings("NumericCastThatLosesPrecision")
- private void updateColors() {
- if (mainPane.getSelectionModel().getSelectedIndex() == 0) {
- if (fullBodyTabbedPane.getSelectionModel().getSelectedIndex() == 0) {
- lightingConfig = LightingConfig.createAllColor(allKnobColor.getCustomColor());
- setDeviceLighting();
- } else if (fullBodyTabbedPane.getSelectionModel().getSelectedIndex() == 1) {
- lightingConfig = LightingConfig.createRainbowAnimation((byte) (int) rainbowPhaseShift.getValue(), (byte) (int) rainbowBrightness.getValue(),
- (byte) (int) rainbowSpeed.getValue(), rainbowReverse.isSelected());
- setDeviceLighting();
- } else if (fullBodyTabbedPane.getSelectionModel().getSelectedIndex() == 2) {
- lightingConfig = LightingConfig.createWaveAnimation((byte) waveHue.getHue(), (byte) (int) waveBrightness.getValue(), (byte) (int) waveSpeed.getValue(),
- waveReverse.isSelected(), waveBounce.isSelected());
- setDeviceLighting();
- } else if (fullBodyTabbedPane.getSelectionModel().getSelectedIndex() == 3) {
- lightingConfig = LightingConfig.createBreathAnimation((byte) breathHue.getHue(), (byte) (int) breathBrightness.getValue(), (byte) (int) breathSpeed.getValue());
- setDeviceLighting();
- }
- } else {
- lightingConfig = new LightingConfig(NUM_KNOBS, NUM_SLIDERS);
- lightingConfig.setLightingMode(LightingMode.CUSTOM);
- for (var knob = 0; knob < NUM_KNOBS; knob++) {
- var knobConfig = lightingConfig.getKnobConfigs()[knob];
- if (knobSingleTabPane[knob].getSelectionModel().getSelectedIndex() == 0) {
- knobConfig.setMode(SINGLE_KNOB_MODE.STATIC);
- knobConfig.setColor1FromColor(knobStaticCDs[knob].getCustomColor());
- } else if (knobSingleTabPane[knob].getSelectionModel().getSelectedIndex() == 1) {
- knobConfig.setMode(SINGLE_KNOB_MODE.VOLUME_GRADIENT);
- knobConfig.setColor1FromColor(knobVolumeGradientCD1[knob].getCustomColor());
- knobConfig.setColor2FromColor(knobVolumeGradientCD2[knob].getCustomColor());
- }
- setOverrideSetting(OverrideTargetType.KNOB, knob, knobConfig::setMuteOverrideDeviceOrFollow, knobConfig::setMuteOverrideColorFromColor);
- }
- int slider;
- for (slider = 0; slider < NUM_SLIDERS; slider++) {
- var sliderLabelConfig = lightingConfig.getSliderLabelConfigs()[slider];
- if (sliderLabelSingleTabPane[slider].getSelectionModel().getSelectedIndex() == 0) {
- sliderLabelConfig.setMode(SINGLE_SLIDER_LABEL_MODE.STATIC);
- sliderLabelConfig.setColorFromColor(sliderLabelStaticCDs[slider].getCustomColor());
- }
- setOverrideSetting(OverrideTargetType.SLIDER_LABEL, slider, sliderLabelConfig::setMuteOverrideDeviceOrFollow, sliderLabelConfig::setMuteOverrideColorFromColor);
- }
- for (slider = 0; slider < NUM_SLIDERS; slider++) {
- if (sliderSingleTabPane[slider].getSelectionModel().getSelectedIndex() == 0) {
- lightingConfig.getSliderConfigs()[slider].setMode(SINGLE_SLIDER_MODE.STATIC);
- lightingConfig.getSliderConfigs()[slider].setColor1FromColor(sliderStaticCDs[slider].getCustomColor());
- } else if (sliderSingleTabPane[slider].getSelectionModel().getSelectedIndex() == 1) {
- lightingConfig.getSliderConfigs()[slider].setMode(SINGLE_SLIDER_MODE.STATIC_GRADIENT);
- lightingConfig.getSliderConfigs()[slider].setColor1FromColor(sliderStaticGradientBottomCD[slider].getCustomColor());
- lightingConfig.getSliderConfigs()[slider].setColor2FromColor(sliderStaticGradientTopCD[slider].getCustomColor());
- } else if (sliderSingleTabPane[slider].getSelectionModel().getSelectedIndex() == 2) {
- lightingConfig.getSliderConfigs()[slider].setMode(SINGLE_SLIDER_MODE.VOLUME_GRADIENT);
- lightingConfig.getSliderConfigs()[slider].setColor1FromColor(sliderVolumeGradientCD1[slider].getCustomColor());
- lightingConfig.getSliderConfigs()[slider].setColor2FromColor(sliderVolumeGradientCD2[slider].getCustomColor());
- }
- var sliderConfig = lightingConfig.getSliderConfigs()[slider];
- setOverrideSetting(OverrideTargetType.SLIDER, slider, sliderConfig::setMuteOverrideDeviceOrFollow, sliderConfig::setMuteOverrideColorFromColor);
- }
- if (logoTabPane.getSelectionModel().getSelectedIndex() == 0) {
- lightingConfig.getLogoConfig().setMode(SINGLE_LOGO_MODE.STATIC);
- lightingConfig.getLogoConfig().setColor(logoStaticColor.getCustomColor());
- } else if (logoTabPane.getSelectionModel().getSelectedIndex() == 1) {
- lightingConfig.getLogoConfig().setMode(SINGLE_LOGO_MODE.RAINBOW);
- lightingConfig.getLogoConfig().setBrightness((byte) (int) logoRainbowBrightness.getValue());
- lightingConfig.getLogoConfig().setSpeed((byte) (int) logoRainbowSpeed.getValue());
- } else if (logoTabPane.getSelectionModel().getSelectedIndex() == 2) {
- lightingConfig.getLogoConfig().setMode(SINGLE_LOGO_MODE.BREATH);
- lightingConfig.getLogoConfig().setBrightness((byte) (int) logoBreathBrightness.getValue());
- lightingConfig.getLogoConfig().setSpeed((byte) (int) logoBreathSpeed.getValue());
- lightingConfig.getLogoConfig().setHue((byte) logoBreathHue.getHue());
- }
- setDeviceLighting();
- }
- }
-
- private static GridPane makeFourPanelGridPane(String str1, String str2, Node obj1, Node obj2) {
- var gp = new GridPane();
- var l1 = new Label(str1);
- var l2 = new Label(str2);
- l1.setWrapText(true);
- l2.setWrapText(true);
- gp.addColumn(0, l1, l2);
- gp.addColumn(1, obj1, obj2);
- return gp;
- }
-
- @Override
- public Collection getDevices() {
- return sndCtrl.getDevices();
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/ProfileSettingsDialog.java b/src/main/java/com/getpcpanel/ui/ProfileSettingsDialog.java
deleted file mode 100644
index eda7fdf3..00000000
--- a/src/main/java/com/getpcpanel/ui/ProfileSettingsDialog.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-
-import javax.annotation.Nonnull;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.osc.OSCService;
-import com.getpcpanel.profile.DeviceSave;
-import com.getpcpanel.profile.OSCBinding;
-import com.getpcpanel.profile.Profile;
-import com.getpcpanel.profile.SaveService;
-import com.getpcpanel.spring.OsHelper;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.util.ShortcutHook;
-import com.github.kwhat.jnativehook.keyboard.NativeKeyEvent;
-
-import javafx.application.Application;
-import javafx.collections.FXCollections;
-import javafx.collections.transformation.FilteredList;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.Scene;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.ComboBox;
-import javafx.scene.control.Label;
-import javafx.scene.control.TextField;
-import javafx.scene.image.Image;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.VBox;
-import javafx.stage.Stage;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-import one.util.streamex.EntryStream;
-import one.util.streamex.StreamEx;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-public class ProfileSettingsDialog extends Application implements UIInitializer {
- private final SaveService saveService;
- private final Optional shortcutHook;
- private final OsHelper osHelper;
- private final OSCService oscService;
- @FXML private Pane root;
- private DeviceSave deviceSave;
- private Profile profile;
- private Stage stage;
- @FXML private TextField profileName;
- @FXML private CheckBox mainProfile;
- @FXML private CheckBox focusBackOnLost;
- @FXML private PickProcessesController focusOnListListController;
- @FXML private TextField activationFld;
- @FXML private VBox osSpecificHolder;
- @FXML private VBox oscBindings;
- private List sortedAddresses;
-
- @Override
- public void initUI(@Nonnull ProfileSettingsArgs args) {
- deviceSave = args.deviceSave();
- profile = args.profile();
- root.setId("pane");
- }
-
- @Override
- public void start(Stage stage) throws Exception {
- this.stage = stage;
- UIHelper.closeOnEscape(stage);
- var scene = new Scene(root, 800.0D, 400.0D);
- scene.getStylesheets().addAll(Objects.requireNonNull(getClass().getResource("/assets/1.css")).toExternalForm());
- stage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResource("/assets/256x256.png")).toExternalForm()));
- stage.setScene(scene);
-
- initWindow();
- ResizeHelper.addResizeListener(stage, 200.0D, 200.0D);
- stage.sizeToScene();
- stage.setTitle("Profile: " + profile.getName());
-
- var toRemove = StreamEx.of(osSpecificHolder.getChildren()).remove(osHelper::isSupported).toSet();
- osSpecificHolder.getChildren().removeAll(toRemove);
-
- stage.show();
- }
-
- private void initWindow() {
- profileName.setText(profile.getName());
- mainProfile.setSelected(profile.isMainProfile());
-
- focusBackOnLost.setSelected(profile.isFocusBackOnLost());
- focusOnListListController.setPickType(PickProcessesController.PickType.process).setSelection(profile.getActivateApplications());
-
- activationFld.focusedProperty().addListener((observable, oldValue, newValue) -> shortcutHook.ifPresent(hook -> {
- if (newValue) {
- hook.setOverrideListener(this::registerShortcut);
- } else {
- hook.setOverrideListener(null);
- }
- }
- ));
- activationFld.setText(StringUtils.defaultString(profile.getActivationShortcut()));
- initOsc();
- }
-
- private void registerShortcut(NativeKeyEvent event) {
- shortcutHook.ifPresent(hook -> {
- if (hook.canBeShortcut(event)) {
- activationFld.setText(hook.toKeyString(event));
- }
- });
- }
-
- @FXML
- private void ok(ActionEvent event) {
- profile.setName(profileName.getText());
- profile.setMainProfile(mainProfile.isSelected());
- if (profile.isMainProfile()) {
- StreamEx.of(deviceSave.getProfiles()).remove(profile::equals).forEach(p -> p.setMainProfile(false));
- }
-
- profile.setFocusBackOnLost(focusBackOnLost.isSelected());
- profile.getActivateApplications().clear();
- profile.setActivateApplications(focusOnListListController.getSelection());
- profile.setActivationShortcut(StringUtils.trimToNull(activationFld.getText()));
- saveOsc();
-
- saveService.save();
- stage.close();
- }
-
- private void initOsc() {
- sortedAddresses = StreamEx.of(oscService.getAddresses()).sorted().prepend("").toList();
- var source = profile.getOscBinding();
- var config = profile.getLightingConfig();
- var knobCount = config.getKnobConfigs().length;
- var sliderCount = config.getSliderConfigs().length;
-
- for (var i = 0; i < knobCount; i++) {
- addOscRow("Knob " + (i + 1), source.getOrDefault(i * 2, OSCBinding.EMPTY), false);
- addOscRow("Button " + (i + 1), source.getOrDefault(i * 2 + 1, OSCBinding.EMPTY), true);
- }
-
- for (var i = 0; i < sliderCount; i++) {
- addOscRow("Slider " + (i + 1), source.getOrDefault((knobCount * 2) + i, OSCBinding.EMPTY), false);
- }
- }
-
- private void addOscRow(String controlName, OSCBinding controlValue, boolean button) {
- var label = new Label(controlName);
- label.setPrefWidth(100);
- HBox.setMargin(label, new Insets(0, 10, 0, 0));
-
- var address = buildComboBox();
- address.setValue(controlValue.address());
- var target = new HBox(label, address);
- target.setAlignment(Pos.CENTER_LEFT);
-
- if (button) {
- // TODO: Add when supporting toggle
- // var toggle = new CheckBox("Toggle");
- // toggle.setSelected(controlValue.toggle());
- // target.getChildren().addAll(toggle);
- } else {
- var min = new TextField(String.valueOf(controlValue.min()));
- var max = new TextField(String.valueOf(controlValue.max()));
- min.setPromptText("Min value");
- max.setPromptText("Max value");
- target.getChildren().addAll(min, max);
- }
-
- oscBindings.getChildren().add(target);
- }
-
- private ComboBox buildComboBox() {
- var field = new ComboBox<>(new FilteredList<>(FXCollections.observableArrayList(sortedAddresses), p -> true));
- field.setPrefHeight(25);
- field.setPrefWidth(200);
- field.setEditable(true);
- return field;
- }
-
- private void saveOsc() {
- var target = new HashMap();
- EntryStream.of(oscBindings.getChildren())
- .selectValues(HBox.class)
- .mapValues(this::toBinding)
- .forKeyValue(target::put);
- profile.setOscBinding(target);
- }
-
- private OSCBinding toBinding(HBox row) {
- @SuppressWarnings("unchecked") var address = ((ComboBox) row.getChildren().get(1)).getValue();
- var min = NumberUtils.toFloat(row.getChildren().size() > 2 && row.getChildren().get(2) instanceof TextField minField ? minField.getText() : "0", 0);
- var max = NumberUtils.toFloat(row.getChildren().size() > 3 && row.getChildren().get(3) instanceof TextField maxField ? maxField.getText() : "1", 1);
- var toggle = row.getChildren().size() > 2 && row.getChildren().get(2) instanceof CheckBox cb && cb.isSelected();
-
- return new OSCBinding(address, min, max, toggle);
- }
-
- @FXML
- private void clearActivationShortcut(ActionEvent event) {
- activationFld.setText("");
- }
-
- @FXML
- private void closeButtonAction(ActionEvent event) {
- stage.close();
- }
-
- public record ProfileSettingsArgs(DeviceSave deviceSave, Profile profile) {
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/RGBLightingDialog.java b/src/main/java/com/getpcpanel/ui/RGBLightingDialog.java
deleted file mode 100644
index 9ffb9d74..00000000
--- a/src/main/java/com/getpcpanel/ui/RGBLightingDialog.java
+++ /dev/null
@@ -1,273 +0,0 @@
-package com.getpcpanel.ui;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.IntStream;
-
-import javax.annotation.Nonnull;
-
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.device.PCPanelRGBUI;
-import com.getpcpanel.profile.LightingConfig;
-import com.getpcpanel.profile.LightingConfig.LightingMode;
-import com.getpcpanel.profile.SaveService;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.UIInitializer.SingleParamInitializer;
-import com.getpcpanel.ui.colorpicker.ColorDialog;
-import com.getpcpanel.ui.colorpicker.HueSlider;
-import com.getpcpanel.util.Util;
-
-import javafx.application.Application;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.Scene;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.Slider;
-import javafx.scene.control.Tab;
-import javafx.scene.control.TabPane;
-import javafx.scene.image.Image;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Color;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-public class RGBLightingDialog extends Application implements UIInitializer> {
- private final SaveService saveService;
- private final ApplicationEventPublisher eventPublisher;
-
- private Stage stage;
- @FXML private TabPane knobsTabbedPane;
- @FXML private TabPane allKnobsTabbedPane;
- @FXML private Slider rainbowPhaseShift;
- @FXML private Slider rainbowBrightness;
- @FXML private Slider rainbowSpeed;
- @FXML private CheckBox rainbowReverse;
- private HueSlider waveHue;
- @FXML private Slider waveBrightness;
- @FXML private Slider waveSpeed;
- @FXML private CheckBox waveReverse;
- @FXML private CheckBox waveBounce;
- private HueSlider breathHue;
- @FXML private Slider breathBrightness;
- @FXML private Slider breathSpeed;
- @FXML private VBox wavebox;
- @FXML private VBox breathbox;
- @FXML private HBox volumeFollowBox;
- @FXML private HBox volumeFollowCheckboxContainer;
- private ColorDialog allKnobColor;
- private final List cds = new ArrayList<>();
- private final List volumeFollowingCheckBoxes = new ArrayList<>();
- private PCPanelRGBUI device;
- private boolean pressedOk;
- @FXML private Pane root;
- private LightingConfig lightingConfig;
-
- @Override
- public void initUI(@Nonnull SingleParamInitializer args) {
- device = args.param();
- lightingConfig = device.getSavedLightingConfig().deepCopy();
- setDeviceLighting();
- postInit();
- }
-
- private void setDeviceLighting() {
- device.setLighting(lightingConfig.deepCopy(), true);
- }
-
- @Override
- public void start(Stage stage) {
- this.stage = stage;
- UIHelper.closeOnEscape(stage);
- var scene = new Scene(root);
- scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/assets/dark_theme.css")).toExternalForm());
- stage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResource("/assets/256x256.png")).toExternalForm()));
- stage.setOnHiding(e -> {
- if (!pressedOk) {
- device.setLighting(device.getSavedLightingConfig(), true);
- }
- eventPublisher.publishEvent(LightingChangedToDefaultEvent.INSTANCE);
- });
- stage.initModality(Modality.APPLICATION_MODAL);
- stage.initOwner(HomePage.stage);
- stage.setScene(scene);
- stage.sizeToScene();
- stage.setTitle("Lighting Dialog");
- stage.show();
- }
-
- public RGBLightingDialog select(int idx) {
- knobsTabbedPane.getSelectionModel().select(idx + 1);
- return this;
- }
-
- @FXML
- private void onCancel(ActionEvent event) {
- stage.close();
- }
-
- @FXML
- private void ok(ActionEvent event) {
- log.debug("{} {}", stage.getWidth(), stage.getHeight());
- pressedOk = true;
- device.setSavedLighting(lightingConfig);
- saveService.save();
- stage.close();
- }
-
- @FXML
- private void turnOffLights(ActionEvent event) {
- allKnobColor.setCustomColor(Color.WHITE);
- allKnobColor.setCustomColor(Color.BLACK);
- knobsTabbedPane.getSelectionModel().select(0);
- allKnobsTabbedPane.getSelectionModel().select(0);
- }
-
- private void postInit() {
- for (var i = 0; i < device.getKnobCount(); i++) {
- var knob = i + 1;
- var tab = new Tab("Knob " + knob);
- var cd = new ColorDialog(Color.BLACK);
- cds.add(cd);
- var cb = new CheckBox("K" + knob);
- volumeFollowingCheckBoxes.add(cb);
- volumeFollowCheckboxContainer.getChildren().add(cb);
- tab.setContent(cd);
- knobsTabbedPane.getTabs().add(tab);
- }
- Util.adjustTabs(allKnobsTabbedPane, 120, 30);
- allKnobColor = new ColorDialog();
- allKnobsTabbedPane.getTabs().get(0).setContent(allKnobColor);
- var allSliders = new Slider[] { rainbowPhaseShift, rainbowBrightness, rainbowSpeed,
- waveBrightness, waveSpeed,
- breathBrightness, breathSpeed };
- var allCheckBoxes = new CheckBox[] { rainbowReverse,
- waveReverse, waveBounce };
- waveHue = new HueSlider();
- wavebox.getChildren().add(1, waveHue);
- breathHue = new HueSlider();
- breathbox.getChildren().add(1, breathHue);
- initFields();
- initListeners(allSliders, allCheckBoxes);
- }
-
- private void initFields() {
- var mode = lightingConfig.getLightingMode();
- setFollowingControlsVisible(false);
- if (mode == LightingMode.ALL_COLOR) {
- setFollowingControlsVisible(true);
- setVolumeTrackingData(lightingConfig.getVolumeBrightnessTrackingEnabled());
- knobsTabbedPane.getSelectionModel().select(0);
- allKnobsTabbedPane.getSelectionModel().select(0);
- var color = Color.valueOf(lightingConfig.getAllColor());
- allKnobColor.setCustomColor(color);
- for (var cd : cds)
- cd.setCustomColor(color);
- } else if (mode == LightingMode.SINGLE_COLOR) {
- setFollowingControlsVisible(true);
- setVolumeTrackingData(lightingConfig.getVolumeBrightnessTrackingEnabled());
- knobsTabbedPane.getSelectionModel().select(1);
- for (var i = 0; i < device.getKnobCount(); i++)
- cds.get(i).setCustomColor(Color.valueOf(lightingConfig.getIndividualColors()[i]));
- } else if (mode == LightingMode.ALL_RAINBOW) {
- knobsTabbedPane.getSelectionModel().select(0);
- allKnobsTabbedPane.getSelectionModel().select(1);
- rainbowPhaseShift.setValue(lightingConfig.getRainbowPhaseShift() & 0xFF);
- rainbowBrightness.setValue(lightingConfig.getRainbowBrightness() & 0xFF);
- rainbowSpeed.setValue(lightingConfig.getRainbowSpeed() & 0xFF);
- rainbowReverse.setSelected(lightingConfig.getRainbowReverse() == 1);
- } else if (mode == LightingMode.ALL_WAVE) {
- knobsTabbedPane.getSelectionModel().select(0);
- allKnobsTabbedPane.getSelectionModel().select(2);
- waveHue.setHue(lightingConfig.getWaveHue() & 0xFF);
- waveBrightness.setValue(lightingConfig.getWaveBrightness() & 0xFF);
- waveSpeed.setValue(lightingConfig.getWaveSpeed() & 0xFF);
- waveReverse.setSelected(lightingConfig.getWaveReverse() == 1);
- waveBounce.setSelected(lightingConfig.getWaveBounce() == 1);
- } else if (mode == LightingMode.ALL_BREATH) {
- knobsTabbedPane.getSelectionModel().select(0);
- allKnobsTabbedPane.getSelectionModel().select(3);
- breathHue.setHue(lightingConfig.getBreathHue() & 0xFF);
- breathBrightness.setValue(lightingConfig.getBreathBrightness() & 0xFF);
- breathSpeed.setValue(lightingConfig.getBreathSpeed() & 0xFF);
- } else {
- log.error("unexpected mode in lightingdialog");
- }
- }
-
- private void initListeners(Slider[] allSliders, CheckBox[] allCheckBoxes) {
- for (var cd : cds)
- cd.customColorProperty().addListener((observable, oldValue, newValue) -> updateColors());
- allKnobColor.customColorProperty().addListener((observable, oldValue, newValue) -> {
- for (var cd : cds)
- cd.setCustomColor(newValue);
- updateColors();
- });
- for (var slider : allSliders) {
- slider.valueProperty().addListener((observable, oldValue, newValue) -> updateColors());
- }
- for (var cb : allCheckBoxes) {
- cb.selectedProperty().addListener((observable, oldValue, newValue) -> updateColors());
- }
- for (var cb : volumeFollowingCheckBoxes)
- cb.selectedProperty().addListener((observable, oldValue, newValue) -> updateColors());
- waveHue.getHueProperty().addListener((observable, oldValue, newValue) -> updateColors());
- breathHue.getHueProperty().addListener((observable, oldValue, newValue) -> updateColors());
- knobsTabbedPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> updateColors());
- allKnobsTabbedPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> updateColors());
- }
-
- @SuppressWarnings("NumericCastThatLosesPrecision")
- private void updateColors() {
- setFollowingControlsVisible(false);
- if (knobsTabbedPane.getSelectionModel().getSelectedIndex() == 0) {
- if (allKnobsTabbedPane.getSelectionModel().getSelectedIndex() == 0) {
- setFollowingControlsVisible(true);
- lightingConfig = LightingConfig.createAllColor(allKnobColor.getCustomColor(), getVolumeTrackingData());
- setDeviceLighting();
- } else if (allKnobsTabbedPane.getSelectionModel().getSelectedIndex() == 1) {
- lightingConfig = LightingConfig.createRainbowAnimation((byte) (int) rainbowPhaseShift.getValue(), (byte) (int) rainbowBrightness.getValue(),
- (byte) (int) rainbowSpeed.getValue(), rainbowReverse.isSelected());
- setDeviceLighting();
- } else if (allKnobsTabbedPane.getSelectionModel().getSelectedIndex() == 2) {
- lightingConfig = LightingConfig.createWaveAnimation((byte) waveHue.getHue(), (byte) (int) waveBrightness.getValue(), (byte) (int) waveSpeed.getValue(),
- waveReverse.isSelected(), waveBounce.isSelected());
- setDeviceLighting();
- } else if (allKnobsTabbedPane.getSelectionModel().getSelectedIndex() == 3) {
- lightingConfig = LightingConfig.createBreathAnimation((byte) breathHue.getHue(), (byte) (int) breathBrightness.getValue(), (byte) (int) breathSpeed.getValue());
- setDeviceLighting();
- }
- } else {
- setFollowingControlsVisible(true);
- var colors = IntStream.range(0, device.getKnobCount()).mapToObj(i -> cds.get(i).getCustomColor()).toArray(Color[]::new);
- lightingConfig = LightingConfig.createSingleColor(colors, getVolumeTrackingData());
- setDeviceLighting();
- }
- }
-
- private void setFollowingControlsVisible(boolean b) {
- volumeFollowBox.setVisible(b);
- }
-
- private boolean[] getVolumeTrackingData() {
- var ret = new boolean[device.getKnobCount()];
- for (var i = 0; i < ret.length; i++)
- ret[i] = volumeFollowingCheckBoxes.get(i).isSelected();
- return ret;
- }
-
- private void setVolumeTrackingData(boolean[] data) {
- for (var i = 0; i < data.length; i++)
- volumeFollowingCheckBoxes.get(i).setSelected(data[i]);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/ResizeHelper.java b/src/main/java/com/getpcpanel/ui/ResizeHelper.java
deleted file mode 100644
index 1d10ab7d..00000000
--- a/src/main/java/com/getpcpanel/ui/ResizeHelper.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package com.getpcpanel.ui;
-
-import javafx.event.EventHandler;
-import javafx.scene.Cursor;
-import javafx.scene.Node;
-import javafx.scene.Parent;
-import javafx.scene.input.MouseEvent;
-import javafx.stage.Stage;
-
-public final class ResizeHelper {
- private ResizeHelper() {
- }
-
- public static void addResizeListener(Stage stage, double minWidth, double minHeight) {
- addResizeListener(stage, minWidth, minHeight, Double.MAX_VALUE, Double.MAX_VALUE);
- }
-
- public static void addResizeListener(Stage stage, double minWidth, double minHeight, double maxWidth, double maxHeight) {
- var resizeListener = new ResizeListener(stage);
- stage.getScene().addEventHandler(MouseEvent.MOUSE_MOVED, resizeListener);
- stage.getScene().addEventHandler(MouseEvent.MOUSE_PRESSED, resizeListener);
- stage.getScene().addEventHandler(MouseEvent.MOUSE_DRAGGED, resizeListener);
- stage.getScene().addEventHandler(MouseEvent.MOUSE_EXITED, resizeListener);
- stage.getScene().addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, resizeListener);
- resizeListener.setMinWidth(minWidth);
- resizeListener.setMinHeight(minHeight);
- resizeListener.setMaxWidth(maxWidth);
- resizeListener.setMaxHeight(maxHeight);
- var children = stage.getScene().getRoot().getChildrenUnmodifiable();
- for (var child : children) {
- addListenerDeeply(child, resizeListener);
- }
- }
-
- private static void addListenerDeeply(Node node, EventHandler listener) {
- node.addEventHandler(MouseEvent.MOUSE_MOVED, listener);
- node.addEventHandler(MouseEvent.MOUSE_PRESSED, listener);
- node.addEventHandler(MouseEvent.MOUSE_DRAGGED, listener);
- node.addEventHandler(MouseEvent.MOUSE_EXITED, listener);
- node.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, listener);
- if (node instanceof Parent parent) {
- var children = parent.getChildrenUnmodifiable();
- for (var child : children) {
- if (!child.getStyleClass().contains("no-resize")) {
- addListenerDeeply(child, listener);
- }
- }
- }
- }
-
- static class ResizeListener implements EventHandler {
- private static final int BORDER = 4;
- private final Stage stage;
-
- private Cursor cursorEvent = Cursor.DEFAULT;
- private boolean resizing = true;
- private double startX;
- private double startY;
- private double screenOffsetX;
- private double screenOffsetY;
- private double minWidth;
- private double maxWidth;
- private double minHeight;
- private double maxHeight;
-
- public ResizeListener(Stage stage) {
- this.stage = stage;
- }
-
- public void setMinWidth(double minWidth) {
- this.minWidth = minWidth;
- }
-
- public void setMaxWidth(double maxWidth) {
- this.maxWidth = maxWidth;
- }
-
- public void setMinHeight(double minHeight) {
- this.minHeight = minHeight;
- }
-
- public void setMaxHeight(double maxHeight) {
- this.maxHeight = maxHeight;
- }
-
- @Override
- public void handle(MouseEvent mouseEvent) {
- var mouseEventType = mouseEvent.getEventType();
- var scene = stage.getScene();
- var mouseEventX = mouseEvent.getSceneX();
- var mouseEventY = mouseEvent.getSceneY();
- var sceneWidth = scene.getWidth();
- var sceneHeight = scene.getHeight();
- if (MouseEvent.MOUSE_MOVED.equals(mouseEventType)) {
- if (mouseEventX < BORDER && mouseEventY < BORDER) {
- cursorEvent = Cursor.NW_RESIZE;
- } else if (mouseEventX < BORDER && mouseEventY > sceneHeight - BORDER) {
- cursorEvent = Cursor.SW_RESIZE;
- } else if (mouseEventX > sceneWidth - BORDER && mouseEventY < BORDER) {
- cursorEvent = Cursor.NE_RESIZE;
- } else if (mouseEventX > sceneWidth - BORDER && mouseEventY > sceneHeight - BORDER) {
- cursorEvent = Cursor.SE_RESIZE;
- } else if (mouseEventX < BORDER) {
- cursorEvent = Cursor.W_RESIZE;
- } else if (mouseEventX > sceneWidth - BORDER) {
- cursorEvent = Cursor.E_RESIZE;
- } else if (mouseEventY < BORDER) {
- cursorEvent = Cursor.N_RESIZE;
- } else if (mouseEventY > sceneHeight - BORDER) {
- cursorEvent = Cursor.S_RESIZE;
- } else {
- cursorEvent = Cursor.DEFAULT;
- }
- scene.setCursor(cursorEvent);
- } else if (MouseEvent.MOUSE_EXITED.equals(mouseEventType) || MouseEvent.MOUSE_EXITED_TARGET.equals(mouseEventType)) {
- scene.setCursor(Cursor.DEFAULT);
- } else if (MouseEvent.MOUSE_PRESSED.equals(mouseEventType)) {
- startX = stage.getWidth() - mouseEventX;
- startY = stage.getHeight() - mouseEventY;
- } else if (MouseEvent.MOUSE_DRAGGED.equals(mouseEventType) &&
- !Cursor.DEFAULT.equals(cursorEvent)) {
- resizing = true;
- if (!Cursor.W_RESIZE.equals(cursorEvent) && !Cursor.E_RESIZE.equals(cursorEvent)) {
- var minHeight = (stage.getMinHeight() > (BORDER * 2)) ? stage.getMinHeight() : (BORDER * 2);
- if (Cursor.NW_RESIZE.equals(cursorEvent) || Cursor.N_RESIZE.equals(cursorEvent) ||
- Cursor.NE_RESIZE.equals(cursorEvent)) {
- if (stage.getHeight() > minHeight || mouseEventY < 0.0D) {
- setStageHeight(stage.getY() - mouseEvent.getScreenY() + stage.getHeight());
- stage.setY(mouseEvent.getScreenY());
- }
- } else if (stage.getHeight() > minHeight || mouseEventY + startY - stage.getHeight() > 0.0D) {
- setStageHeight(mouseEventY + startY);
- }
- }
- if (!Cursor.N_RESIZE.equals(cursorEvent) && !Cursor.S_RESIZE.equals(cursorEvent)) {
- var minWidth = (stage.getMinWidth() > (BORDER * 2)) ? stage.getMinWidth() : (BORDER * 2);
- if (Cursor.NW_RESIZE.equals(cursorEvent) || Cursor.W_RESIZE.equals(cursorEvent) ||
- Cursor.SW_RESIZE.equals(cursorEvent)) {
- if (stage.getWidth() > minWidth || mouseEventX < 0.0D) {
- setStageWidth(stage.getX() - mouseEvent.getScreenX() + stage.getWidth());
- stage.setX(mouseEvent.getScreenX());
- }
- } else if (stage.getWidth() > minWidth || mouseEventX + startX - stage.getWidth() > 0.0D) {
- setStageWidth(mouseEventX + startX);
- }
- }
- resizing = false;
- }
- if (MouseEvent.MOUSE_PRESSED.equals(mouseEventType) && Cursor.DEFAULT.equals(cursorEvent)) {
- resizing = false;
- screenOffsetX = stage.getX() - mouseEvent.getScreenX();
- screenOffsetY = stage.getY() - mouseEvent.getScreenY();
- }
- if (MouseEvent.MOUSE_DRAGGED.equals(mouseEventType) && Cursor.DEFAULT.equals(cursorEvent) && !resizing) {
- stage.setX(mouseEvent.getScreenX() + screenOffsetX);
- stage.setY(mouseEvent.getScreenY() + screenOffsetY);
- }
- }
-
- private void setStageWidth(double width) {
- width = Math.min(width, maxWidth);
- width = Math.max(width, minWidth);
- stage.setWidth(width);
- }
-
- private void setStageHeight(double height) {
- height = Math.min(height, maxHeight);
- height = Math.max(height, minHeight);
- stage.setHeight(height);
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/SettingsDialog.java b/src/main/java/com/getpcpanel/ui/SettingsDialog.java
deleted file mode 100644
index 5e687d29..00000000
--- a/src/main/java/com/getpcpanel/ui/SettingsDialog.java
+++ /dev/null
@@ -1,369 +0,0 @@
-package com.getpcpanel.ui;
-
-import static com.getpcpanel.profile.Save.DEFAULT_OVERLAY_BAR_BACKGROUND_COLOR;
-import static com.getpcpanel.profile.Save.DEFAULT_OVERLAY_BAR_COLOR;
-import static com.getpcpanel.profile.Save.DEFAULT_OVERLAY_BAR_HEIGHT;
-import static com.getpcpanel.profile.Save.DEFAULT_OVERLAY_BG_COLOR;
-import static com.getpcpanel.profile.Save.DEFAULT_OVERLAY_PADDING;
-import static com.getpcpanel.profile.Save.DEFAULT_OVERLAY_TEXT_COLOR;
-
-import java.util.List;
-import java.util.Objects;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.apache.commons.lang3.math.NumberUtils;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.MainFX;
-import com.getpcpanel.cpp.linux.pulseaudio.SndCtrlPulseAudioDebug;
-import com.getpcpanel.cpp.windows.SndCtrlWindows;
-import com.getpcpanel.obs.OBS;
-import com.getpcpanel.profile.Save;
-import com.getpcpanel.profile.SaveService;
-import com.getpcpanel.profile.WaveLinkSettings;
-import com.getpcpanel.spring.OsHelper;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.UIInitializer.SingleParamInitializer;
-import com.getpcpanel.util.FileUtil;
-import com.getpcpanel.util.IPlatformCommand;
-
-import javafx.application.Application;
-import javafx.application.Platform;
-import javafx.beans.binding.Bindings;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.Scene;
-import javafx.scene.control.Button;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.ColorPicker;
-import javafx.scene.control.Label;
-import javafx.scene.control.Tab;
-import javafx.scene.control.TextField;
-import javafx.scene.control.ToggleButton;
-import javafx.scene.image.Image;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Color;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-public class SettingsDialog extends Application implements UIInitializer> {
- private final SaveService saveService;
- private final FileUtil fileUtil;
- private final IPlatformCommand platformCommand;
- private final OsHelper osHelper;
- private final OBS obs;
- private Stage parentStage;
-
- private Stage stage;
- @FXML private Pane root;
- @FXML private CheckBox mainUiIcons;
- @FXML private CheckBox startupVersionCheck;
- @FXML private CheckBox forceVolume;
- @FXML private CheckBox overlay;
- @FXML private CheckBox overlayUseLog;
- @FXML private CheckBox overlayShowNumber;
- @FXML private ColorPicker overlayTextColor;
- @FXML private ColorPicker overlayBackgroundColor;
- @FXML private ColorPicker overlayBarColor;
- @FXML private ColorPicker overlayBarBackgroundColor;
- @FXML private TextField overlayWindowCornerRounding;
- @FXML private TextField overlayBarHeight;
- @FXML private TextField overlayBarCornerRounding;
- @FXML private Label overlayBGTransparency;
- @FXML private TextField dblClickInterval;
- @FXML private CheckBox preventClickWhenDblClick;
- @FXML private CheckBox obsEnable;
- @FXML private Pane obsControls;
- @FXML private TextField obsAddress;
- @FXML private TextField obsPort;
- @FXML private TextField obsPassword;
- @FXML private Button testBtn;
- @FXML private Label obsTestResult;
- @FXML private CheckBox vmEnable;
- @FXML private Pane vmControls;
- @FXML private TextField vmPath;
- @FXML private Tab voicemeeterTab;
- @FXML private Tab waveLinkTab;
- @FXML private CheckBox waveLinkEnable;
- @FXML private TextField txtPreventSliderTwitch;
- @FXML private TextField txtSliderRollingAverage;
- @FXML private TextField txtOnlyIfDelta;
- @FXML private CheckBox cbFixOnlySliders;
- @FXML private OSCSettingsDialog oscSettingsController;
- @FXML private MqttSettingsDialog mqttSettingsController;
- @FXML private VBox debug;
- @FXML private Label copied;
- @FXML private ToggleButton btnTL;
- @FXML private ToggleButton btnTM;
- @FXML private ToggleButton btnTR;
- @FXML private ToggleButton btnML;
- @FXML private ToggleButton btnMM;
- @FXML private ToggleButton btnMR;
- @FXML private ToggleButton btnBL;
- @FXML private ToggleButton btnBM;
- @FXML private ToggleButton btnBR;
- @FXML public TextField overlayPadding;
-
- @Override
- public void initUI(@Nonnull SingleParamInitializer args) {
- parentStage = args.param();
- postInit();
- }
-
- @Override
- public void start(Stage stage) {
- this.stage = stage;
- UIHelper.closeOnEscape(stage);
- var scene = new Scene(root);
- scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/assets/dark_theme.css"), "Unable to find dark_theme.css").toExternalForm());
- scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/assets/1.css"), "Unable to find 1.css").toExternalForm());
- stage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResource("/assets/256x256.png")).toExternalForm()));
- stage.setScene(scene);
- stage.setResizable(false);
- stage.sizeToScene();
- stage.setTitle("Settings");
- stage.initModality(Modality.WINDOW_MODAL);
- stage.initOwner(parentStage);
-
- if (osHelper.notWindows()) {
- voicemeeterTab.getTabPane().getTabs().remove(voicemeeterTab);
- }
- if (osHelper.isLinux()) { // MacOS is supported by WaveLink
- waveLinkTab.getTabPane().getTabs().remove(waveLinkTab);
- }
-
- osHelper.hideUnsupportedChildren(List.of(forceVolume));
- stage.showAndWait();
- }
-
- @FXML
- private void onOBSEnablePressed(@Nullable ActionEvent ignored) {
- obsControls.setDisable(!obsEnable.isSelected());
- }
-
- @FXML
- private void onVMEnablePressed(@Nullable ActionEvent ignored) {
- vmControls.setDisable(!vmEnable.isSelected());
- }
-
- @FXML
- private void onVoiceMeeterBrowse(ActionEvent event) {
- UIHelper.showFolderPicker("Pick VoiceMeeter directory", vmPath);
- }
-
- @FXML
- private void ok(ActionEvent event) {
- var save = saveService.get();
- save.setMainUIIcons(mainUiIcons.isSelected());
- save.setStartupVersionCheck(startupVersionCheck.isSelected());
- save.setForceVolume(forceVolume.isSelected());
- save.setOverlayEnabled(overlay.isSelected());
- save.setOverlayUseLog(overlayUseLog.isSelected());
- save.setOverlayShowNumber(overlayShowNumber.isSelected());
- save.setOverlayBackgroundColor(toWebColor(overlayBackgroundColor.getValue()));
- save.setOverlayBarColor(toWebColor(overlayBarColor.getValue()));
- save.setOverlayBarBackgroundColor(toWebColor(overlayBarBackgroundColor.getValue()));
- save.setOverlayTextColor(toWebColor(overlayTextColor.getValue()));
- save.setOverlayWindowCornerRounding(NumberUtils.toInt(overlayWindowCornerRounding.getText(), 0));
- save.setOverlayBarHeight(NumberUtils.toInt(overlayBarHeight.getText(), 0));
- save.setOverlayBarCornerRounding(NumberUtils.toInt(overlayBarCornerRounding.getText(), 0));
- save.setOverlayPadding(NumberUtils.toInt(overlayPadding.getText(), 0));
- save.setOverlayPosition(getOverlayPosition());
- save.setDblClickInterval(NumberUtils.toLong(dblClickInterval.getText(), 500));
- save.setPreventClickWhenDblClick(preventClickWhenDblClick.isSelected());
- save.setObsEnabled(obsEnable.isSelected());
- save.setObsAddress(obsAddress.getText());
- save.setObsPort(obsPort.getText());
- save.setObsPassword(obsPassword.getText());
- save.setVoicemeeterEnabled(vmEnable.isSelected());
- save.setVoicemeeterPath(vmPath.getText());
- save.setWaveLink(new WaveLinkSettings(waveLinkEnable.isSelected()));
- save.setPreventSliderTwitchDelay(NumberUtils.toInt(txtPreventSliderTwitch.getText(), 0));
- save.setSliderRollingAverage(NumberUtils.toInt(txtSliderRollingAverage.getText(), 0));
- save.setSendOnlyIfDelta(NumberUtils.toInt(txtOnlyIfDelta.getText(), 0));
- save.setWorkaroundsOnlySliders(cbFixOnlySliders.isSelected());
- oscSettingsController.save(save);
- mqttSettingsController.save(save);
- saveService.save();
- stage.close();
- }
-
- private String toWebColor(@Nonnull Color value) {
- return "rgba(%s, %s, %s, %s)".formatted(
- Math.round(value.getRed() * 255),
- Math.round(value.getGreen() * 255),
- Math.round(value.getBlue() * 255),
- Math.round(value.getOpacity() * 100) / 100f
- );
- }
-
- @FXML
- private void closeButtonAction(ActionEvent event) {
- stage.close();
- }
-
- @FXML
- private void openLogsFolder(ActionEvent event) {
- var logFolder = fileUtil.getFile("logs");
- platformCommand.exec(logFolder.getAbsolutePath());
- }
-
- private void initFields() {
- var save = saveService.get();
- mainUiIcons.setSelected(save.isMainUIIcons());
- startupVersionCheck.setSelected(save.isStartupVersionCheck());
- forceVolume.setSelected(save.isForceVolume());
- overlay.setSelected(save.isOverlayEnabled());
- overlayUseLog.setSelected(save.isOverlayUseLog());
- overlayShowNumber.setSelected(save.isOverlayShowNumber());
- overlayWindowCornerRounding.setText("" + save.getOverlayWindowCornerRounding());
- overlayBarHeight.setText("" + save.getOverlayBarHeight());
- overlayBarCornerRounding.setText("" + save.getOverlayBarCornerRounding());
- initOverlayPosition(save);
- overlayPadding.setText("" + save.getOverlayPadding());
- dblClickInterval.setText(save.getDblClickInterval() == null ? "500" : save.getDblClickInterval().toString());
- preventClickWhenDblClick.setSelected(save.isPreventClickWhenDblClick());
- obsEnable.setSelected(save.isObsEnabled());
- obsAddress.setText(save.getObsAddress());
- obsPort.setText(save.getObsPort());
- obsPassword.setText(save.getObsPassword());
- onOBSEnablePressed(null);
- vmEnable.setSelected(save.isVoicemeeterEnabled());
- vmPath.setText(save.getVoicemeeterPath());
- waveLinkEnable.setSelected(save.getWaveLink().enabled());
- onVMEnablePressed(null);
- txtPreventSliderTwitch.setText(save.getPreventSliderTwitchDelay() == null ? "" : save.getPreventSliderTwitchDelay().toString());
- txtSliderRollingAverage.setText(save.getSliderRollingAverage() == null ? "" : save.getSliderRollingAverage().toString());
- txtOnlyIfDelta.setText(save.getSendOnlyIfDelta() == null ? "" : save.getSendOnlyIfDelta().toString());
- cbFixOnlySliders.setSelected(save.isWorkaroundsOnlySliders());
-
- oscSettingsController.populate(save);
- mqttSettingsController.populate(save);
- initOverlayColors(save);
- }
-
- private void initOverlayPosition(Save save) {
- var position = save.getOverlayPosition();
- btnTL.setSelected(position == OverlayPosition.topLeft);
- btnTM.setSelected(position == OverlayPosition.topMiddle);
- btnTR.setSelected(position == OverlayPosition.topRight);
- btnML.setSelected(position == OverlayPosition.middleLeft);
- btnMM.setSelected(position == OverlayPosition.middleMiddle);
- btnMR.setSelected(position == OverlayPosition.middleRight);
- btnBL.setSelected(position == OverlayPosition.bottomLeft);
- btnBM.setSelected(position == OverlayPosition.bottomMiddle);
- btnBR.setSelected(position == OverlayPosition.bottomRight);
- }
-
- private OverlayPosition getOverlayPosition() {
- // @formatter:off
- if (btnTL.isSelected())
- return OverlayPosition.topLeft;
- if (btnTM.isSelected())
- return OverlayPosition.topMiddle;
- if (btnTR.isSelected())
- return OverlayPosition.topRight;
- if (btnML.isSelected())
- return OverlayPosition.middleLeft;
- if (btnMM.isSelected())
- return OverlayPosition.middleMiddle;
- if (btnMR.isSelected())
- return OverlayPosition.middleRight;
- if (btnBL.isSelected())
- return OverlayPosition.bottomLeft;
- if (btnBM.isSelected())
- return OverlayPosition.bottomMiddle;
- if (btnBR.isSelected())
- return OverlayPosition.bottomRight;
- // @formatter:on
- return OverlayPosition.topLeft;
- }
-
- private void initOverlayColors(Save save) {
- try {
- overlayBackgroundColor.setValue(Color.web(save.getOverlayBackgroundColor()));
- } catch (IllegalArgumentException e) {
- overlayBackgroundColor.setValue(Color.web(DEFAULT_OVERLAY_BG_COLOR));
- }
- try {
- overlayTextColor.setValue(Color.web(save.getOverlayTextColor()));
- } catch (IllegalArgumentException e) {
- overlayTextColor.setValue(Color.web(DEFAULT_OVERLAY_TEXT_COLOR));
- }
- try {
- overlayBarColor.setValue(Color.web(save.getOverlayBarColor()));
- } catch (IllegalArgumentException e) {
- overlayBarColor.setValue(Color.web(DEFAULT_OVERLAY_BAR_COLOR));
- }
- try {
- overlayBarBackgroundColor.setValue(Color.web(save.getOverlayBarBackgroundColor()));
- } catch (IllegalArgumentException e) {
- overlayBarBackgroundColor.setValue(Color.web(DEFAULT_OVERLAY_BAR_BACKGROUND_COLOR));
- }
-
- var colorOpacityBinding = Bindings.createObjectBinding(() -> Math.round(overlayBackgroundColor.getValue().getOpacity() * 100) + "%", overlayBackgroundColor.valueProperty());
- overlayBGTransparency.textProperty().bind(colorOpacityBinding);
- }
-
- private void postInit() {
- initFields();
- osHelper.hideUnsupportedChildren(debug.getChildrenUnmodifiable());
- }
-
- public void doTest(ActionEvent ignored) {
- obsTestResult.setText("Testing...");
- testBtn.setDisable(true);
- new Thread(() -> {
- var port = NumberUtils.toInt(obsPort.getText(), -1);
- String result;
- if (port == -1) {
- result = "Invalid port";
- } else {
- var message = obs.test(obsAddress.getText(), port, obsPassword.getText(), 2_500L);
- if (message == null) {
- result = "Success";
- } else {
- result = "Failed: " + message;
- }
- }
- Platform.runLater(() -> {
- testBtn.setDisable(false);
- obsTestResult.setText(result);
- });
- }).start();
- }
-
- @SuppressWarnings("unused")
- public void triggerAv(ActionEvent ignored) {
- MainFX.getBean(SndCtrlWindows.class).triggerAv();
- }
-
- public void copyAudioOutput(ActionEvent ignored) {
- copied.setText("Preparing output");
- MainFX.getOptionalBean(SndCtrlPulseAudioDebug.class).ifPresent(SndCtrlPulseAudioDebug::copyDebugOutput);
- copied.setText("Output was copied to your clipboard");
- }
-
- public void resetOverlayToDefault(ActionEvent actionEvent) {
- overlayUseLog.setSelected(false);
- overlayShowNumber.setSelected(false);
- btnTL.setSelected(true);
- overlayWindowCornerRounding.setText("0");
- overlayBarHeight.setText(DEFAULT_OVERLAY_BAR_HEIGHT + "");
- overlayBarCornerRounding.setText("0");
- overlayPadding.setText(DEFAULT_OVERLAY_PADDING + "");
- overlayBackgroundColor.setValue(Color.web(DEFAULT_OVERLAY_BG_COLOR));
- overlayTextColor.setValue(Color.web(DEFAULT_OVERLAY_TEXT_COLOR));
- overlayBarColor.setValue(Color.web(DEFAULT_OVERLAY_BAR_COLOR));
- overlayBarBackgroundColor.setValue(Color.web(DEFAULT_OVERLAY_BAR_BACKGROUND_COLOR));
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/SoundDeviceExportFactory.java b/src/main/java/com/getpcpanel/ui/SoundDeviceExportFactory.java
deleted file mode 100644
index 5b3b72da..00000000
--- a/src/main/java/com/getpcpanel/ui/SoundDeviceExportFactory.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.getpcpanel.ui;
-
-import com.getpcpanel.cpp.AudioDevice;
-import com.getpcpanel.cpp.DataFlow;
-
-import javafx.scene.control.ListCell;
-import javafx.scene.control.ListView;
-import javafx.scene.input.ClipboardContent;
-import javafx.scene.input.DataFormat;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.input.TransferMode;
-import javafx.util.Callback;
-import lombok.Setter;
-
-public class SoundDeviceExportFactory implements Callback, ListCell> {
- private static final DataFormat JAVA_FORMAT = SoundDeviceImportFactory.JAVA_FORMAT;
- @Setter private DataFlow enabledFlavor;
-
- public SoundDeviceExportFactory(ListView listView) {
- setupListView(listView);
- }
-
- @Override
- public ListCell call(ListView listView) {
- ListCell cell = new ListCell<>() {
- @Override
- protected void updateItem(AudioDevice item, boolean empty) {
- super.updateItem(item, empty);
- if (item == null) {
- setText("");
- setDisable(false);
- return;
- }
- setText(item.toString());
- setDisable(enabledFlavor != null && enabledFlavor != item.dataflow());
- }
- };
- cell.setOnDragDetected(event -> dragDetected(event, cell));
- return cell;
- }
-
- private void dragDetected(MouseEvent event, ListCell treeCell) {
- var draggedItem = treeCell.getItem();
- var db = treeCell.startDragAndDrop(TransferMode.MOVE);
- var content = new ClipboardContent();
- content.put(JAVA_FORMAT, draggedItem);
- db.setContent(content);
- db.setDragView(treeCell.snapshot(null, null));
- event.consume();
- }
-
- private static void setupListView(ListView listView) {
- listView.setOnDragOver(event -> {
- if (!event.getDragboard().hasContent(JAVA_FORMAT))
- return;
- var dropContent = (AudioDevice) event.getDragboard().getContent(JAVA_FORMAT);
- if (listView.getItems().contains(dropContent))
- return;
- event.acceptTransferModes(TransferMode.MOVE);
- });
- listView.setOnDragDropped(event -> {
- var db = event.getDragboard();
- var success = false;
- if (!db.hasContent(JAVA_FORMAT))
- return;
- var index = 0;
- listView.getItems().add(index, (AudioDevice) db.getContent(JAVA_FORMAT));
- event.setDropCompleted(success);
- });
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/SoundDeviceImportFactory.java b/src/main/java/com/getpcpanel/ui/SoundDeviceImportFactory.java
deleted file mode 100644
index ecee2d35..00000000
--- a/src/main/java/com/getpcpanel/ui/SoundDeviceImportFactory.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package com.getpcpanel.ui;
-
-import com.getpcpanel.cpp.AudioDevice;
-
-import javafx.scene.control.ListCell;
-import javafx.scene.control.ListView;
-import javafx.scene.input.ClipboardContent;
-import javafx.scene.input.DataFormat;
-import javafx.scene.input.DragEvent;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.input.TransferMode;
-import javafx.util.Callback;
-
-public class SoundDeviceImportFactory implements Callback, ListCell> {
- public static final DataFormat JAVA_FORMAT = new DataFormat("application/x-java-serialized-object");
-
- private static final String DROP_HINT_STYLE_ABOVE = "-fx-border-color: #eea82f; -fx-border-width: 2 0 0 0; -fx-padding: 1 7 3 7;";
-
- private static final String DROP_HINT_STYLE_BELLOW = "-fx-border-color: #eea82f; -fx-border-width: 0 0 2 0; -fx-padding: 3 7 1 7";
-
- private ListCell dropZone;
-
- private AudioDevice draggedItem;
-
- private final ListView listView;
-
- public SoundDeviceImportFactory(ListView listView) {
- this.listView = listView;
- setupListView(listView);
- }
-
- @Override
- public ListCell call(ListView listView) {
- var cell = new ListCell() {
- @Override
- protected void updateItem(AudioDevice item, boolean empty) {
- super.updateItem(item, empty);
- if (item == null) {
- setText("");
- return;
- }
- setText(item.toString());
- }
- };
- cell.setOnDragDetected(event -> dragDetected(event, cell, listView));
- cell.setOnDragOver(event -> dragOver(event, cell, listView));
- cell.setOnDragDropped(event -> drop(event, cell, listView));
- cell.setOnDragDone(event -> clearDropLocation());
- cell.setOnDragExited(event -> clearDropLocation());
- return cell;
- }
-
- private void dragDetected(MouseEvent event, ListCell treeCell, ListView treeView) {
- draggedItem = treeCell.getItem();
- var db = treeCell.startDragAndDrop(TransferMode.MOVE);
- var content = new ClipboardContent();
- content.put(JAVA_FORMAT, draggedItem);
- db.setContent(content);
- db.setDragView(treeCell.snapshot(null, null));
- event.consume();
- }
-
- private void dragOver(DragEvent event, ListCell treeCell, ListView treeView) {
- if (!event.getDragboard().hasContent(JAVA_FORMAT))
- return;
- var thisItem = treeCell.getItem();
- var dropContent = (AudioDevice) event.getDragboard().getContent(JAVA_FORMAT);
- if (event.getGestureSource().getClass().getEnclosingClass().getName().contains("SoundDeviceImportFactory")) {
- if (thisItem == draggedItem)
- return;
- } else if (treeView.getItems().contains(dropContent)) {
- return;
- }
- event.acceptTransferModes(TransferMode.MOVE);
- if (thisItem == null)
- return;
- clearDropLocation();
- dropZone = treeCell;
- if (event.getY() < treeCell.getHeight() / 2.0D) {
- dropZone.setStyle(DROP_HINT_STYLE_ABOVE);
- } else {
- dropZone.setStyle(DROP_HINT_STYLE_BELLOW);
- }
- }
-
- private void drop(DragEvent event, ListCell treeCell, ListView treeView) {
- var db = event.getDragboard();
- var success = false;
- if (!db.hasContent(JAVA_FORMAT))
- return;
- var thisItem = treeCell.getItem();
- var index = listView.getItems().indexOf(thisItem);
- if (DROP_HINT_STYLE_BELLOW.equals(treeCell.getStyle()))
- index++;
- if (index == -1)
- index = listView.getItems().size();
- if (event.getGestureSource().getClass().getEnclosingClass().getName().contains("SoundDeviceImportFactory")) {
- var moverLocation = listView.getItems().indexOf(draggedItem);
- if (index > moverLocation)
- index--;
- listView.getItems().remove(draggedItem);
- listView.getItems().add(index, draggedItem);
- treeView.getSelectionModel().select(draggedItem);
- } else {
- listView.getItems().add(index, (AudioDevice) db.getContent(JAVA_FORMAT));
- }
- event.setDropCompleted(success);
- clearDropLocation();
- }
-
- private void clearDropLocation() {
- if (dropZone != null)
- dropZone.setStyle("");
- }
-
- private static void setupListView(ListView listView) {
- listView.setOnDragOver(event -> {
- if (!event.getDragboard().hasContent(JAVA_FORMAT) || !listView.getItems().isEmpty())
- return;
- var dropContent = (AudioDevice) event.getDragboard().getContent(JAVA_FORMAT);
- if (listView.getItems().contains(dropContent))
- return;
- event.acceptTransferModes(TransferMode.MOVE);
- });
- listView.setOnDragDropped(event -> {
- var db = event.getDragboard();
- var success = false;
- if (!db.hasContent(JAVA_FORMAT) || !listView.getItems().isEmpty())
- return;
- var index = listView.getItems().size();
- listView.getItems().add(index, (AudioDevice) db.getContent(JAVA_FORMAT));
- event.setDropCompleted(success);
- });
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/UIHelper.java b/src/main/java/com/getpcpanel/ui/UIHelper.java
deleted file mode 100644
index 4c7fcf7d..00000000
--- a/src/main/java/com/getpcpanel/ui/UIHelper.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.getpcpanel.ui;
-
-import static javafx.scene.input.KeyEvent.KEY_PRESSED;
-
-import java.io.File;
-import java.util.Optional;
-
-import javafx.scene.control.TextField;
-import javafx.scene.input.KeyCode;
-import javafx.stage.FileChooser;
-import javafx.stage.Stage;
-
-public final class UIHelper {
-
- private UIHelper() {
- }
-
- public static void closeOnEscape(Stage stage) {
- stage.addEventHandler(KEY_PRESSED, t -> {
- if (t.getCode() == KeyCode.ESCAPE) {
- stage.close();
- }
- });
- }
-
- public static void showFolderPicker(String title, TextField target) {
- pickFile(title, target)
- .map(f -> f.isFile() ? f.getParentFile() : f)
- .ifPresent(f -> target.setText(f.getAbsolutePath()));
- }
-
- public static void showFilePicker(String title, TextField target) {
- pickFile(title, target)
- .ifPresent(f -> target.setText(f.getAbsolutePath()));
- }
-
- private static Optional pickFile(String title, TextField target) {
- var stage = (Stage) target.getScene().getWindow();
- var fileChooser = new FileChooser();
- fileChooser.setTitle(title);
-
- var current = new File(target.getText());
- fileChooser.setInitialFileName(current.isDirectory() ? "" : current.getName());
- fileChooser.setInitialDirectory(current.isDirectory() ? current : current.getParentFile());
-
- return Optional.ofNullable(fileChooser.showOpenDialog(stage));
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/UIInitializer.java b/src/main/java/com/getpcpanel/ui/UIInitializer.java
deleted file mode 100644
index 1f2ded12..00000000
--- a/src/main/java/com/getpcpanel/ui/UIInitializer.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.getpcpanel.ui;
-
-import javax.annotation.Nonnull;
-
-public interface UIInitializer {
- default void initUI(@Nonnull T args) {
- }
-
- record SingleParamInitializer(TT param) {
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/colorpicker/ColorDialog.java b/src/main/java/com/getpcpanel/ui/colorpicker/ColorDialog.java
deleted file mode 100644
index 89ec06b4..00000000
--- a/src/main/java/com/getpcpanel/ui/colorpicker/ColorDialog.java
+++ /dev/null
@@ -1,471 +0,0 @@
-package com.getpcpanel.ui.colorpicker;
-
-import java.util.Objects;
-
-import com.sun.javafx.scene.control.skin.resources.ControlResources;
-
-import javafx.beans.Observable;
-import javafx.beans.binding.Bindings;
-import javafx.beans.binding.ObjectBinding;
-import javafx.beans.property.DoubleProperty;
-import javafx.beans.property.IntegerProperty;
-import javafx.beans.property.ObjectProperty;
-import javafx.beans.property.Property;
-import javafx.beans.property.SimpleDoubleProperty;
-import javafx.beans.property.SimpleIntegerProperty;
-import javafx.beans.property.SimpleObjectProperty;
-import javafx.event.EventHandler;
-import javafx.geometry.Insets;
-import javafx.geometry.Orientation;
-import javafx.geometry.Pos;
-import javafx.scene.control.Label;
-import javafx.scene.control.Slider;
-import javafx.scene.control.ToggleButton;
-import javafx.scene.control.ToggleGroup;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.Background;
-import javafx.scene.layout.BackgroundFill;
-import javafx.scene.layout.ColumnConstraints;
-import javafx.scene.layout.CornerRadii;
-import javafx.scene.layout.GridPane;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.Region;
-import javafx.scene.layout.RowConstraints;
-import javafx.scene.layout.StackPane;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Color;
-import javafx.scene.paint.CycleMethod;
-import javafx.scene.paint.LinearGradient;
-import javafx.scene.paint.Stop;
-
-public class ColorDialog extends HBox {
- private ColorRectPane colorRectPane;
- private final ObjectProperty customColorProperty = new SimpleObjectProperty<>(Color.TRANSPARENT);
-
- public ColorDialog(Color color) {
- getStyleClass().add("custom-color-dialog");
- buildUI();
- setCustomColor(Objects.requireNonNullElse(color, Color.BLACK));
- }
-
- public ColorDialog() {
- this(null);
- }
-
- private void buildUI() {
- colorRectPane = new ColorRectPane();
- var controlsPane = new ControlsPane();
- setHgrow(controlsPane, Priority.ALWAYS);
- getChildren().setAll(colorRectPane, controlsPane);
- }
-
- static String getString(String key) {
- return ControlResources.getString("ColorPicker." + key);
- }
-
- public ObjectProperty customColorProperty() {
- return customColorProperty;
- }
-
- public final void setCustomColor(Color color) {
- customColorProperty.set(color);
- }
-
- public Color getCustomColor() {
- return customColorProperty.get();
- }
-
- private class ColorRectPane extends HBox {
- private final Pane colorRect;
- private final Pane colorBar;
- private final Region colorRectIndicator;
- private boolean changeIsLocal;
-
- private final DoubleProperty hue = new SimpleDoubleProperty(-1.0D) {
- @Override
- protected void invalidated() {
- if (!changeIsLocal) {
- changeIsLocal = true;
- updateHSBColor();
- changeIsLocal = false;
- }
- }
- };
-
- private final DoubleProperty sat = new SimpleDoubleProperty(-1.0D) {
- @Override
- protected void invalidated() {
- if (!changeIsLocal) {
- changeIsLocal = true;
- updateHSBColor();
- changeIsLocal = false;
- }
- }
- };
-
- private final DoubleProperty bright = new SimpleDoubleProperty(-1.0D) {
- @Override
- protected void invalidated() {
- if (!changeIsLocal) {
- changeIsLocal = true;
- updateHSBColor();
- changeIsLocal = false;
- }
- }
- };
-
- private final IntegerProperty red = new SimpleIntegerProperty(-1) {
- @Override
- protected void invalidated() {
- if (!changeIsLocal) {
- changeIsLocal = true;
- updateRGBColor();
- changeIsLocal = false;
- }
- }
- };
-
- private final IntegerProperty green = new SimpleIntegerProperty(-1) {
- @Override
- protected void invalidated() {
- if (!changeIsLocal) {
- changeIsLocal = true;
- updateRGBColor();
- changeIsLocal = false;
- }
- }
- };
-
- private final IntegerProperty blue = new SimpleIntegerProperty(-1) {
- @Override
- protected void invalidated() {
- if (!changeIsLocal) {
- changeIsLocal = true;
- updateRGBColor();
- changeIsLocal = false;
- }
- }
- };
-
- private final DoubleProperty alpha = new SimpleDoubleProperty(100.0D) {
- @Override
- protected void invalidated() {
- if (!changeIsLocal) {
- changeIsLocal = true;
- setCustomColor(new Color(
- getCustomColor().getRed(),
- getCustomColor().getGreen(),
- getCustomColor().getBlue(),
- clamp(alpha.get() / 100.0D)));
- changeIsLocal = false;
- }
- }
- };
-
- private void updateRGBColor() {
- var newColor = Color.rgb(red.get(), green.get(), blue.get(), clamp(alpha.get() / 100.0D));
- hue.set(newColor.getHue());
- sat.set(newColor.getSaturation() * 100.0D);
- bright.set(newColor.getBrightness() * 100.0D);
- setCustomColor(newColor);
- }
-
- private void updateHSBColor() {
- var newColor = Color.hsb(hue.get(), clamp(sat.get() / 100.0D),
- clamp(bright.get() / 100.0D), clamp(alpha.get() / 100.0D));
- red.set(doubleToInt(newColor.getRed()));
- green.set(doubleToInt(newColor.getGreen()));
- blue.set(doubleToInt(newColor.getBlue()));
- setCustomColor(newColor);
- }
-
- private void colorChanged() {
- if (!changeIsLocal) {
- changeIsLocal = true;
- hue.set(getCustomColor().getHue());
- sat.set(getCustomColor().getSaturation() * 100.0D);
- bright.set(getCustomColor().getBrightness() * 100.0D);
- red.set(doubleToInt(getCustomColor().getRed()));
- green.set(doubleToInt(getCustomColor().getGreen()));
- blue.set(doubleToInt(getCustomColor().getBlue()));
- changeIsLocal = false;
- }
- }
-
- public ColorRectPane() {
- getStyleClass().add("color-rect-pane");
- customColorProperty().addListener((ov, t, t1) -> colorChanged());
- colorRectIndicator = new Region();
- colorRectIndicator.setId("color-rect-indicator");
- colorRectIndicator.setManaged(false);
- colorRectIndicator.setMouseTransparent(true);
- colorRectIndicator.setCache(true);
- var stackPane = new StackPane();
- colorRect = new StackPane() {
- @Override
- public Orientation getContentBias() {
- return Orientation.VERTICAL;
- }
-
- @Override
- protected double computePrefWidth(double height) {
- return height;
- }
-
- @Override
- protected double computeMaxWidth(double height) {
- return height;
- }
- };
- colorRect.getStyleClass().addAll("color-rect", "transparent-pattern");
- var colorRectHue = new Pane();
- colorRectHue.backgroundProperty().bind(new BindingObjectBinding<>(hue) {
- @Override
- protected Background computeValue() {
- return new Background(new BackgroundFill(
- Color.hsb(hue.getValue(), 1.0D, 1.0D),
- CornerRadii.EMPTY, Insets.EMPTY));
- }
- });
- var colorRectOverlayOne = new Pane();
- colorRectOverlayOne.getStyleClass().add("color-rect");
- colorRectOverlayOne.setBackground(new Background(new BackgroundFill(
- new LinearGradient(0.0D, 0.0D, 1.0D, 0.0D, true, CycleMethod.NO_CYCLE, new Stop(0.0D, Color.rgb(255, 255, 255, 1.0D)),
- new Stop(1.0D, Color.rgb(255, 255, 255, 0.0D))), CornerRadii.EMPTY, Insets.EMPTY)));
- EventHandler rectMouseHandler = event -> {
- var x = event.getX();
- var y = event.getY();
- sat.set(clamp(x / colorRect.getWidth()) * 100.0D);
- bright.set(100.0D - clamp(y / colorRect.getHeight()) * 100.0D);
- };
- var colorRectOverlayTwo = new Pane();
- colorRectOverlayTwo.getStyleClass().addAll("color-rect");
- colorRectOverlayTwo.setBackground(new Background(new BackgroundFill(
- new LinearGradient(0.0D, 0.0D, 0.0D, 1.0D, true, CycleMethod.NO_CYCLE, new Stop(0.0D, Color.rgb(0, 0, 0, 0.0D)), new Stop(1.0D, Color.rgb(0, 0, 0, 1.0D))),
- CornerRadii.EMPTY, Insets.EMPTY)));
- colorRectOverlayTwo.setOnMouseDragged(rectMouseHandler);
- colorRectOverlayTwo.setOnMousePressed(rectMouseHandler);
- var colorRectBlackBorder = new Pane();
- colorRectBlackBorder.setMouseTransparent(true);
- colorRectBlackBorder.getStyleClass().addAll("color-rect", "color-rect-border");
- colorBar = new Pane();
- colorBar.getStyleClass().add("color-bar");
- colorBar.setBackground(new Background(new BackgroundFill(createHueGradient(), CornerRadii.EMPTY, Insets.EMPTY)));
- var colorBarIndicator = new Region();
- colorBarIndicator.setId("color-bar-indicator");
- colorBarIndicator.setMouseTransparent(true);
- colorBarIndicator.setCache(true);
- colorRectIndicator.layoutXProperty().bind(sat.divide(100).multiply(colorRect.widthProperty()));
- colorRectIndicator.layoutYProperty()
- .bind(Bindings.subtract(1, bright.divide(100)).multiply(colorRect.heightProperty()));
- colorBarIndicator.layoutYProperty().bind(hue.divide(360).multiply(colorBar.heightProperty()));
- stackPane.opacityProperty().bind(alpha.divide(100));
- EventHandler barMouseHandler = event -> {
- var y = event.getY();
- hue.set(clamp(y / colorRect.getHeight()) * 360.0D);
- };
- colorBar.setOnMouseDragged(barMouseHandler);
- colorBar.setOnMousePressed(barMouseHandler);
- colorBar.getChildren().setAll(colorBarIndicator);
- stackPane.getChildren().setAll(colorRectHue, colorRectOverlayOne, colorRectOverlayTwo);
- colorRect.getChildren().setAll(stackPane, colorRectBlackBorder, colorRectIndicator);
- HBox.setHgrow(colorRect, Priority.SOMETIMES);
- getChildren().addAll(colorRect, colorBar);
- }
-
- @Override
- protected void layoutChildren() {
- super.layoutChildren();
- colorRectIndicator.autosize();
- var size = Math.min(colorRect.getWidth(), colorRect.getHeight());
- colorRect.resize(size, size);
- colorBar.resize(colorBar.getWidth(), size);
- }
- }
-
- private class ControlsPane extends VBox {
-
- private final ToggleButton hsbButton;
-
- private final ToggleButton rgbButton;
-
- private final Label[] labels = new Label[4];
-
- private final Slider[] sliders = new Slider[4];
-
- private final IntegerField[] fields = new IntegerField[4];
-
- private final Property[] bindedProperties;
-
- private void showHSBSettings() {
- set(0, getString("hue_colon"), 360, colorRectPane.hue);
- set(1, getString("saturation_colon"), 100, colorRectPane.sat);
- set(2, getString("brightness_colon"), 100, colorRectPane.bright);
- }
-
- private void showRGBSettings() {
- set(0, getString("red_colon"), 255, colorRectPane.red);
- set(1, getString("green_colon"), 255, colorRectPane.green);
- set(2, getString("blue_colon"), 255, colorRectPane.blue);
- }
-
- private void showWebSettings() {
- labels[0].setText(getString("web_colon"));
- }
-
- public ControlsPane() {
- bindedProperties = new Property[4];
- getStyleClass().add("controls-pane");
- var newColorRect = new Region();
- newColorRect.getStyleClass().add("color-rect");
- newColorRect.setId("new-color");
- newColorRect.backgroundProperty().bind(new BindingObjectBinding<>(customColorProperty) {
- @Override
- protected Background computeValue() {
- return new Background(
- new BackgroundFill(customColorProperty.get(), CornerRadii.EMPTY, Insets.EMPTY));
- }
- });
- var newColorLabel = new Label("Color");
- var whiteBox = new Region();
- whiteBox.getStyleClass().add("customcolor-controls-background");
- hsbButton = new ToggleButton(getString("colorType.hsb"));
- hsbButton.getStyleClass().add("left-pill");
- rgbButton = new ToggleButton(getString("colorType.rgb"));
- rgbButton.getStyleClass().add("center-pill");
- var webButton = new ToggleButton(getString("colorType.web"));
- webButton.getStyleClass().add("right-pill");
- var group = new ToggleGroup();
- var hBox = new HBox();
- hBox.setAlignment(Pos.CENTER);
- hBox.getChildren().addAll(hsbButton, rgbButton, webButton);
- var leftSpacer = new Region();
- leftSpacer.setId("spacer-side");
- var rightSpacer = new Region();
- rightSpacer.setId("spacer-side");
- var bottomSpacer = new Region();
- bottomSpacer.setId("spacer-bottom");
- var currentAndNewColor = new GridPane();
- currentAndNewColor.getColumnConstraints().addAll(new ColumnConstraints());
- currentAndNewColor.getColumnConstraints().get(0).setHgrow(Priority.ALWAYS);
- currentAndNewColor.getRowConstraints().addAll(new RowConstraints(), new RowConstraints(), new RowConstraints());
- currentAndNewColor.getRowConstraints().get(2).setVgrow(Priority.ALWAYS);
- var labelCenterer = new HBox(newColorLabel);
- labelCenterer.setAlignment(Pos.CENTER);
- currentAndNewColor.getStyleClass().add("current-new-color-grid");
- currentAndNewColor.add(labelCenterer, 0, 0);
- currentAndNewColor.add(newColorRect, 0, 2);
- currentAndNewColor.setPrefHeight(80.0D);
- currentAndNewColor.setMaxHeight(80.0D);
- var settingsPane = new GridPane();
- settingsPane.setMaxHeight(Double.MAX_VALUE);
- VBox.setVgrow(settingsPane, Priority.ALWAYS);
- settingsPane.setId("settings-pane");
- settingsPane.getColumnConstraints()
- .addAll(new ColumnConstraints(), new ColumnConstraints(), new ColumnConstraints(), new ColumnConstraints(), new ColumnConstraints(),
- new ColumnConstraints());
- settingsPane.getColumnConstraints().get(0).setHgrow(Priority.NEVER);
- settingsPane.getColumnConstraints().get(2).setHgrow(Priority.ALWAYS);
- settingsPane.getColumnConstraints().get(3).setHgrow(Priority.NEVER);
- settingsPane.getColumnConstraints().get(4).setHgrow(Priority.NEVER);
- settingsPane.getColumnConstraints().get(5).setHgrow(Priority.NEVER);
- settingsPane.add(whiteBox, 0, 0, 6, 5);
- settingsPane.add(hBox, 0, 0, 6, 1);
- settingsPane.add(leftSpacer, 0, 0);
- settingsPane.add(rightSpacer, 5, 0);
- settingsPane.add(bottomSpacer, 0, 4);
- var webField = new WebColorField();
- webField.getStyleClass().add("web-field");
- webField.setSkin(new WebColorFieldSkin(webField));
- webField.valueProperty().bindBidirectional(customColorProperty);
- webField.visibleProperty().bind(group.selectedToggleProperty().isEqualTo(webButton));
- settingsPane.add(webField, 2, 1);
- for (var i = 0; i < 4; i++) {
- labels[i] = new Label();
- labels[i].getStyleClass().add("settings-label");
- sliders[i] = new Slider();
- fields[i] = new IntegerField();
- fields[i].getStyleClass().add("color-input-field");
- fields[i].setSkin(new IntegerFieldSkin(fields[i]));
- var units = new Label[4];
- units[i] = new Label((i == 0) ? "°" : "%");
- units[i].getStyleClass().add("settings-unit");
- if (i > 0 && i < 3)
- labels[i].visibleProperty().bind(group.selectedToggleProperty().isNotEqualTo(webButton));
- if (i < 3) {
- sliders[i].visibleProperty().bind(group.selectedToggleProperty().isNotEqualTo(webButton));
- fields[i].visibleProperty().bind(group.selectedToggleProperty().isNotEqualTo(webButton));
- units[i].visibleProperty().bind(group.selectedToggleProperty().isEqualTo(hsbButton));
- }
- var row = 1 + i;
- if (i == 3)
- row++;
- if (i != 3) {
- settingsPane.add(labels[i], 1, row);
- settingsPane.add(sliders[i], 2, row);
- settingsPane.add(fields[i], 3, row);
- settingsPane.add(units[i], 4, row);
- }
- }
- set(3, getString("opacity_colon"), 100, colorRectPane.alpha);
- hsbButton.setToggleGroup(group);
- rgbButton.setToggleGroup(group);
- webButton.setToggleGroup(group);
- group.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
- if (newValue == null) {
- group.selectToggle(oldValue);
- } else if (Objects.equals(newValue, hsbButton)) {
- showHSBSettings();
- } else if (Objects.equals(newValue, rgbButton)) {
- showRGBSettings();
- } else {
- showWebSettings();
- }
- });
- group.selectToggle(hsbButton);
- var spacer = new VBox();
- VBox.setVgrow(spacer, Priority.ALWAYS);
- getChildren().addAll(currentAndNewColor, spacer, settingsPane);
- }
-
- private void set(int row, String caption, int maxValue, Property prop) {
- labels[row].setText(caption);
- if (bindedProperties[row] != null) {
- sliders[row].valueProperty().unbindBidirectional(bindedProperties[row]);
- fields[row].valueProperty().unbindBidirectional(bindedProperties[row]);
- }
- sliders[row].setMax(maxValue);
- sliders[row].valueProperty().bindBidirectional(prop);
- labels[row].setLabelFor(sliders[row]);
- fields[row].setMaxValue(maxValue);
- fields[row].valueProperty().bindBidirectional(prop);
- bindedProperties[row] = prop;
- }
- }
-
- static double clamp(double value) {
- return (value < 0.0D) ? 0.0D : Math.min(value, 1.0D);
- }
-
- private static LinearGradient createHueGradient() {
- var stops = new Stop[255];
- for (var y = 0; y < 255; y++) {
- var offset = 1.0D - 0.00392156862745098D * y;
- var h = (int) (y / 255.0D * 360.0D);
- stops[y] = new Stop(offset, Color.hsb(h, 1.0D, 1.0D));
- }
- return new LinearGradient(0.0D, 1.0D, 0.0D, 0.0D, true, CycleMethod.NO_CYCLE, stops);
- }
-
- private static int doubleToInt(double value) {
- return (int) (value * 255.0D + 0.5D);
- }
-
- private abstract static class BindingObjectBinding extends ObjectBinding {
- protected BindingObjectBinding(Observable... obs) {
- bind(obs);
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/colorpicker/HueSlider.java b/src/main/java/com/getpcpanel/ui/colorpicker/HueSlider.java
deleted file mode 100644
index 07c890ab..00000000
--- a/src/main/java/com/getpcpanel/ui/colorpicker/HueSlider.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.getpcpanel.ui.colorpicker;
-
-import javafx.beans.property.IntegerProperty;
-import javafx.beans.property.SimpleIntegerProperty;
-import javafx.event.EventHandler;
-import javafx.geometry.Insets;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.Background;
-import javafx.scene.layout.BackgroundFill;
-import javafx.scene.layout.CornerRadii;
-import javafx.scene.layout.Pane;
-import javafx.scene.paint.Color;
-import javafx.scene.paint.CycleMethod;
-import javafx.scene.paint.LinearGradient;
-import javafx.scene.paint.Paint;
-import javafx.scene.paint.Stop;
-import javafx.scene.shape.Circle;
-
-public class HueSlider extends Pane {
- private static final int MAX_HUE = 255;
-
- private final IntegerProperty hue = new SimpleIntegerProperty();
-
- public HueSlider() {
- getStyleClass().add("color-bar");
- setBackground(new Background(new BackgroundFill(createHueGradient(),
- CornerRadii.EMPTY, Insets.EMPTY)));
- setMinHeight(20.0D);
- var colorBarIndicator = new Circle(10.0D);
- colorBarIndicator.setFill(Paint.valueOf("#25262A"));
- colorBarIndicator.setId("color-bar-indicator");
- colorBarIndicator.setMouseTransparent(true);
- colorBarIndicator.setCache(true);
- colorBarIndicator.layoutXProperty().bind(hue.multiply(widthProperty()).divide(MAX_HUE));
- EventHandler barMouseHandler = event -> {
- var x = event.getX();
- hue.set((int) (clamp(x / getWidth()) * 255.0D));
- };
- setOnMouseDragged(barMouseHandler);
- setOnMousePressed(barMouseHandler);
- getChildren().setAll(colorBarIndicator);
- colorBarIndicator.setLayoutY(10.0D);
- }
-
- public IntegerProperty getHueProperty() {
- return hue;
- }
-
- public int getHue() {
- return hue.get();
- }
-
- public void setHue(int h) {
- hue.set(h);
- }
-
- private static LinearGradient createHueGradient() {
- var stops = new Stop[255];
- for (var y = 0; y < 255; y++) {
- var offset = 1.0D - 0.00392156862745098D * y;
- var h = (int) (y / 255.0D * 360.0D);
- stops[y] = new Stop(offset, Color.hsb(h, 1.0D, 1.0D));
- }
- return new LinearGradient(1.0D, 0.0D, 0.0D, 0.0D, true, CycleMethod.NO_CYCLE, stops);
- }
-
- static double clamp(double value) {
- return (value < 0.0D) ? 0.0D : ((value > 1.0D) ? 1.0D : value);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/colorpicker/InputField.java b/src/main/java/com/getpcpanel/ui/colorpicker/InputField.java
deleted file mode 100644
index 6d569f37..00000000
--- a/src/main/java/com/getpcpanel/ui/colorpicker/InputField.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package com.getpcpanel.ui.colorpicker;
-
-import javafx.beans.property.BooleanProperty;
-import javafx.beans.property.IntegerProperty;
-import javafx.beans.property.IntegerPropertyBase;
-import javafx.beans.property.ObjectProperty;
-import javafx.beans.property.ObjectPropertyBase;
-import javafx.beans.property.SimpleBooleanProperty;
-import javafx.beans.property.StringProperty;
-import javafx.beans.property.StringPropertyBase;
-import javafx.event.ActionEvent;
-import javafx.event.EventHandler;
-import javafx.scene.control.Control;
-
-abstract class InputField extends Control {
- public static final int DEFAULT_PREF_COLUMN_COUNT = 12;
-
- private final BooleanProperty editable = new SimpleBooleanProperty(this, "editable", true);
-
- public final boolean isEditable() {
- return editable.getValue();
- }
-
- public final void setEditable(boolean value) {
- editable.setValue(value);
- }
-
- public final BooleanProperty editableProperty() {
- return editable;
- }
-
- private final StringProperty promptText = new StringPropertyBase("") {
- @Override
- protected void invalidated() {
- var txt = get();
- if (txt != null && txt.contains("\n")) {
- txt = txt.replace("\n", "");
- set(txt);
- }
- }
-
- @Override
- public Object getBean() {
- return InputField.this;
- }
-
- @Override
- public String getName() {
- return "promptText";
- }
- };
-
- public final StringProperty promptTextProperty() {
- return promptText;
- }
-
- public final String getPromptText() {
- return promptText.get();
- }
-
- public final void setPromptText(String value) {
- promptText.set(value);
- }
-
- private final IntegerProperty prefColumnCount = new IntegerPropertyBase(DEFAULT_PREF_COLUMN_COUNT) {
- private int oldValue = get();
-
- @Override
- protected void invalidated() {
- var value = get();
- if (value < 0) {
- if (isBound())
- unbind();
- set(oldValue);
- throw new IllegalArgumentException("value cannot be negative.");
- }
- oldValue = value;
- }
-
- @Override
- public Object getBean() {
- return InputField.this;
- }
-
- @Override
- public String getName() {
- return "prefColumnCount";
- }
- };
-
- public final IntegerProperty prefColumnCountProperty() {
- return prefColumnCount;
- }
-
- public final int getPrefColumnCount() {
- return prefColumnCount.getValue();
- }
-
- public final void setPrefColumnCount(int value) {
- prefColumnCount.setValue(value);
- }
-
- private final ObjectProperty> onAction = new ObjectPropertyBase<>() {
- @Override
- protected void invalidated() {
- setEventHandler(ActionEvent.ACTION, get());
- }
-
- @Override
- public Object getBean() {
- return InputField.this;
- }
-
- @Override
- public String getName() {
- return "onAction";
- }
- };
-
- public final ObjectProperty> onActionProperty() {
- return onAction;
- }
-
- public final EventHandler getOnAction() {
- return onActionProperty().get();
- }
-
- public final void setOnAction(EventHandler value) {
- onActionProperty().set(value);
- }
-
- protected InputField() {
- getStyleClass().setAll("input-field");
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/colorpicker/InputFieldSkin.java b/src/main/java/com/getpcpanel/ui/colorpicker/InputFieldSkin.java
deleted file mode 100644
index 7a33c42e..00000000
--- a/src/main/java/com/getpcpanel/ui/colorpicker/InputFieldSkin.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.getpcpanel.ui.colorpicker;
-
-import com.sun.javafx.event.EventDispatchChainImpl;
-
-import javafx.beans.InvalidationListener;
-import javafx.event.EventDispatchChain;
-import javafx.scene.Node;
-import javafx.scene.control.Skin;
-import javafx.scene.control.TextField;
-
-abstract class InputFieldSkin implements Skin {
- protected InputField control;
-
- private InnerTextField textField;
-
- private final InvalidationListener InputFieldFocusListener;
-
- private final InvalidationListener InputFieldStyleClassListener;
-
- protected InputFieldSkin(InputField control) {
- this.control = control;
- textField = new InnerTextField() {
- @Override
- public void replaceText(int start, int end, String text) {
- var t = (textField.getText() == null) ? "" : textField.getText();
- t = t.substring(0, start) + text + t.substring(end);
- if (accept(t))
- super.replaceText(start, end, text);
- }
-
- @Override
- public void replaceSelection(String text) {
- var t = (textField.getText() == null) ? "" : textField.getText();
- var start = Math.min(textField.getAnchor(), textField.getCaretPosition());
- var end = Math.max(textField.getAnchor(), textField.getCaretPosition());
- t = t.substring(0, start) + text + t.substring(end);
- if (accept(t))
- super.replaceSelection(text);
- }
- };
- textField.setId("input-text-field");
- textField.setFocusTraversable(false);
- control.getStyleClass().addAll(textField.getStyleClass());
- textField.getStyleClass().setAll(control.getStyleClass());
- control.getStyleClass().addListener(InputFieldStyleClassListener = (observable -> textField.getStyleClass().setAll(control.getStyleClass())));
- textField.promptTextProperty().bind(control.promptTextProperty());
- textField.prefColumnCountProperty().bind(control.prefColumnCountProperty());
- textField.textProperty().addListener(observable -> updateValue());
- control.focusedProperty().addListener(InputFieldFocusListener = (observable -> textField.handleFocus(control.isFocused())));
- updateText();
- }
-
- @Override
- public InputField getSkinnable() {
- return control;
- }
-
- @Override
- public Node getNode() {
- return textField;
- }
-
- @Override
- public void dispose() {
- control.getStyleClass().removeListener(InputFieldStyleClassListener);
- control.focusedProperty().removeListener(InputFieldFocusListener);
- textField = null;
- }
-
- protected TextField getTextField() {
- return textField;
- }
-
- protected abstract boolean accept(String paramString);
-
- protected abstract void updateText();
-
- protected abstract void updateValue();
-
- private class InnerTextField extends TextField {
- private InnerTextField() {
- }
-
- public void handleFocus(boolean b) {
- setFocused(b);
- }
-
- @Override
- public EventDispatchChain buildEventDispatchChain(EventDispatchChain tail) {
- var eventDispatchChainImpl = new EventDispatchChainImpl();
- eventDispatchChainImpl.append(textField.getEventDispatcher());
- return eventDispatchChainImpl;
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/colorpicker/IntegerField.java b/src/main/java/com/getpcpanel/ui/colorpicker/IntegerField.java
deleted file mode 100644
index 56c60fc4..00000000
--- a/src/main/java/com/getpcpanel/ui/colorpicker/IntegerField.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.getpcpanel.ui.colorpicker;
-
-import javafx.beans.property.IntegerProperty;
-import javafx.beans.property.SimpleIntegerProperty;
-import javafx.scene.control.Skin;
-
-class IntegerField extends InputField {
- private final IntegerProperty value = new SimpleIntegerProperty(this, "value");
-
- public final int getValue() {
- return value.get();
- }
-
- public final void setValue(int value) {
- this.value.set(value);
- }
-
- public final IntegerProperty valueProperty() {
- return value;
- }
-
- private final IntegerProperty maxValue = new SimpleIntegerProperty(this, "maxValue", -1);
-
- public final int getMaxValue() {
- return maxValue.get();
- }
-
- public final void setMaxValue(int maxVal) {
- maxValue.set(maxVal);
- }
-
- public final IntegerProperty maxValueProperty() {
- return maxValue;
- }
-
- public IntegerField() {
- this(-1);
- }
-
- public IntegerField(int maxVal) {
- getStyleClass().setAll("integer-field");
- setMaxValue(maxVal);
- }
-
- @Override
- protected Skin> createDefaultSkin() {
- return new IntegerFieldSkin(this);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/colorpicker/IntegerFieldSkin.java b/src/main/java/com/getpcpanel/ui/colorpicker/IntegerFieldSkin.java
deleted file mode 100644
index 06fe40d8..00000000
--- a/src/main/java/com/getpcpanel/ui/colorpicker/IntegerFieldSkin.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.getpcpanel.ui.colorpicker;
-
-import javafx.application.Platform;
-import javafx.beans.InvalidationListener;
-import javafx.scene.Node;
-
-class IntegerFieldSkin extends InputFieldSkin {
- private final InvalidationListener integerFieldValueListener;
-
- public IntegerFieldSkin(IntegerField control) {
- super(control);
- control.valueProperty().addListener(integerFieldValueListener = (observable -> updateText()));
- }
-
- @Override
- public IntegerField getSkinnable() {
- return (IntegerField) control;
- }
-
- @Override
- public Node getNode() {
- return getTextField();
- }
-
- @Override
- public void dispose() {
- ((IntegerField) control).valueProperty().removeListener(integerFieldValueListener);
- super.dispose();
- }
-
- @Override
- protected boolean accept(String text) {
- if (text.isEmpty())
- return true;
- if (text.matches("[0-9]*"))
- try {
- Integer.parseInt(text);
- var value = Integer.parseInt(text);
- var maxValue = ((IntegerField) control).getMaxValue();
- return maxValue == -1 || (value <= maxValue);
- } catch (NumberFormatException numberFormatException) {
- }
- return false;
- }
-
- @Override
- protected void updateText() {
- getTextField().setText(String.valueOf(((IntegerField) control).getValue()));
- }
-
- @Override
- protected void updateValue() {
- var value = ((IntegerField) control).getValue();
- var text = (getTextField().getText() == null) ? "" : getTextField().getText().trim();
- try {
- var newValue = Integer.parseInt(text);
- if (newValue != value)
- ((IntegerField) control).setValue(newValue);
- } catch (NumberFormatException ex) {
- ((IntegerField) control).setValue(0);
- Platform.runLater(() -> getTextField().positionCaret(1));
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/colorpicker/WebColorField.java b/src/main/java/com/getpcpanel/ui/colorpicker/WebColorField.java
deleted file mode 100644
index 6ff31123..00000000
--- a/src/main/java/com/getpcpanel/ui/colorpicker/WebColorField.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.getpcpanel.ui.colorpicker;
-
-import javafx.beans.property.ObjectProperty;
-import javafx.beans.property.SimpleObjectProperty;
-import javafx.scene.control.Skin;
-import javafx.scene.paint.Color;
-
-class WebColorField extends InputField {
- private final ObjectProperty value = new SimpleObjectProperty<>(this, "value");
-
- public final Color getValue() {
- return value.get();
- }
-
- public final void setValue(Color value) {
- this.value.set(value);
- }
-
- public final ObjectProperty valueProperty() {
- return value;
- }
-
- public WebColorField() {
- getStyleClass().setAll("webcolor-field");
- }
-
- @Override
- protected Skin> createDefaultSkin() {
- return new WebColorFieldSkin(this);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/colorpicker/WebColorFieldSkin.java b/src/main/java/com/getpcpanel/ui/colorpicker/WebColorFieldSkin.java
deleted file mode 100644
index c6b31a50..00000000
--- a/src/main/java/com/getpcpanel/ui/colorpicker/WebColorFieldSkin.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.getpcpanel.ui.colorpicker;
-
-import java.util.Locale;
-
-import com.getpcpanel.util.Util;
-
-import javafx.beans.InvalidationListener;
-import javafx.geometry.NodeOrientation;
-import javafx.scene.Node;
-import javafx.scene.paint.Color;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-class WebColorFieldSkin extends InputFieldSkin {
- private final InvalidationListener integerFieldValueListener;
-
- private boolean noChangeInValue;
-
- public WebColorFieldSkin(WebColorField control) {
- super(control);
- control.valueProperty().addListener(integerFieldValueListener = (observable -> updateText()));
- getTextField().setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
- }
-
- @Override
- public WebColorField getSkinnable() {
- return (WebColorField) control;
- }
-
- @Override
- public Node getNode() {
- return getTextField();
- }
-
- @Override
- public void dispose() {
- ((WebColorField) control).valueProperty().removeListener(integerFieldValueListener);
- super.dispose();
- }
-
- @Override
- protected boolean accept(String text) {
- if (text.length() == 0)
- return true;
- return text.matches("#[a-fA-F0-9]{0,6}") || text.matches("[a-fA-F0-9]{0,6}");
- }
-
- @Override
- protected void updateText() {
- var color = ((WebColorField) control).getValue();
- if (color == null)
- color = Color.BLACK;
- getTextField().setText(Util.formatHexString(color));
- }
-
- @Override
- protected void updateValue() {
- if (noChangeInValue)
- return;
- var value = ((WebColorField) control).getValue();
- var text = (getTextField().getText() == null) ? "" : getTextField().getText().trim().toUpperCase(Locale.ROOT);
- if (text.matches("#[A-F0-9]{6}") || text.matches("[A-F0-9]{6}"))
- try {
- var newValue = (text.charAt(0) == '#') ? Color.web(text) : Color.web("#" + text);
- if (!newValue.equals(value)) {
- ((WebColorField) control).setValue(newValue);
- } else {
- noChangeInValue = true;
- getTextField().setText(Util.formatHexString(newValue));
- noChangeInValue = false;
- }
- } catch (IllegalArgumentException ex) {
- log.error("Failed to parse [{}]", text, ex);
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/ButtonCommandController.java b/src/main/java/com/getpcpanel/ui/command/ButtonCommandController.java
deleted file mode 100644
index 0b58237b..00000000
--- a/src/main/java/com/getpcpanel/ui/command/ButtonCommandController.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.getpcpanel.ui.command;
-
-import com.getpcpanel.commands.command.Command;
-
-public interface ButtonCommandController {
- Command buildCommand();
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/ButtonController.java b/src/main/java/com/getpcpanel/ui/command/ButtonController.java
deleted file mode 100644
index 68da93b5..00000000
--- a/src/main/java/com/getpcpanel/ui/command/ButtonController.java
+++ /dev/null
@@ -1,341 +0,0 @@
-package com.getpcpanel.ui.command;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.springframework.stereotype.Component;
-import org.springframework.util.ReflectionUtils;
-
-import com.getpcpanel.commands.Commands;
-import com.getpcpanel.commands.CommandsType;
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandNoOp;
-import com.getpcpanel.commands.command.DialAction;
-import com.getpcpanel.commands.command.DialAction.DialCommandParams;
-import com.getpcpanel.hid.DialValueCalculator;
-import com.getpcpanel.profile.KnobSetting;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.FxHelper;
-import com.getpcpanel.ui.MacroControllerService;
-import com.getpcpanel.ui.MacroControllerService.ControllerInfo;
-import com.getpcpanel.ui.command.Cmd.Type;
-import com.getpcpanel.ui.command.DialCutoffOptions.DialCutoffOptionsParams;
-import com.getpcpanel.ui.graphviewer.GraphViewer;
-import com.getpcpanel.util.Images;
-
-import javafx.beans.binding.Bindings;
-import javafx.beans.property.StringProperty;
-import javafx.beans.value.ObservableValue;
-import javafx.collections.ListChangeListener.Change;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.geometry.Side;
-import javafx.scene.Node;
-import javafx.scene.control.Accordion;
-import javafx.scene.control.Button;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.ChoiceBox;
-import javafx.scene.control.ContextMenu;
-import javafx.scene.control.Label;
-import javafx.scene.control.MenuItem;
-import javafx.scene.control.TabPane;
-import javafx.scene.control.TextField;
-import javafx.scene.control.TitledPane;
-import javafx.scene.layout.BorderPane;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Priority;
-import javafx.scene.shape.SVGPath;
-import javafx.stage.Stage;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import lombok.Setter;
-import lombok.SneakyThrows;
-import lombok.extern.log4j.Log4j2;
-import one.util.streamex.StreamEx;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-public class ButtonController {
- private final MacroControllerService macroControllerService;
- private final FxHelper fxHelper;
-
- private Type cmdType;
- private CommandContext context;
- private final ContextMenu addMenu = new ContextMenu();
- @FXML @Getter private TabPane root;
-
- @FXML private Accordion commands;
- @FXML private Button addButton;
- @FXML private ChoiceBox commandsType;
- @Setter private Stage stage;
-
- public void initController(Type cmdType, CommandContext context, @Nullable Commands buttonData) {
- this.cmdType = cmdType;
- this.context = context;
- Commands.cmds(buttonData).forEach(this::add);
-
- var panes = commands.getPanes();
- if (!panes.isEmpty()) {
- commands.setExpandedPane(panes.get(0));
- }
-
- macroControllerService.getControllersForType(cmdType).forEach(ctrlr -> {
- if (!isEnabled(ctrlr)) {
- return;
- }
-
- var menuItem = new MenuItem(ctrlr.cmd().name());
- menuItem.setOnAction(ignored -> {
- add(ctrlr, null);
- commands.setExpandedPane(panes.get(panes.size() - 1));
- });
- addMenu.getItems().add(menuItem);
- });
- addButton.setContextMenu(addMenu);
-
- commandsType.getItems().addAll(CommandsType.values());
- if (buttonData != null) {
- commandsType.getSelectionModel().select(buttonData.getType());
- }
-
- if (cmdType == Type.button) {
- commands.getPanes().addListener(this::determineCommandsTypeVisible);
- determineCommandsTypeVisible(null);
- }
- }
-
- private void determineCommandsTypeVisible(@Nullable Change> change) {
- commandsType.setVisible(commands.getPanes().size() > 1);
- if (!commandsType.isVisible()) {
- commandsType.getSelectionModel().selectFirst();
- }
- }
-
- @SneakyThrows
- private static boolean isEnabled(@Nonnull ControllerInfo ctrlr) {
- return ReflectionUtils.accessibleConstructor(ctrlr.cmd().enabled()).newInstance().isEnabled();
- }
-
- private void add(Command cmd) {
- var controllerInfo = macroControllerService.getControllerForCommand(cmd.getClass());
- if (controllerInfo == null) {
- log.warn("Dial/button with {} found, but that command is not supported", cmd);
- return;
- }
- add(controllerInfo, cmd);
- }
-
- @SneakyThrows
- private void add(@Nonnull ControllerInfo info, @Nullable Command cmd) {
- var loader = fxHelper.getLoader(info.getFxml());
- var loaded = loader.load();
- var controller = loader.>getController();
- controller.postInit(context);
- HBox.setHgrow(loaded, Priority.ALWAYS);
-
- var pane = new TitledPane(null, loaded);
- var panelData = addPanelOptions(controller, pane, info.cmd().name(), cmd);
- pane.setUserData(panelData);
- commands.getPanes().add(pane);
-
- if (cmd != null) {
- controller.initFromCommand(cmd);
- }
- }
-
- private PanelData addPanelOptions(CommandController controller, @Nonnull TitledPane pane, String title, @Nullable Command cmd) {
- // Labels
- var titleOfTitledPane = new Label(title);
- var additionalLabel = buildAdditionalLabel(controller, pane);
- var labelsBox = new HBox(titleOfTitledPane, additionalLabel);
- labelsBox.setAlignment(Pos.CENTER_LEFT);
-
- // Buttons
- var buttonDelete = deleteButton(pane);
- var buttonUp = moveButton(pane, Images.chevronUp(), -1);
- var buttonDown = moveButton(pane, Images.chevronDown(), 1);
- var buttonCopy = copyButton(pane);
-
- var hbox = new HBox(buttonCopy, buttonUp, buttonDown, buttonDelete);
- var result = new PanelData(controller, cmd instanceof DialAction da ? da.getDialParams() : null);
-
- if (cmd instanceof DialAction da) {
- var invertCheck = addInvertCheck(result, hbox, da);
- addGraphViewer(result, controller, cmd, hbox, invertCheck);
- }
-
- var borderPane = new BorderPane();
- borderPane.setLeft(labelsBox);
- BorderPane.setAlignment(titleOfTitledPane, Pos.CENTER_LEFT);
- borderPane.setRight(hbox);
- borderPane.prefWidthProperty().bind(commands.widthProperty().subtract(40));
- pane.setGraphic(borderPane);
-
- return result;
- }
-
- private CheckBox addInvertCheck(PanelData result, HBox target, DialAction da) {
- var invertCheck = new CheckBox("Invert");
- HBox.setMargin(invertCheck, new Insets(3, 20, 0, 0));
-
- invertCheck.setSelected(da.isInvert());
- invertCheck.selectedProperty().addListener((obs, old, newValue) -> result.setParams(result.params.withInvert(newValue)));
-
- target.getChildren().add(0, invertCheck);
- return invertCheck;
- }
-
- private void addGraphViewer(PanelData panelData, CommandController controller, @Nonnull Command cmd, HBox hbox, CheckBox invertCheck) {
- if (!(cmd instanceof DialAction) || !(controller instanceof DialCommandController dc)) {
- return;
- }
-
- var graphViewer = new GraphViewer(new DialValueCalculator(new KnobSetting()), cmd);
- graphViewer.setPrefSize(75, 28);
-
- var graphBox = new HBox(graphViewer);
- HBox.setMargin(graphBox, new Insets(0, 10, 0, 0));
- hbox.getChildren().add(0, graphBox);
- graphViewer.setOnAction(event -> {
- var newParams = DialCutoffOptions.show(new DialCutoffOptionsParams(stage, panelData.params));
- newParams.ifPresent(params -> {
- panelData.setParams(params);
- invertCheck.setSelected(params.invert());
- graphViewer.setCmd(dc.buildCommand(params));
- graphViewer.redraw();
- });
- });
-
- invertCheck.selectedProperty().addListener((obs, old, newValue) -> {
- graphViewer.setCmd(dc.buildCommand(panelData.params));
- graphViewer.redraw();
- });
-
- panelData.setGraph(graphViewer);
- }
-
- public void setupGraphRenderer(TextField trimMin, TextField trimMax, CheckBox logarithmic) {
- trimMin.textProperty().addListener((obs, old, newValue) -> doUpdateGraphRenderer(trimMin.getText(), trimMax.getText(), logarithmic.isSelected()));
- trimMax.textProperty().addListener((obs, old, newValue) -> doUpdateGraphRenderer(trimMin.getText(), trimMax.getText(), logarithmic.isSelected()));
- logarithmic.selectedProperty().addListener((obs, old, newValue) -> doUpdateGraphRenderer(trimMin.getText(), trimMax.getText(), logarithmic.isSelected()));
- }
-
- private void doUpdateGraphRenderer(String trimMinStr, String trimMaxStr, boolean logarithmic) {
- var trimMin = NumberUtils.toInt(trimMinStr, 0);
- var trimMax = NumberUtils.toInt(trimMaxStr, 100);
-
- var knobSettings = new KnobSetting().setMinTrim(trimMin).setMaxTrim(trimMax).setLogarithmic(logarithmic);
- StreamEx.of(commands.getPanes())
- .map(Node::getUserData)
- .select(PanelData.class)
- .map(PanelData::getGraph)
- .nonNull()
- .forEach(graph -> {
- graph.setCalculator(new DialValueCalculator(knobSettings));
- graph.redraw();
- });
- }
-
- @Nonnull
- private Label buildAdditionalLabel(@Nonnull CommandController controller, @Nonnull TitledPane pane) {
- var additionalLabel = new Label();
- additionalLabel.setStyle("-fx-text-fill: #999;");
- additionalLabel.textProperty().bind(appendSemiColonBinding(controller.additionalLabelText()));
-
- // Hide when not needed
- var showProperty = Bindings.notEqual(pane, commands.expandedPaneProperty());
- additionalLabel.visibleProperty().bind(showProperty);
- additionalLabel.managedProperty().bind(showProperty);
- return additionalLabel;
- }
-
- private ObservableValue appendSemiColonBinding(StringProperty stringProperty) {
- // TODO: Make this a map call when using JavaFX 19
- // stringProperty.map(v -> StringUtils.isBlank(v) ? "" : ": " + v);
- return Bindings.createStringBinding(() -> StringUtils.isBlank(stringProperty.get()) ? "" : ": " + stringProperty.get(), stringProperty);
- }
-
- private Button deleteButton(@Nonnull TitledPane pane) {
- var buttonDelete = createButton(Images.delete());
- buttonDelete.setOnAction(event -> commands.getPanes().remove(pane));
- return buttonDelete;
- }
-
- private Button moveButton(@Nonnull TitledPane pane, SVGPath image, int idxChange) {
- var buttonMove = createButton(image);
- commands.getPanes().addListener((Change> c) -> showHideButton(buttonMove, commands.getPanes().size() > 1));
- buttonMove.setOnAction(event -> {
- var idx = commands.getPanes().indexOf(pane);
- commands.getPanes().remove(pane);
-
- var newIdx = Math.max(0, Math.min(commands.getPanes().size(), idx + idxChange));
- commands.getPanes().add(newIdx, pane);
- });
- return buttonMove;
- }
-
- private Button copyButton(TitledPane pane) {
- var buttonCopy = createButton(Images.copy());
- buttonCopy.setOnAction(event -> {
- var data = (PanelData) pane.getUserData();
- if (data.controller instanceof DialCommandController dc) {
- add(dc.buildCommand(data.params));
- } else if (data.controller instanceof ButtonCommandController bc) {
- add(bc.buildCommand());
- }
- commands.setExpandedPane(commands.getPanes().get(commands.getPanes().size() - 1));
-
- });
- return buttonCopy;
- }
-
- private Button createButton(SVGPath image) {
- var result = new Button("", image);
- result.setStyle("-fx-background-color: transparent;");
- return result;
- }
-
- private void showHideButton(Button btn, boolean visible) {
- btn.setVisible(visible);
- btn.setManaged(visible);
- }
-
- public Commands determineButtonCommand() {
- var userdata = StreamEx.of(commands.getPanes()).map(Node::getUserData);
-
- if (cmdType == Type.dial) {
- userdata = userdata.select(PanelData.class)
- .mapToEntry(PanelData::getController, PanelData::getParams)
- .selectKeys(DialCommandController.class)
- .mapKeyValue(DialCommandController::buildCommand);
- } else {
- userdata = userdata.select(PanelData.class).map(PanelData::getController).select(ButtonCommandController.class).map(ButtonCommandController::buildCommand);
- }
-
- var cmds = userdata.select(Command.class).remove(CommandNoOp.class::isInstance).toList();
- return new Commands(cmds, commandsType.getValue());
- }
-
- public void showActionsMenu(ActionEvent ignored) {
- addMenu.show(addButton, Side.TOP, 0, 0);
- }
-
- @Getter
- private static class PanelData {
- private final CommandController> controller;
-
- @Setter private GraphViewer graph;
- @Setter private DialCommandParams params;
-
- public PanelData(CommandController> controller, @Nullable DialCommandParams params) {
- this.controller = controller;
- this.params = params == null ? DialCommandParams.DEFAULT : params;
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/Cmd.java b/src/main/java/com/getpcpanel/ui/command/Cmd.java
deleted file mode 100644
index 76279303..00000000
--- a/src/main/java/com/getpcpanel/ui/command/Cmd.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.getpcpanel.ui.command;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-import com.getpcpanel.commands.command.Command;
-
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Cmd {
- String name();
-
- String fxml();
-
- Class extends Command>[] cmds();
-
- String os() default "*";
-
- Class extends CmdEnabled> enabled() default CmdEnabled.class;
-
- enum Type {
- button, dial
- }
-
- class CmdEnabled {
- public boolean isEnabled() {
- return true;
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/CommandContext.java b/src/main/java/com/getpcpanel/ui/command/CommandContext.java
deleted file mode 100644
index 890d303c..00000000
--- a/src/main/java/com/getpcpanel/ui/command/CommandContext.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.getpcpanel.ui.command;
-
-import com.getpcpanel.profile.DeviceSave;
-import com.getpcpanel.profile.Profile;
-
-import javafx.stage.Stage;
-
-public record CommandContext(Stage stage, DeviceSave deviceSave, Profile profile) {
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/CommandController.java b/src/main/java/com/getpcpanel/ui/command/CommandController.java
deleted file mode 100644
index 63e945fd..00000000
--- a/src/main/java/com/getpcpanel/ui/command/CommandController.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.getpcpanel.ui.command;
-
-import java.util.Arrays;
-
-import com.getpcpanel.commands.command.Command;
-
-import javafx.beans.Observable;
-import javafx.beans.binding.Bindings;
-import javafx.beans.property.BooleanProperty;
-import javafx.beans.property.SimpleBooleanProperty;
-import javafx.beans.property.SimpleStringProperty;
-import javafx.beans.property.StringProperty;
-import javafx.scene.Node;
-
-public abstract class CommandController {
- private final BooleanProperty initialized = new SimpleBooleanProperty(false);
-
- public abstract void postInit(CommandContext context);
-
- public void initFromCommand(T cmd) {
- initialized.set(true);
- }
-
- public StringProperty additionalLabelText() {
- var old = determineDependencies();
- var dependencies = Arrays.copyOf(old, old.length + 1);
- dependencies[old.length] = initialized;
-
- var result = new SimpleStringProperty();
- result.bind(Bindings.createStringBinding(() -> buildLabel(), dependencies));
- return result;
- }
-
- protected abstract Observable[] determineDependencies();
-
- protected String buildLabel() {
- if (this instanceof DialCommandController dc) {
- return dc.buildLabelCommand().buildLabel();
- }
- if (this instanceof ButtonCommandController bc) {
- return bc.buildCommand().buildLabel();
- }
- return "";
- }
-
- protected void setVisible(Node node, boolean visible) {
- node.setVisible(visible);
- node.setManaged(visible);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/DialCommandController.java b/src/main/java/com/getpcpanel/ui/command/DialCommandController.java
deleted file mode 100644
index e78a255c..00000000
--- a/src/main/java/com/getpcpanel/ui/command/DialCommandController.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.getpcpanel.ui.command;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.DialAction.DialCommandParams;
-
-public interface DialCommandController {
- Command buildCommand(DialCommandParams params);
-
- default Command buildLabelCommand() {
- return buildCommand(DialCommandParams.DEFAULT);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/DialCutoffOptions.java b/src/main/java/com/getpcpanel/ui/command/DialCutoffOptions.java
deleted file mode 100644
index b7ba22a2..00000000
--- a/src/main/java/com/getpcpanel/ui/command/DialCutoffOptions.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.getpcpanel.ui.command;
-
-import java.util.Objects;
-import java.util.Optional;
-
-import javax.annotation.Nonnull;
-
-import org.apache.commons.lang3.math.NumberUtils;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.MainFX;
-import com.getpcpanel.commands.command.CommandBrightness;
-import com.getpcpanel.commands.command.CommandNoOp;
-import com.getpcpanel.commands.command.DialAction.DialCommandParams;
-import com.getpcpanel.hid.DialValueCalculator;
-import com.getpcpanel.profile.KnobSetting;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.FxHelper;
-import com.getpcpanel.ui.UIHelper;
-import com.getpcpanel.ui.UIInitializer;
-import com.getpcpanel.ui.graphviewer.GraphViewer;
-
-import javafx.application.Application;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.Scene;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.TextField;
-import javafx.scene.image.Image;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.VBox;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import lombok.SneakyThrows;
-
-@Component
-@Prototype
-public class DialCutoffOptions extends Application implements UIInitializer {
- @FXML private CheckBox invert;
- @FXML private VBox panel;
- @FXML private TextField moveStart;
- @FXML private TextField moveEnd;
- @FXML private HBox chartholder;
- private Stage stage;
- private Stage parentStage;
- private boolean okClicked;
- private GraphViewer graph;
-
- @SneakyThrows
- public static Optional show(DialCutoffOptionsParams params) {
- var res = MainFX.getBean(FxHelper.class).open(DialCutoffOptions.class, params);
- var afdStage = new Stage();
- res.start(afdStage);
-
- if (res.okClicked) {
- return Optional.of(res.buildResult());
- }
- return Optional.empty();
- }
-
- @Override
- public void initUI(@Nonnull DialCutoffOptionsParams args) {
- parentStage = args.parentStage;
- if (parentStage == null) {
- throw new IllegalStateException("Parent stage is required");
- }
- setInitialFieldValues(args.params);
-
- graph = new GraphViewer(new DialValueCalculator(new KnobSetting()), new CommandNoOp());
- graph.setPrefSize(400, 100);
- chartholder.getChildren().add(graph);
- keepGraphUpToDate();
- }
-
- private void keepGraphUpToDate() {
- moveStart.textProperty().addListener((observable, oldValue, newValue) -> updateGraph());
- moveEnd.textProperty().addListener((observable, oldValue, newValue) -> updateGraph());
- invert.selectedProperty().addListener((observable, oldValue, newValue) -> updateGraph());
- updateGraph();
- }
-
- private void updateGraph() {
- graph.setCmd(new CommandBrightness(buildResult()));
- graph.redraw();
- }
-
- private void setInitialFieldValues(DialCommandParams originalArgs) {
- invert.setSelected(originalArgs.invert());
-
- if (originalArgs.moveStart() != null) {
- moveStart.setText(String.valueOf(originalArgs.moveStart()));
- }
- if (originalArgs.moveEnd() != null) {
- moveEnd.setText(String.valueOf(originalArgs.moveEnd()));
- }
- }
-
- @Override
- public void start(Stage stage) throws Exception {
- this.stage = stage;
- UIHelper.closeOnEscape(stage);
- var scene = new Scene(panel);
- scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/assets/dark_theme.css")).toExternalForm());
- stage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResource("/assets/256x256.png")).toExternalForm()));
- stage.setScene(scene);
- stage.setTitle("Volume options");
-
- stage.initModality(Modality.WINDOW_MODAL);
- stage.initOwner(parentStage);
- stage.showAndWait();
- }
-
- @Nonnull
- private DialCommandParams buildResult() {
- var moveStartVal = NumberUtils.toInt(moveStart.getText(), 0);
- var moveEndVal = NumberUtils.toInt(moveEnd.getText(), 0);
- return new DialCommandParams(invert.isSelected(), moveStartVal, moveEndVal);
- }
-
- public void ok(ActionEvent actionEvent) {
- okClicked = true;
- stage.close();
- }
-
- public void closeButtonAction(ActionEvent actionEvent) {
- stage.close();
- }
-
- public record DialCutoffOptionsParams(Stage parentStage, DialCommandParams params) {
- public DialCutoffOptionsParams {
- if (params == null) {
- params = DialCommandParams.DEFAULT;
- }
- }
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/ObsEnabled.java b/src/main/java/com/getpcpanel/ui/command/ObsEnabled.java
deleted file mode 100644
index 6fb0339b..00000000
--- a/src/main/java/com/getpcpanel/ui/command/ObsEnabled.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.getpcpanel.ui.command;
-
-import com.getpcpanel.MainFX;
-import com.getpcpanel.obs.OBS;
-import com.getpcpanel.ui.command.Cmd.CmdEnabled;
-
-public class ObsEnabled extends CmdEnabled {
- @Override
- public boolean isEnabled() {
- return MainFX.getBean(OBS.class).isConnected();
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/VoiceMeeterEnabled.java b/src/main/java/com/getpcpanel/ui/command/VoiceMeeterEnabled.java
deleted file mode 100644
index 1e1d2ae6..00000000
--- a/src/main/java/com/getpcpanel/ui/command/VoiceMeeterEnabled.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.getpcpanel.ui.command;
-
-import com.getpcpanel.MainFX;
-import com.getpcpanel.ui.command.Cmd.CmdEnabled;
-import com.getpcpanel.voicemeeter.Voicemeeter;
-
-public class VoiceMeeterEnabled extends CmdEnabled {
- @Override
- public boolean isEnabled() {
- return MainFX.getBean(Voicemeeter.class).login();
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnApplicationDeviceToggleController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnApplicationDeviceToggleController.java
deleted file mode 100644
index 5612ac4d..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnApplicationDeviceToggleController.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import static com.getpcpanel.spring.OsHelper.WINDOWS;
-
-import java.util.List;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandVolumeApplicationDeviceToggle;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.AdvancedDevices;
-import com.getpcpanel.ui.PickProcessesController;
-import com.getpcpanel.ui.PickProcessesController.PickType;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.RadioButton;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Application Sound Device", fxml = "ApplicationDeviceToggle", cmds = CommandVolumeApplicationDeviceToggle.class, os = WINDOWS)
-public class BtnApplicationDeviceToggleController extends CommandController implements ButtonCommandController {
- @FXML private AdvancedDevices applicationDeviceDevicesController;
- @FXML private PickProcessesController applicationDeviceProcessesController;
- @FXML private RadioButton rdioApplicationDeviceFocus;
- @FXML private RadioButton rdioApplicationDeviceSpecific;
-
- @Override
- public void postInit(CommandContext context) {
- applicationDeviceProcessesController.setPickType(PickType.soundSource);
- applicationDeviceDevicesController.setAllowRemove(true);
- applicationDeviceDevicesController.setOnlyMedia(true);
- }
-
- @Override
- public void initFromCommand(CommandVolumeApplicationDeviceToggle cmd) {
- rdioApplicationDeviceSpecific.setSelected(!cmd.isFollowFocus());
- rdioApplicationDeviceFocus.setSelected(cmd.isFollowFocus());
- applicationDeviceProcessesController.setSelection(cmd.getProcesses());
- cmd.getDevices().forEach(applicationDeviceDevicesController::add);
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- var followFocus = rdioApplicationDeviceFocus.isSelected();
- var processes = followFocus ? List.of() : applicationDeviceProcessesController.getSelection();
- return new CommandVolumeApplicationDeviceToggle(processes, followFocus, applicationDeviceDevicesController.getEntries());
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] {
- applicationDeviceProcessesController.getObservable(),
- rdioApplicationDeviceFocus.selectedProperty(), rdioApplicationDeviceSpecific.selectedProperty()
- };
- }
-
- public void addApplicationDevice(ActionEvent ignored) {
- applicationDeviceDevicesController.add();
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnDefaultDeviceAdvancedController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnDefaultDeviceAdvancedController.java
deleted file mode 100644
index 990ecd32..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnDefaultDeviceAdvancedController.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import static com.getpcpanel.spring.OsHelper.WINDOWS;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandVolumeDefaultDeviceAdvanced;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.AdvancedDevices;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.fxml.FXML;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Default Device Advanced", fxml = "DefaultDeviceAdvanced", cmds = CommandVolumeDefaultDeviceAdvanced.class, os = WINDOWS)
-public class BtnDefaultDeviceAdvancedController extends CommandController implements ButtonCommandController {
- @FXML private AdvancedDevices defaultDeviceAdvancedController;
-
- @Override
- public void postInit(CommandContext context) {
- defaultDeviceAdvancedController.add();
- }
-
- @Override
- public void initFromCommand(CommandVolumeDefaultDeviceAdvanced cmd) {
- defaultDeviceAdvancedController.set(cmd.getName(), cmd.getMediaPb(), cmd.getMediaRec(), cmd.getCommunicationPb(), cmd.getCommunicationRec());
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- var entry = defaultDeviceAdvancedController.getEntries().get(0);
- return new CommandVolumeDefaultDeviceAdvanced(entry.name(), entry.mediaPlayback(), entry.mediaRecord(), entry.communicationPlayback(), entry.communicationRecord());
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[0];
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnDefaultDeviceController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnDefaultDeviceController.java
deleted file mode 100644
index 2306ae7b..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnDefaultDeviceController.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import static com.getpcpanel.commands.command.CommandNoOp.NOOP;
-
-import java.util.Collection;
-
-import javax.annotation.Nullable;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandVolumeDefaultDevice;
-import com.getpcpanel.cpp.AudioDevice;
-import com.getpcpanel.cpp.ISndCtrl;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.fxml.FXML;
-import javafx.scene.control.ChoiceBox;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-import one.util.streamex.StreamEx;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Sound Device", fxml = "DefaultDevice", cmds = CommandVolumeDefaultDevice.class)
-public class BtnDefaultDeviceController extends CommandController implements ButtonCommandController {
- private final ISndCtrl sndCtrl;
- private Collection allSoundDevices;
-
- @FXML private ChoiceBox sounddevices;
-
- @Override
- public void postInit(CommandContext context) {
- allSoundDevices = sndCtrl.getDevices();
- sounddevices.getItems().addAll(allSoundDevices);
- }
-
- @Override
- public void initFromCommand(CommandVolumeDefaultDevice cmd) {
- sounddevices.setValue(getSoundDeviceById(cmd.getDeviceId()));
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- return sounddevices.getValue() == null ? NOOP : new CommandVolumeDefaultDevice(sounddevices.getValue().id());
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] { sounddevices.valueProperty() };
- }
-
- @Nullable
- private AudioDevice getSoundDeviceById(String id) {
- return StreamEx.of(allSoundDevices).findFirst(sd -> sd.id().equals(id)).orElse(null);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnDefaultDeviceToggleController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnDefaultDeviceToggleController.java
deleted file mode 100644
index 786e1e74..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnDefaultDeviceToggleController.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import java.util.Collection;
-
-import javax.annotation.Nullable;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandVolumeDefaultDeviceToggle;
-import com.getpcpanel.cpp.AudioDevice;
-import com.getpcpanel.cpp.ISndCtrl;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.SoundDeviceExportFactory;
-import com.getpcpanel.ui.SoundDeviceImportFactory;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.collections.ListChangeListener;
-import javafx.fxml.FXML;
-import javafx.scene.control.ListView;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-import one.util.streamex.StreamEx;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Toggle Device", fxml = "DefaultDeviceToggle", cmds = CommandVolumeDefaultDeviceToggle.class)
-public class BtnDefaultDeviceToggleController extends CommandController implements ButtonCommandController {
- private final ISndCtrl sndCtrl;
- private Collection allSoundDevices;
- @FXML private ListView soundDevices2;
- @FXML private ListView soundDeviceSource;
-
- @Override
- public void postInit(CommandContext context) {
- allSoundDevices = sndCtrl.getDevices();
- soundDeviceSource.getItems().addAll(allSoundDevices);
- initDeviceToggleEvents();
- soundDevices2.setCellFactory(new SoundDeviceImportFactory(soundDevices2));
- }
-
- @Override
- public void initFromCommand(CommandVolumeDefaultDeviceToggle cmd) {
- var devices = StreamEx.of(cmd.getDevices()).map(this::getSoundDeviceById).toList();
- soundDevices2.getItems().addAll(devices);
- soundDeviceSource.getItems().removeAll(devices);
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- return new CommandVolumeDefaultDeviceToggle(soundDevices2.getItems().stream().map(AudioDevice::id).toList());
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] { soundDeviceSource.getChildrenUnmodifiable() };
- }
-
- private void initDeviceToggleEvents() {
- var sourceRenderer = new SoundDeviceExportFactory(soundDeviceSource);
- disableDeviceToggleOtherTypes(sourceRenderer);
- soundDeviceSource.setCellFactory(sourceRenderer);
- soundDeviceSource.getItems().addListener((ListChangeListener) change -> disableDeviceToggleOtherTypes(sourceRenderer));
- }
-
- private void disableDeviceToggleOtherTypes(SoundDeviceExportFactory sourceRenderer) {
- if (!soundDevices2.getItems().isEmpty()) {
- var df = soundDevices2.getItems().get(0).dataflow();
- sourceRenderer.setEnabledFlavor(df);
- } else {
- sourceRenderer.setEnabledFlavor(null);
- }
- soundDeviceSource.refresh();
- }
-
- @Nullable
- private AudioDevice getSoundDeviceById(String id) {
- return StreamEx.of(allSoundDevices).findFirst(sd -> sd.id().equals(id)).orElse(null);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnDeviceMuteController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnDeviceMuteController.java
deleted file mode 100644
index 533bd2b5..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnDeviceMuteController.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import java.util.Collection;
-
-import javax.annotation.Nullable;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandVolumeDeviceMute;
-import com.getpcpanel.cpp.AudioDevice;
-import com.getpcpanel.cpp.ISndCtrl;
-import com.getpcpanel.cpp.MuteType;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.ChoiceBox;
-import javafx.scene.control.RadioButton;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-import one.util.streamex.StreamEx;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Mute Device", fxml = "DeviceMute", cmds = CommandVolumeDeviceMute.class)
-public class BtnDeviceMuteController extends CommandController implements ButtonCommandController {
- private final ISndCtrl sndCtrl;
- private Collection allSoundDevices;
- @FXML private ChoiceBox muteSoundDevice;
- @FXML private RadioButton rdio_muteDevice_Default;
- @FXML private RadioButton rdio_muteDevice_Specific;
- @FXML private RadioButton rdio_muteDevice_mute;
- @FXML private RadioButton rdio_muteDevice_toggle;
- @FXML private RadioButton rdio_muteDevice_unmute;
-
- @Override
- public void postInit(CommandContext context) {
- allSoundDevices = sndCtrl.getDevices();
- muteSoundDevice.getItems().addAll(allSoundDevices);
- }
-
- @Override
- public void initFromCommand(CommandVolumeDeviceMute cmd) {
- if (StringUtils.equalsAny(StringUtils.defaultString(cmd.getDeviceId(), ""), "", "default")) {
- rdio_muteDevice_Default.setSelected(true);
- } else {
- rdio_muteDevice_Specific.setSelected(true);
- muteSoundDevice.setValue(getSoundDeviceById(cmd.getDeviceId()));
- }
- switch (cmd.getMuteType()) {
- case unmute -> rdio_muteDevice_unmute.setSelected(true);
- case mute -> rdio_muteDevice_mute.setSelected(true);
- case toggle -> rdio_muteDevice_toggle.setSelected(true);
- }
- onRadioButton(null);
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- var device = rdio_muteDevice_Default.isSelected() || muteSoundDevice.getValue() == null ? "" : muteSoundDevice.getValue().id();
- return new CommandVolumeDeviceMute(device, rdio_muteDevice_unmute.isSelected() ? MuteType.unmute : rdio_muteDevice_mute.isSelected() ? MuteType.mute : MuteType.toggle);
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] {
- muteSoundDevice.valueProperty(),
- rdio_muteDevice_Default.selectedProperty(),
- rdio_muteDevice_Specific.selectedProperty(),
- rdio_muteDevice_mute.selectedProperty(),
- rdio_muteDevice_toggle.selectedProperty(),
- rdio_muteDevice_unmute.selectedProperty()
- };
- }
-
- @Nullable
- private AudioDevice getSoundDeviceById(String id) {
- return StreamEx.of(allSoundDevices).findFirst(sd -> sd.id().equals(id)).orElse(null);
- }
-
- @FXML
- private void onRadioButton(@Nullable ActionEvent event) {
- muteSoundDevice.setDisable(!rdio_muteDevice_Specific.isSelected());
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnDeviceToggleAdvancedController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnDeviceToggleAdvancedController.java
deleted file mode 100644
index 410cb75a..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnDeviceToggleAdvancedController.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import static com.getpcpanel.spring.OsHelper.WINDOWS;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandVolumeDefaultDeviceToggleAdvanced;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.AdvancedDevices;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Toggle Device Advanced", fxml = "DeviceToggleAdvanced", cmds = CommandVolumeDefaultDeviceToggleAdvanced.class, os = WINDOWS)
-public class BtnDeviceToggleAdvancedController extends CommandController implements ButtonCommandController {
- @FXML private AdvancedDevices defaultDeviceToggleAdvancedController;
-
- @Override
- public void postInit(CommandContext context) {
- defaultDeviceToggleAdvancedController.setAllowRemove(true);
- }
-
- @Override
- public void initFromCommand(CommandVolumeDefaultDeviceToggleAdvanced cmd) {
- cmd.getDevices().forEach(defaultDeviceToggleAdvancedController::add);
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- return new CommandVolumeDefaultDeviceToggleAdvanced(defaultDeviceToggleAdvancedController.getEntries());
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[0];
- }
-
- public void addDefaultDeviceToggleAdvanced(ActionEvent ignored) {
- defaultDeviceToggleAdvancedController.add();
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnEndProgramController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnEndProgramController.java
deleted file mode 100644
index 493c3c1a..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnEndProgramController.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandEndProgram;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.PickProcessesController;
-import com.getpcpanel.ui.PickProcessesController.PickType;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.RadioButton;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "End Program", fxml = "EndProgram", cmds = CommandEndProgram.class)
-public class BtnEndProgramController extends CommandController implements ButtonCommandController {
- @FXML private RadioButton rdioEndFocusedProgram;
- @FXML private RadioButton rdioEndSpecificProgram;
- @FXML private PickProcessesController applicationEndProcessController;
-
- @Override
- public void postInit(CommandContext context) {
- applicationEndProcessController.setPickType(PickType.process);
- applicationEndProcessController.setSingle(true);
- }
-
- @Override
- public void initFromCommand(CommandEndProgram endProgram) {
- if (endProgram.isSpecific()) {
- rdioEndSpecificProgram.setSelected(true);
- applicationEndProcessController.setSelection(Set.of(endProgram.getName()));
- } else {
- rdioEndFocusedProgram.setSelected(true);
- }
- onRadioButton(null);
- super.initFromCommand(endProgram);
- }
-
- @Override
- public Command buildCommand() {
- var selection = applicationEndProcessController.getSelection();
- var program = selection.isEmpty() ? "" : selection.get(0);
- return new CommandEndProgram(rdioEndSpecificProgram.isSelected(), program);
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] { rdioEndFocusedProgram.selectedProperty(), rdioEndSpecificProgram.selectedProperty(), applicationEndProcessController.getObservable() };
- }
-
- @FXML
- private void onRadioButton(@Nullable ActionEvent event) {
- applicationEndProcessController.setDisable(!rdioEndSpecificProgram.isSelected());
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnFocusMuteController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnFocusMuteController.java
deleted file mode 100644
index d35d1e0d..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnFocusMuteController.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandVolumeFocusMute;
-import com.getpcpanel.cpp.MuteType;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.fxml.FXML;
-import javafx.scene.control.RadioButton;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Focus Mute", fxml = "FocusMute", cmds = CommandVolumeFocusMute.class)
-public class BtnFocusMuteController extends CommandController implements ButtonCommandController {
- @FXML private RadioButton rdio_focus_mute_mute;
- @FXML private RadioButton rdio_focus_mute_toggle;
- @FXML private RadioButton rdio_focus_mute_unmute;
-
- @Override
- public void postInit(CommandContext context) {
- }
-
- @Override
- public void initFromCommand(CommandVolumeFocusMute cmd) {
- switch (cmd.getMuteType()) {
- case unmute -> rdio_focus_mute_unmute.setSelected(true);
- case mute -> rdio_focus_mute_mute.setSelected(true);
- case toggle -> rdio_focus_mute_toggle.setSelected(true);
- }
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- return new CommandVolumeFocusMute(rdio_focus_mute_unmute.isSelected() ? MuteType.unmute : rdio_focus_mute_mute.isSelected() ? MuteType.mute : MuteType.toggle);
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] {
- rdio_focus_mute_mute.selectedProperty(),
- rdio_focus_mute_toggle.selectedProperty(),
- rdio_focus_mute_unmute.selectedProperty(),
- };
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnKeystrokeController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnKeystrokeController.java
deleted file mode 100644
index af96a7c8..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnKeystrokeController.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandKeystroke;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.TextField;
-import javafx.scene.input.KeyCode;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Keystroke", fxml = "Keystroke", cmds = CommandKeystroke.class)
-public class BtnKeystrokeController extends CommandController implements ButtonCommandController {
- @FXML private TextField keystrokeField;
- private boolean k_alt;
- private boolean k_ctrl;
- private boolean k_shift;
- private boolean k_win;
-
- @Override
- public void postInit(CommandContext context) {
- keystrokeField.setOnKeyPressed(event -> {
- var code = event.getCode();
- if (code == KeyCode.ALT) {
- k_alt = true;
- } else if (code == KeyCode.SHIFT) {
- k_shift = true;
- } else if (code == KeyCode.WINDOWS) {
- k_win = true;
- } else if (code == KeyCode.CONTROL) {
- k_ctrl = true;
- } else if (!k_alt && !k_shift && !k_win && !k_ctrl) {
- if (code.name().startsWith("DIGIT")) {
- keystrokeField.setText(code.name().substring(5));
- } else {
- keystrokeField.setText(code.name());
- }
- } else {
- var str = new StringBuilder();
- var bools = new boolean[] { k_ctrl, k_shift, k_alt, k_win };
- var keys = new String[] { "ctrl", "shift", "alt", "windows" };
- for (var i = 0; i < 4; i++) {
- if (bools[i])
- str.append(keys[i]).append(" + ");
- }
- if (code.name().startsWith("DIGIT")) {
- str.append(code.name().substring(5));
- } else {
- str.append(code.name());
- }
- keystrokeField.setText(str.toString());
- }
- });
- keystrokeField.setOnKeyReleased(event -> {
- var code = event.getCode();
- if (code == KeyCode.ALT) {
- k_alt = false;
- } else if (code == KeyCode.SHIFT) {
- k_shift = false;
- } else if (code == KeyCode.WINDOWS) {
- k_win = false;
- } else if (code == KeyCode.CONTROL) {
- k_ctrl = false;
- }
- });
- }
-
- @Override
- public void initFromCommand(CommandKeystroke cmd) {
- keystrokeField.setText(cmd.getKeystroke());
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- return new CommandKeystroke(keystrokeField.getText());
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] { keystrokeField.textProperty() };
- }
-
- @FXML
- private void clearKeystroke(ActionEvent event) {
- keystrokeField.setText("");
- k_alt = false;
- k_shift = false;
- k_win = false;
- k_ctrl = false;
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnMediaController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnMediaController.java
deleted file mode 100644
index f98f10f3..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnMediaController.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import static com.getpcpanel.spring.OsHelper.WINDOWS;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandMedia;
-import com.getpcpanel.commands.command.CommandMedia.VolumeButton;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.fxml.FXML;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.RadioButton;
-import javafx.scene.control.ToggleGroup;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Music Control", fxml = "Media", cmds = CommandMedia.class, os = WINDOWS)
-public class BtnMediaController extends CommandController implements ButtonCommandController {
- @FXML private ToggleGroup mediagroup;
- @FXML private CheckBox cmdMediaSpotify;
-
- @Override
- public void postInit(CommandContext context) {
- }
-
- @Override
- public void initFromCommand(CommandMedia cmd) {
- mediagroup.getToggles().get(switch (cmd.getButton()) {
- case playPause -> 0;
- case stop -> 1;
- case prev -> 2;
- case next -> 3;
- case mute -> 4;
- }
- ).setSelected(true);
- cmdMediaSpotify.setSelected(cmd.isSpotify());
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- return new CommandMedia(VolumeButton.valueOf(((RadioButton) mediagroup.getSelectedToggle()).getId()), cmdMediaSpotify.isSelected());
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] { mediagroup.selectedToggleProperty(), cmdMediaSpotify.selectedProperty() };
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnNoopController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnNoopController.java
deleted file mode 100644
index 8c02b205..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnNoopController.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandNoOp;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "No action", fxml = "Noop", cmds = CommandNoOp.class)
-public class BtnNoopController extends CommandController implements ButtonCommandController {
- @Override
- public void postInit(CommandContext context) {
- }
-
- @Override
- public Command buildCommand() {
- return CommandNoOp.NOOP;
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[0];
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnObsController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnObsController.java
deleted file mode 100644
index b69eeace..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnObsController.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import static com.getpcpanel.commands.command.CommandNoOp.NOOP;
-
-import javax.annotation.Nullable;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandObs;
-import com.getpcpanel.commands.command.CommandObsMuteSource;
-import com.getpcpanel.commands.command.CommandObsMuteSource.MuteType;
-import com.getpcpanel.commands.command.CommandObsSetScene;
-import com.getpcpanel.obs.OBS;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-import com.getpcpanel.ui.command.ObsEnabled;
-
-import javafx.beans.Observable;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.ChoiceBox;
-import javafx.scene.control.RadioButton;
-import javafx.scene.layout.Pane;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "OBS", fxml = "Obs", cmds = { CommandObsSetScene.class, CommandObsMuteSource.class }, enabled = ObsEnabled.class)
-public class BtnObsController extends CommandController implements ButtonCommandController {
- private final OBS obs;
-
- @FXML private ChoiceBox obsSetScene;
- @FXML private ChoiceBox obsSourceToMute;
- @FXML private Pane obsPaneMuteSource;
- @FXML private Pane obsPaneSetScene;
- @FXML private RadioButton obsMuteMute;
- @FXML private RadioButton obsMuteToggle;
- @FXML private RadioButton obsMuteUnmute;
- @FXML private RadioButton obs_rdio_MuteSource;
- @FXML private RadioButton obs_rdio_SetScene;
-
- @Override
- public void postInit(CommandContext context) {
- if (obs.isConnected()) {
- var sourcesWithAudio = obs.getSourcesWithAudio();
- var scenes = obs.getScenes();
- obsSourceToMute.getItems().addAll(sourcesWithAudio);
- obsSetScene.getItems().addAll(scenes);
- }
- }
-
- @Override
- public void initFromCommand(CommandObs cmd) {
- if (cmd instanceof CommandObsMuteSource ms) {
- obsSourceToMute.getItems().add(ms.getSource());
- } else if (cmd instanceof CommandObsSetScene ss) {
- obsSetScene.getItems().add(ss.getScene());
- }
-
- if (cmd instanceof CommandObsSetScene ss) {
- obs_rdio_SetScene.setSelected(true);
- obsSetScene.getSelectionModel().select(ss.getScene());
- } else if (cmd instanceof CommandObsMuteSource ms) {
- obs_rdio_MuteSource.setSelected(true);
- obsSourceToMute.getSelectionModel().select(ms.getSource());
- switch (ms.getType()) {
- case unmute -> obsMuteUnmute.setSelected(true);
- case mute -> obsMuteMute.setSelected(true);
- case toggle -> obsMuteToggle.setSelected(true);
- }
- }
- onRadioButton(null);
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- if (obs_rdio_SetScene.isSelected()) {
- return new CommandObsSetScene(obsSetScene.getSelectionModel().getSelectedItem());
- } else if (obs_rdio_MuteSource.isSelected()) {
- return new CommandObsMuteSource(obsSourceToMute.getSelectionModel().getSelectedItem(),
- obsMuteUnmute.isSelected() ? MuteType.unmute : obsMuteMute.isSelected() ? MuteType.mute : MuteType.toggle);
- } else {
- log.error("ERROR INVALID RADIO BUTTON IN BUTTON OBS");
- return NOOP;
- }
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] { obsSetScene.getSelectionModel().selectedItemProperty(),
- obsSourceToMute.getSelectionModel().selectedItemProperty(),
- obsMuteMute.selectedProperty(), obsMuteToggle.selectedProperty(), obsMuteUnmute.selectedProperty(), obs_rdio_MuteSource.selectedProperty(), obs_rdio_SetScene.selectedProperty() };
- }
-
- @FXML
- private void onRadioButton(@Nullable ActionEvent event) {
- obsPaneSetScene.setDisable(!obs_rdio_SetScene.isSelected());
- obsPaneMuteSource.setDisable(!obs_rdio_MuteSource.isSelected());
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnProfileController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnProfileController.java
deleted file mode 100644
index 2ec2d006..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnProfileController.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandProfile;
-import com.getpcpanel.profile.DeviceSave;
-import com.getpcpanel.profile.Profile;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.fxml.FXML;
-import javafx.scene.control.ChoiceBox;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-import one.util.streamex.StreamEx;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Profile", fxml = "Profile", cmds = CommandProfile.class)
-public class BtnProfileController extends CommandController implements ButtonCommandController {
- private DeviceSave deviceSave;
-
- @FXML private ChoiceBox profileDropdown;
-
- @Override
- public void postInit(CommandContext context) {
- deviceSave = context.deviceSave();
-
- var curProfile = context.profile().getName();
- StreamEx.of(deviceSave.getProfiles()).removeBy(Profile::getName, curProfile).toListAndThen(profileDropdown.getItems()::addAll);
- }
-
- @Override
- public void initFromCommand(CommandProfile cmd) {
- deviceSave.getProfile(cmd.getProfile()).ifPresent(profile -> profileDropdown.setValue(profile));
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- return new CommandProfile(profileDropdown.getValue() == null ? null : profileDropdown.getValue().getName());
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] { profileDropdown.valueProperty() };
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnShortcutController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnShortcutController.java
deleted file mode 100644
index 9ff550d9..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnShortcutController.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandShortcut;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.UIHelper;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-
-import javafx.beans.Observable;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.TextField;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Shortcut", fxml = "Shortcut", cmds = CommandShortcut.class)
-public class BtnShortcutController extends CommandController implements ButtonCommandController {
- @FXML private TextField shortcutField;
-
- @Override
- public void postInit(CommandContext context) {
- }
-
- @Override
- public void initFromCommand(CommandShortcut cmd) {
- shortcutField.setText(cmd.getShortcut());
- super.initFromCommand(cmd);
- }
-
- @Override
- public Command buildCommand() {
- return new CommandShortcut(shortcutField.getText());
- }
-
- @Override
- protected Observable[] determineDependencies() {
- return new Observable[] { shortcutField.textProperty() };
- }
-
- @FXML
- private void scFile(ActionEvent event) {
- UIHelper.showFilePicker("Pick file", shortcutField);
- }
-}
diff --git a/src/main/java/com/getpcpanel/ui/command/button/BtnVoiceMeeterController.java b/src/main/java/com/getpcpanel/ui/command/button/BtnVoiceMeeterController.java
deleted file mode 100644
index f86bf1cb..00000000
--- a/src/main/java/com/getpcpanel/ui/command/button/BtnVoiceMeeterController.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package com.getpcpanel.ui.command.button;
-
-import static com.getpcpanel.commands.command.CommandNoOp.NOOP;
-
-import org.springframework.stereotype.Component;
-
-import com.getpcpanel.commands.command.Command;
-import com.getpcpanel.commands.command.CommandVoiceMeeter;
-import com.getpcpanel.commands.command.CommandVoiceMeeterAdvancedButton;
-import com.getpcpanel.commands.command.CommandVoiceMeeterBasicButton;
-import com.getpcpanel.spring.Prototype;
-import com.getpcpanel.ui.command.ButtonCommandController;
-import com.getpcpanel.ui.command.Cmd;
-import com.getpcpanel.ui.command.CommandContext;
-import com.getpcpanel.ui.command.CommandController;
-import com.getpcpanel.ui.command.VoiceMeeterEnabled;
-import com.getpcpanel.util.Util;
-import com.getpcpanel.voicemeeter.Voicemeeter;
-import com.getpcpanel.voicemeeter.Voicemeeter.ButtonControlMode;
-import com.getpcpanel.voicemeeter.Voicemeeter.ButtonType;
-import com.getpcpanel.voicemeeter.Voicemeeter.ControlType;
-
-import javafx.beans.Observable;
-import javafx.fxml.FXML;
-import javafx.scene.control.ChoiceBox;
-import javafx.scene.control.Label;
-import javafx.scene.control.TabPane;
-import javafx.scene.control.TextField;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-@Component
-@Prototype
-@RequiredArgsConstructor
-@Cmd(name = "Voicemeeter", fxml = "VoiceMeeter", cmds = { CommandVoiceMeeterBasicButton.class, CommandVoiceMeeterAdvancedButton.class }, enabled = VoiceMeeterEnabled.class)
-public class BtnVoiceMeeterController extends CommandController