diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java index ca849833ed..8327a41eaf 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java @@ -69,6 +69,7 @@ import org.jackhuang.hmcl.ui.animation.AnimationUtils; import org.jackhuang.hmcl.ui.animation.Motion; import org.jackhuang.hmcl.ui.construct.IconedMenuItem; +import org.jackhuang.hmcl.ui.construct.JFXTooltip; import org.jackhuang.hmcl.ui.construct.MenuSeparator; import org.jackhuang.hmcl.ui.construct.PopupMenu; import org.jackhuang.hmcl.ui.image.ImageLoader; @@ -471,31 +472,30 @@ public static void smoothScrolling(VirtualFlow virtualFlow) { } } - private static final Duration TOOLTIP_FAST_SHOW_DELAY = Duration.millis(50); + private static final Duration TOOLTIP_FAST_SHOW_DELAY = Duration.millis(250); private static final Duration TOOLTIP_SLOW_SHOW_DELAY = Duration.millis(500); private static final Duration TOOLTIP_SHOW_DURATION = Duration.millis(5000); - public static void installTooltip(Node node, Duration showDelay, Duration showDuration, Duration hideDelay, Tooltip tooltip) { + public static void installTooltip(Node node, Duration showDelay, Duration showDuration, JFXTooltip tooltip) { tooltip.setShowDelay(showDelay); tooltip.setShowDuration(showDuration); - tooltip.setHideDelay(hideDelay); - Tooltip.install(node, tooltip); + tooltip.install(node); } - public static void installFastTooltip(Node node, Tooltip tooltip) { - runInFX(() -> installTooltip(node, TOOLTIP_FAST_SHOW_DELAY, TOOLTIP_SHOW_DURATION, Duration.ZERO, tooltip)); + public static void installFastTooltip(Node node, JFXTooltip tooltip) { + runInFX(() -> installTooltip(node, TOOLTIP_FAST_SHOW_DELAY, TOOLTIP_SHOW_DURATION, tooltip)); } - public static void installFastTooltip(Node node, String tooltip) { - installFastTooltip(node, new Tooltip(tooltip)); + public static void installFastTooltip(Node node, String tooltipText) { + installFastTooltip(node, new JFXTooltip(tooltipText)); } - public static void installSlowTooltip(Node node, Tooltip tooltip) { - runInFX(() -> installTooltip(node, TOOLTIP_SLOW_SHOW_DELAY, TOOLTIP_SHOW_DURATION, Duration.ZERO, tooltip)); + public static void installSlowTooltip(Node node, JFXTooltip tooltip) { + runInFX(() -> installTooltip(node, TOOLTIP_SLOW_SHOW_DELAY, TOOLTIP_SHOW_DURATION, tooltip)); } - public static void installSlowTooltip(Node node, String tooltip) { - installSlowTooltip(node, new Tooltip(tooltip)); + public static void installSlowTooltip(Node node, String tooltipText) { + installSlowTooltip(node, new JFXTooltip(tooltipText)); } public static void playAnimation(Node node, String animationKey, Animation animation) { @@ -1321,18 +1321,18 @@ public static void showTooltipWhenTruncated(Labeled labeled) { if (textTruncatedProperty != null) { ChangeListener listener = (observable, oldValue, newValue) -> { var label = (Labeled) ((ReadOnlyProperty) observable).getBean(); - var tooltip = (Tooltip) label.getProperties().get(LABEL_FULL_TEXT_PROP_KEY); + var tooltip = (JFXTooltip) label.getProperties().get(LABEL_FULL_TEXT_PROP_KEY); if (newValue) { if (tooltip == null) { - tooltip = new Tooltip(); + tooltip = new JFXTooltip(); tooltip.textProperty().bind(label.textProperty()); label.getProperties().put(LABEL_FULL_TEXT_PROP_KEY, tooltip); } FXUtils.installFastTooltip(label, tooltip); } else if (tooltip != null) { - Tooltip.uninstall(label, tooltip); + tooltip.uninstall(); } }; listener.changed(textTruncatedProperty, false, textTruncatedProperty.get()); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountAdvancedListItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountAdvancedListItem.java index 63fac2d4fb..7f8f7cd472 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountAdvancedListItem.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountAdvancedListItem.java @@ -23,7 +23,6 @@ import javafx.beans.value.ObservableValue; import javafx.geometry.Pos; import javafx.scene.canvas.Canvas; -import javafx.scene.control.Tooltip; import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount; import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer; @@ -32,6 +31,7 @@ import org.jackhuang.hmcl.setting.Accounts; import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.construct.AdvancedListItem; +import org.jackhuang.hmcl.ui.construct.JFXTooltip; import org.jackhuang.hmcl.util.javafx.BindingMapping; import static javafx.beans.binding.Bindings.createStringBinding; @@ -40,7 +40,7 @@ import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public class AccountAdvancedListItem extends AdvancedListItem { - private final Tooltip tooltip; + private final JFXTooltip tooltip; private final Canvas canvas; private final ObjectProperty account = new SimpleObjectProperty() { @@ -73,7 +73,7 @@ public AccountAdvancedListItem() { } public AccountAdvancedListItem(Account account) { - tooltip = new Tooltip(); + tooltip = new JFXTooltip(); FXUtils.installFastTooltip(this, tooltip); canvas = new Canvas(32, 32); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java index c2551eff5e..236c7f73c1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListItemSkin.java @@ -26,7 +26,6 @@ import javafx.scene.canvas.Canvas; import javafx.scene.control.Label; import javafx.scene.control.SkinBase; -import javafx.scene.control.Tooltip; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; @@ -41,6 +40,7 @@ import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.SVG; +import org.jackhuang.hmcl.ui.construct.JFXTooltip; import org.jackhuang.hmcl.ui.construct.SpinnerPane; import org.jackhuang.hmcl.util.javafx.BindingMapping; @@ -75,7 +75,7 @@ public AccountListItemSkin(AccountListItem skinnable) { subtitle.getStyleClass().add("subtitle"); subtitle.textProperty().bind(skinnable.subtitleProperty()); if (skinnable.getAccount() instanceof AuthlibInjectorAccount) { - Tooltip tooltip = new Tooltip(); + JFXTooltip tooltip = new JFXTooltip(); AuthlibInjectorServer server = ((AuthlibInjectorAccount) skinnable.getAccount()).getServer(); tooltip.textProperty().bind(BindingMapping.of(server, AuthlibInjectorServer::toString)); FXUtils.installSlowTooltip(subtitle, tooltip); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java index bdcaff5f0a..d193f100c2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java @@ -18,13 +18,7 @@ package org.jackhuang.hmcl.ui.account; import javafx.beans.binding.Bindings; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.ListProperty; -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.ReadOnlyObjectProperty; -import javafx.beans.property.ReadOnlyObjectWrapper; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleListProperty; +import javafx.beans.property.*; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; @@ -32,7 +26,6 @@ import javafx.geometry.Insets; import javafx.scene.control.ScrollPane; import javafx.scene.control.Skin; -import javafx.scene.control.Tooltip; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import org.jackhuang.hmcl.auth.Account; @@ -43,6 +36,7 @@ import org.jackhuang.hmcl.ui.SVG; import org.jackhuang.hmcl.ui.construct.AdvancedListItem; import org.jackhuang.hmcl.ui.construct.ClassTitle; +import org.jackhuang.hmcl.ui.construct.JFXTooltip; import org.jackhuang.hmcl.ui.decorator.DecoratorAnimatedPage; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.util.i18n.LocaleUtils; @@ -157,7 +151,7 @@ public AccountListPageSkin(AccountListPage skinnable) { LOG.warning("Unparsable authlib-injector server url " + server.getUrl(), e); } item.subtitleProperty().set(host); - Tooltip tooltip = new Tooltip(); + JFXTooltip tooltip = new JFXTooltip(); tooltip.textProperty().bind(Bindings.format("%s (%s)", title, server.getUrl())); FXUtils.installFastTooltip(item, tooltip); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/JFXTooltip.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/JFXTooltip.java new file mode 100644 index 0000000000..31576947d8 --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/JFXTooltip.java @@ -0,0 +1,149 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2026 huangyuhui and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.jackhuang.hmcl.ui.construct; + +import javafx.animation.FadeTransition; +import javafx.animation.PauseTransition; +import javafx.beans.property.StringProperty; +import javafx.event.EventHandler; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.StackPane; +import javafx.stage.Popup; +import javafx.util.Duration; +import org.jackhuang.hmcl.ui.animation.AnimationUtils; + +public class JFXTooltip { + // https://api.flutter.dev/flutter/material/Tooltip-class.html + private static final double FADE_IN_MS = AnimationUtils.isAnimationEnabled() ? 150 : 0; + private static final double FADE_OUT_MS = AnimationUtils.isAnimationEnabled() ? 75 : 0; + + private final Popup popup; + private final Label label; + private final PauseTransition showDelayTransition; + private final PauseTransition showDurationTransition; + + private final FadeTransition fadeIn; + private final FadeTransition fadeOut; + + private double mouseX; + private double mouseY; + + private EventHandler enteredHandler; + private EventHandler exitedHandler; + private EventHandler pressedHandler; + private Node attachedNode; + + public JFXTooltip() { + this(""); + } + + public JFXTooltip(String text) { + popup = new Popup(); + popup.setAutoHide(false); + + label = new Label(text); + StackPane root = new StackPane(label); + root.getStyleClass().add("jfx-tooltip"); + root.setMouseTransparent(true); + + popup.getContent().add(root); + + fadeIn = new FadeTransition(Duration.millis(FADE_IN_MS), root); + fadeIn.setFromValue(0.0); + fadeIn.setToValue(1.0); + + fadeOut = new FadeTransition(Duration.millis(FADE_OUT_MS), root); + fadeOut.setFromValue(1.0); + fadeOut.setToValue(0.0); + fadeOut.setOnFinished(event -> popup.hide()); + + showDelayTransition = new PauseTransition(Duration.millis(500)); + showDurationTransition = new PauseTransition(Duration.millis(5000)); + showDurationTransition.setOnFinished(e -> hideTooltip()); + } + + public void setShowDelay(Duration delay) { + this.showDelayTransition.setDuration(delay); + } + + public void setShowDuration(Duration duration) { + this.showDurationTransition.setDuration(duration); + } + + public final StringProperty textProperty() { + return label.textProperty(); + } + + public final void setText(String value) { + label.setText(value); + } + + private void hideTooltip() { + showDelayTransition.stop(); + showDurationTransition.stop(); + if (popup.isShowing()) { + fadeIn.stop(); + fadeOut.playFromStart(); + } + } + + public void install(Node targetNode) { + if (attachedNode != null) { + uninstall(); + } + this.attachedNode = targetNode; + + enteredHandler = event -> { + mouseX = event.getScreenX(); + mouseY = event.getScreenY(); + showDelayTransition.playFromStart(); + }; + + exitedHandler = event -> hideTooltip(); + pressedHandler = event -> hideTooltip(); + + targetNode.addEventHandler(MouseEvent.MOUSE_ENTERED, enteredHandler); + targetNode.addEventHandler(MouseEvent.MOUSE_EXITED, exitedHandler); + targetNode.addEventHandler(MouseEvent.MOUSE_PRESSED, pressedHandler); + + showDelayTransition.setOnFinished(e -> { + if (targetNode.getScene() != null && targetNode.getScene().getWindow() != null) { + fadeOut.stop(); + popup.show(targetNode.getScene().getWindow(), mouseX + 5, mouseY); + fadeIn.playFromStart(); + showDurationTransition.playFromStart(); + } + }); + } + + public void uninstall() { + if (attachedNode != null) { + hideTooltip(); + attachedNode.removeEventHandler(MouseEvent.MOUSE_ENTERED, enteredHandler); + attachedNode.removeEventHandler(MouseEvent.MOUSE_EXITED, exitedHandler); + attachedNode.removeEventHandler(MouseEvent.MOUSE_PRESSED, pressedHandler); + + attachedNode = null; + enteredHandler = null; + exitedHandler = null; + pressedHandler = null; + } + } +} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java index 5fa9e5b9f5..77dcabfd15 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java @@ -27,7 +27,6 @@ import javafx.scene.Node; import javafx.scene.control.ListCell; import javafx.scene.control.Skin; -import javafx.scene.control.Tooltip; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; @@ -41,6 +40,7 @@ import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.ui.*; +import org.jackhuang.hmcl.ui.construct.JFXTooltip; import org.jackhuang.hmcl.ui.construct.MessageDialogPane; import org.jackhuang.hmcl.ui.construct.RipplerContainer; import org.jackhuang.hmcl.ui.construct.TwoLineListItem; @@ -49,16 +49,18 @@ import org.jackhuang.hmcl.util.Pair; import org.jackhuang.hmcl.util.TaskCancellationAction; import org.jackhuang.hmcl.util.io.FileUtils; -import org.jackhuang.hmcl.util.platform.UnsupportedPlatformException; -import org.jackhuang.hmcl.util.tree.ArchiveFileTree; import org.jackhuang.hmcl.util.platform.Architecture; import org.jackhuang.hmcl.util.platform.OperatingSystem; import org.jackhuang.hmcl.util.platform.Platform; +import org.jackhuang.hmcl.util.platform.UnsupportedPlatformException; +import org.jackhuang.hmcl.util.tree.ArchiveFileTree; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.logging.Logger.LOG; @@ -221,7 +223,7 @@ private static final class JavaItemCell extends ListCell { private SVG removeIcon; private final StackPane removeIconPane; - private final Tooltip removeTooltip = new Tooltip(); + private final JFXTooltip removeTooltip = new JFXTooltip(); JavaItemCell(JFXListView listView) { BorderPane root = new BorderPane(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java index 3393035fc6..fb3323f314 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java @@ -29,7 +29,6 @@ import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Label; -import javafx.scene.control.Tooltip; import javafx.scene.image.ImageView; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; @@ -56,6 +55,7 @@ import org.jackhuang.hmcl.ui.animation.AnimationUtils; import org.jackhuang.hmcl.ui.animation.ContainerAnimations; import org.jackhuang.hmcl.ui.animation.TransitionPane; +import org.jackhuang.hmcl.ui.construct.JFXTooltip; import org.jackhuang.hmcl.ui.construct.MessageDialogPane; import org.jackhuang.hmcl.ui.construct.TwoLineListItem; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; @@ -219,7 +219,7 @@ public final class MainPage extends StackPane implements DecoratorPage { currentLabel.setStyle("-fx-font-size: 12px;"); FXUtils.onChangeAndOperate(currentGameProperty(), new Consumer<>() { - private Tooltip tooltip; + private JFXTooltip tooltip; @Override public void accept(String currentGame) { @@ -229,7 +229,7 @@ public void accept(String currentGame) { graphic.getChildren().setAll(launchLabel); FXUtils.setOnActionWithCooldown(launchButton, MainPage.this::launchNoGame); if (tooltip == null) - tooltip = new Tooltip(i18n("version.launch.empty.tooltip")); + tooltip = new JFXTooltip(i18n("version.launch.empty.tooltip")); FXUtils.installFastTooltip(launchButton, tooltip); } else { launchLabel.setText(i18n("version.launch")); @@ -237,7 +237,7 @@ public void accept(String currentGame) { graphic.getChildren().setAll(launchLabel, currentLabel); FXUtils.setOnActionWithCooldown(launchButton, MainPage.this::launch); if (tooltip != null) - Tooltip.uninstall(launchButton, tooltip); + tooltip.uninstall(); } } }); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java index 32e7b24ca8..4505222cd1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java @@ -184,7 +184,7 @@ protected Skin(RootPage control) { Controllers.getDownloadPage().showGameDownloads(); Controllers.navigate(Controllers.getDownloadPage()); }); - FXUtils.installFastTooltip(downloadItem, i18n("download.hint")); + FXUtils.installSlowTooltip(downloadItem, i18n("download.hint")); if (AnimationUtils.isAnimationEnabled()) { FXUtils.prepareOnMouseEnter(downloadItem, Controllers::prepareDownloadPage); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java index bad72233f5..55f8a51190 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java @@ -28,7 +28,10 @@ import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; -import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.SelectionMode; +import javafx.scene.control.SkinBase; import javafx.scene.image.Image; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; @@ -54,7 +57,10 @@ import org.jackhuang.hmcl.ui.animation.ContainerAnimations; import org.jackhuang.hmcl.ui.animation.TransitionPane; import org.jackhuang.hmcl.ui.construct.*; -import org.jackhuang.hmcl.util.*; +import org.jackhuang.hmcl.util.FXThread; +import org.jackhuang.hmcl.util.Lazy; +import org.jackhuang.hmcl.util.Pair; +import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.i18n.I18n; import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.FileUtils; @@ -560,7 +566,7 @@ final class ModInfoListCell extends MDListCell { JFXButton revealButton = FXUtils.newToggleButton4(SVG.FOLDER); BooleanProperty booleanProperty; - Tooltip warningTooltip; + JFXTooltip warningTooltip; ModInfoListCell(JFXListView listView) { super(listView); @@ -588,7 +594,7 @@ final class ModInfoListCell extends MDListCell { protected void updateControl(ModInfoObject dataItem, boolean empty) { pseudoClassStateChanged(WARNING, false); if (warningTooltip != null) { - Tooltip.uninstall(this, warningTooltip); + warningTooltip.uninstall(); warningTooltip = null; } @@ -678,8 +684,8 @@ protected void updateControl(ModInfoObject dataItem, boolean empty) { //noinspection ConstantValue this.warningTooltip = warning.size() == 1 - ? new Tooltip(warning.get(0)) - : new Tooltip(String.join("\n", warning)); + ? new JFXTooltip(warning.get(0)) + : new JFXTooltip(String.join("\n", warning)); FXUtils.installFastTooltip(this, warningTooltip); } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/SchematicsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/SchematicsPage.java index 30d769f8de..09bb75c725 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/SchematicsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/SchematicsPage.java @@ -23,7 +23,9 @@ import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; -import javafx.scene.control.*; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.Skin; import javafx.scene.image.Image; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; @@ -548,7 +550,7 @@ private static final class Cell extends ListCell { private final ImageContainer iconImageView; private final SVGContainer iconSVGView; - private final Tooltip tooltip = new Tooltip(); + private final JFXTooltip tooltip = new JFXTooltip(); public Cell() { this.root = new BorderPane(); @@ -631,7 +633,7 @@ protected void updateItem(Item item, boolean empty) { FXUtils.installSlowTooltip(left, tooltip); } else { tooltip.setText(""); - Tooltip.uninstall(left, tooltip); + tooltip.uninstall(); } root.setRight(item instanceof BackItem ? null : right); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java index b5f0f355ad..793aa30956 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java @@ -29,7 +29,6 @@ import javafx.scene.Node; import javafx.scene.control.ListCell; import javafx.scene.control.Skin; -import javafx.scene.control.Tooltip; import javafx.scene.input.MouseButton; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; @@ -243,7 +242,7 @@ private static final class WorldListCell extends ListCell { private final RipplerContainer graphic; private final ImageContainer imageView; - private final Tooltip leftTooltip; + private final JFXTooltip leftTooltip; private final TwoLineListItem content; private final JFXButton btnLaunch; @@ -256,7 +255,7 @@ public WorldListCell(WorldListPage page) { { StackPane left = new StackPane(); - this.leftTooltip = new Tooltip(); + this.leftTooltip = new JFXTooltip(); FXUtils.installSlowTooltip(left, leftTooltip); root.setLeft(left); left.setPadding(new Insets(0, 8, 0, 0)); diff --git a/HMCL/src/main/resources/assets/css/root.css b/HMCL/src/main/resources/assets/css/root.css index 5b035f97f6..c5f53f54d6 100644 --- a/HMCL/src/main/resources/assets/css/root.css +++ b/HMCL/src/main/resources/assets/css/root.css @@ -1853,12 +1853,18 @@ * * ******************************************************************************/ -.tooltip { +.jfx-tooltip { -fx-text-fill: -monet-inverse-on-surface; -fx-background-color: -monet-inverse-surface; + -fx-background-insets: 0; + -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.5) , 10, 0.0 , 0 , 3 ); + -fx-font-size: 12px; + -fx-background-radius: 4px; + -fx-padding: 8px; + -fx-min-height: 24px; } -.tooltip .text { +.jfx-tooltip .text { -fx-fill: -monet-inverse-on-surface; }