diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/DoubleValidator.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/DoubleValidator.java deleted file mode 100644 index 7813ccce75..0000000000 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/DoubleValidator.java +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (C) 2020 The HMCL Authors -// SPDX-License-Identifier: GPL-3.0-or-later WITH AdditionRef-HMCL -package org.jackhuang.hmcl.ui.construct; - -import com.jfoenix.validation.base.ValidatorBase; -import javafx.beans.NamedArg; -import javafx.scene.control.TextInputControl; -import org.jackhuang.hmcl.util.Lang; -import org.jackhuang.hmcl.util.StringUtils; - -public class DoubleValidator extends ValidatorBase { - private final boolean nullable; - - public DoubleValidator() { - this(false); - } - - public DoubleValidator(@NamedArg("nullable") boolean nullable) { - this.nullable = nullable; - } - - public DoubleValidator(@NamedArg("message") String message, @NamedArg("nullable") boolean nullable) { - super(message); - this.nullable = nullable; - } - - @Override - protected void eval() { - if (srcControl.get() instanceof TextInputControl) { - evalTextInputField(); - } - } - - private void evalTextInputField() { - TextInputControl textField = ((TextInputControl) srcControl.get()); - - if (StringUtils.isBlank(textField.getText())) - hasErrors.set(!nullable); - else - hasErrors.set(Lang.toDoubleOrNull(textField.getText()) == null); - } -} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FontComboBox.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FontComboBox.java deleted file mode 100644 index d7ea14c192..0000000000 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FontComboBox.java +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (C) 2020 The HMCL Authors -// SPDX-License-Identifier: GPL-3.0-or-later WITH AdditionRef-HMCL -package org.jackhuang.hmcl.ui.construct; - -import static javafx.collections.FXCollections.emptyObservableList; -import static javafx.collections.FXCollections.observableList; -import static javafx.collections.FXCollections.singletonObservableList; - -import org.jackhuang.hmcl.ui.FXUtils; -import org.jackhuang.hmcl.util.javafx.BindingMapping; - -import com.jfoenix.controls.JFXComboBox; -import com.jfoenix.controls.JFXListCell; - -import javafx.beans.binding.Bindings; -import javafx.scene.text.Font; - -public final class FontComboBox extends JFXComboBox { - - private boolean loaded = false; - - public FontComboBox() { - setMinWidth(260); - - styleProperty().bind(Bindings.concat("-fx-font-family: \"", valueProperty(), "\"")); - - setCellFactory(listView -> new JFXListCell<>() { - @Override - public void updateItem(String item, boolean empty) { - super.updateItem(item, empty); - if (!empty) { - setText(item); - setGraphic(null); - setStyle("-fx-font-family: \"" + item + "\""); - } - } - }); - - itemsProperty().bind(BindingMapping.of(valueProperty()) - .map(value -> value == null ? emptyObservableList() : singletonObservableList(value))); - - FXUtils.onClicked(this, () -> { - if (loaded) - return; - itemsProperty().unbind(); - setItems(observableList(Font.getFamilies())); - loaded = true; - }); - } -} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/JFXCheckBoxTableCell.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/JFXCheckBoxTableCell.java deleted file mode 100644 index fe1b5f3363..0000000000 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/JFXCheckBoxTableCell.java +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (C) 2025 The HMCL Authors -// SPDX-License-Identifier: GPL-3.0-or-later WITH AdditionRef-HMCL -package org.jackhuang.hmcl.ui.construct; - -import com.jfoenix.controls.JFXCheckBox; -import javafx.beans.binding.Bindings; -import javafx.beans.property.BooleanProperty; -import javafx.scene.control.TableCell; -import javafx.scene.control.TableColumn; -import javafx.util.Callback; - -/// @author Glavo -public final class JFXCheckBoxTableCell extends TableCell { - public static Callback, TableCell> forTableColumn( - final TableColumn column) { - return list -> new JFXCheckBoxTableCell<>(); - } - - private final JFXCheckBox checkBox = new JFXCheckBox(); - private BooleanProperty booleanProperty; - - public JFXCheckBoxTableCell() { - this.getStyleClass().add("jfx-checkbox-table-cell"); - } - - @Override - protected void updateItem(T item, boolean empty) { - super.updateItem(item, empty); - - if (empty) { - setText(null); - setGraphic(null); - checkBox.disableProperty().unbind(); - } else { - setGraphic(checkBox); - - if (booleanProperty != null) { - checkBox.selectedProperty().unbindBidirectional(booleanProperty); - } - if (getTableColumn().getCellObservableValue(getIndex()) instanceof BooleanProperty obsValue) { - booleanProperty = obsValue; - checkBox.selectedProperty().bindBidirectional(booleanProperty); - } - - checkBox.disableProperty().bind(Bindings.not( - getTableView().editableProperty().and( - getTableColumn().editableProperty()).and( - editableProperty()) - )); - } - } - -} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/LineFileChooserButton.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/LineFileChooserButton.java deleted file mode 100644 index 835ed4d7e8..0000000000 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/LineFileChooserButton.java +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (C) 2026 The HMCL Authors -// SPDX-License-Identifier: GPL-3.0-or-later WITH AdditionRef-HMCL -package org.jackhuang.hmcl.ui.construct; - -import javafx.beans.property.*; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.scene.Scene; -import javafx.stage.DirectoryChooser; -import javafx.stage.FileChooser; -import javafx.stage.Window; -import org.jackhuang.hmcl.Metadata; -import org.jackhuang.hmcl.ui.SVG; -import org.jackhuang.hmcl.util.io.FileUtils; - -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.jackhuang.hmcl.util.logging.Logger.LOG; - -public class LineFileChooserButton extends LineButton { - private static final String DEFAULT_STYLE_CLASS = "line-file-select-button"; - - public LineFileChooserButton() { - getStyleClass().add(DEFAULT_STYLE_CLASS); - setTrailingIcon(SVG.EDIT); - } - - /// Converts the given path to absolute/relative(if possible) path according to [#convertToRelativePathProperty()]. - private String processPath(Path path) { - if (isConvertToRelativePath() && path.isAbsolute()) { - try { - return Metadata.CURRENT_DIRECTORY.relativize(path).normalize().toString(); - } catch (IllegalArgumentException e) { - // the given path can't be relativized against current path - } - } - return path.normalize().toString(); - } - - @Override - public void fire() { - super.fire(); - - Scene scene = this.getScene(); - - Window owner = scene != null ? scene.getWindow() : null; // TODO: Allow user to set owner stage - String windowTitle = getFileChooserTitle(); - - Path initialDirectory = null; - if (getLocation() != null) { - Path file; - try { - file = FileUtils.toAbsolute(Path.of(getLocation())); - if (Files.exists(file)) { - if (Files.isRegularFile(file)) - initialDirectory = file.getParent(); - else if (Files.isDirectory(file)) - initialDirectory = file; - } - } catch (IllegalArgumentException e) { - LOG.warning("Failed to resolve path: " + getLocation()); - } - } - - Path path; - Type type = getType(); - if (type == Type.OPEN_DIRECTORY) { - var directoryChooser = new DirectoryChooser(); - if (windowTitle != null) - directoryChooser.setTitle(windowTitle); - if (initialDirectory != null) - directoryChooser.setInitialDirectory(initialDirectory.toFile()); - - path = FileUtils.toPath(directoryChooser.showDialog(owner)); - } else { - var fileChooser = new FileChooser(); - if (windowTitle != null) - fileChooser.setTitle(windowTitle); - if (initialDirectory != null) - fileChooser.setInitialDirectory(initialDirectory.toFile()); - - if (extensionFilters != null) - fileChooser.getExtensionFilters().setAll(extensionFilters); - - fileChooser.setInitialFileName(getInitialFileName()); - - path = FileUtils.toPath(switch (type) { - case OPEN_FILE -> fileChooser.showOpenDialog(owner); - case SAVE_FILE -> fileChooser.showSaveDialog(owner); - default -> throw new AssertionError("Unknown Type: " + type); - }); - } - - if (path != null) { - setLocation(processPath(path)); - } - } - - private final StringProperty location = new StringPropertyBase() { - @Override - public Object getBean() { - return LineFileChooserButton.this; - } - - @Override - public String getName() { - return "location"; - } - - @Override - protected void invalidated() { - setTrailingText(get()); - } - }; - - public StringProperty locationProperty() { - return location; - } - - public String getLocation() { - return locationProperty().get(); - } - - public void setLocation(String location) { - locationProperty().set(location); - } - - private final StringProperty fileChooserTitle = new SimpleStringProperty(this, "fileChooserTitle"); - - public StringProperty fileChooserTitleProperty() { - return fileChooserTitle; - } - - public String getFileChooserTitle() { - return fileChooserTitleProperty().get(); - } - - public void setFileChooserTitle(String fileChooserTitle) { - fileChooserTitleProperty().set(fileChooserTitle); - } - - private ObjectProperty type; - - public ObjectProperty typeProperty() { - if (type == null) { - type = new SimpleObjectProperty<>(this, "type", Type.OPEN_FILE); - } - return type; - } - - public Type getType() { - return type != null ? type.get() : Type.OPEN_FILE; - } - - public void setType(Type type) { - typeProperty().set(type); - } - - private ObjectProperty initialFileName; - - public final ObjectProperty initialFileNameProperty() { - if (initialFileName == null) - initialFileName = new SimpleObjectProperty<>(this, "initialFileName"); - - return initialFileName; - } - - public final String getInitialFileName() { - return initialFileName != null ? initialFileName.get() : null; - } - - public final void setInitialFileName(String value) { - initialFileNameProperty().set(value); - } - - private ObservableList extensionFilters; - - public ObservableList getExtensionFilters() { - if (extensionFilters == null) - extensionFilters = FXCollections.observableArrayList(); - return extensionFilters; - } - - private BooleanProperty convertToRelativePath; - - public BooleanProperty convertToRelativePathProperty() { - if (convertToRelativePath == null) - convertToRelativePath = new BooleanPropertyBase(false) { - @Override - public Object getBean() { - return LineFileChooserButton.this; - } - - @Override - public String getName() { - return "convertToRelativePath"; - } - - @Override - protected void invalidated() { - String location = getLocation(); - if (location == null) - return; - try { - setLocation(processPath(FileUtils.toAbsolute(Path.of(getLocation())))); - } catch (IllegalArgumentException ignored) { - } - } - }; - return convertToRelativePath; - } - - public boolean isConvertToRelativePath() { - return convertToRelativePath != null && convertToRelativePath.get(); - } - - public void setConvertToRelativePath(boolean convertToRelativePath) { - convertToRelativePathProperty().set(convertToRelativePath); - } - - public enum Type { - OPEN_FILE, - OPEN_DIRECTORY, - SAVE_FILE - } -} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/NoneMultipleSelectionModel.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/NoneMultipleSelectionModel.java deleted file mode 100644 index 44b586916c..0000000000 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/NoneMultipleSelectionModel.java +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (C) 2020 The HMCL Authors -// SPDX-License-Identifier: GPL-3.0-or-later WITH AdditionRef-HMCL -package org.jackhuang.hmcl.ui.construct; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.scene.control.MultipleSelectionModel; - -public class NoneMultipleSelectionModel extends MultipleSelectionModel { - - public NoneMultipleSelectionModel() { - } - - @Override - public ObservableList getSelectedIndices() { - return FXCollections.emptyObservableList(); - } - - @Override - public ObservableList getSelectedItems() { - return FXCollections.emptyObservableList(); - } - - @Override - public void selectIndices(int index, int... indices) { - } - - @Override - public void selectAll() { - } - - @Override - public void clearAndSelect(int index) { - } - - @Override - public void select(int index) { - } - - @Override - public void select(T obj) { - } - - @Override - public void clearSelection(int index) { - } - - @Override - public void clearSelection() { - } - - @Override - public boolean isSelected(int index) { - return false; - } - - @Override - public boolean isEmpty() { - return true; - } - - @Override - public void selectPrevious() { - } - - @Override - public void selectNext() { - } - - @Override - public void selectFirst() { - } - - @Override - public void selectLast() { - } -}